MC-exceptions: add support for compact-unwind without .eh_frame
authorTim Northover <tnorthover@apple.com>
Sat, 29 Mar 2014 09:03:13 +0000 (09:03 +0000)
committerTim Northover <tnorthover@apple.com>
Sat, 29 Mar 2014 09:03:13 +0000 (09:03 +0000)
ARM64 has compact-unwind information, but doesn't necessarily want to
emit .eh_frame directives as well. This teaches MC about such a
situation so that it will skip .eh_frame info when compact unwind has
been successfully produced.

For functions incompatible with compact unwind, the normal information
is still written.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205087 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCObjectFileInfo.h
lib/MC/MCDwarf.cpp
lib/MC/MCObjectFileInfo.cpp

index 25246929ce539c691fa586c198c49a288c848eb0..1c5c19e51c3e740f20561f807487c67888329b6f 100644 (file)
@@ -39,6 +39,11 @@ protected:
   /// non-.globl label.  This defaults to true.
   bool IsFunctionEHFrameSymbolPrivate;
 
+  /// SupportsCompactUnwindWithoutEHFrame - True if the target object file
+  /// supports emitting a compact unwind section without an associated EH frame
+  /// section.
+  bool SupportsCompactUnwindWithoutEHFrame;
+
   /// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some
   /// encoding values for EH.
   unsigned PersonalityEncoding;
@@ -203,6 +208,9 @@ public:
   bool getSupportsWeakOmittedEHFrame() const {
     return SupportsWeakOmittedEHFrame;
   }
+  bool getSupportsCompactUnwindWithoutEHFrame() const {
+    return SupportsCompactUnwindWithoutEHFrame;
+  }
   bool getCommDirectiveSupportsAlignment() const {
     return CommDirectiveSupportsAlignment;
   }
index 79f1312fcaa3b39a6c9fbc7db09c4a4a567ea010..5fa8f66422b9ba5e5f9968aab2352a8da8e65402 100644 (file)
@@ -1502,6 +1502,7 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB,
   ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos();
 
   // Emit the compact unwind info if available.
+  bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
   if (IsEH && MOFI->getCompactUnwindSection()) {
     bool SectionEmitted = false;
     for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
@@ -1512,13 +1513,19 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB,
         Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
         SectionEmitted = true;
       }
+      NeedsEHFrameSection |=
+        Frame.CompactUnwindEncoding ==
+          MOFI->getCompactUnwindDwarfEHFrameOnly();
       Emitter.EmitCompactUnwind(Streamer, Frame);
     }
   }
 
+  if (!NeedsEHFrameSection) return;
+
   const MCSection &Section =
     IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() :
            *MOFI->getDwarfFrameSection();
+
   Streamer.SwitchSection(&Section);
   MCSymbol *SectionStart = Context.CreateTempSymbol();
   Streamer.EmitLabel(SectionStart);
@@ -1528,8 +1535,22 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB,
   DenseMap<CIEKey, const MCSymbol*> CIEStarts;
 
   const MCSymbol *DummyDebugKey = NULL;
+  NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
   for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
     const MCDwarfFrameInfo &Frame = FrameArray[i];
+
+    // Emit the label from the previous iteration
+    if (FDEEnd) {
+      Streamer.EmitLabel(FDEEnd);
+      FDEEnd = NULL;
+    }
+
+    if (!NeedsEHFrameSection && Frame.CompactUnwindEncoding !=
+          MOFI->getCompactUnwindDwarfEHFrameOnly())
+      // Don't generate an EH frame if we don't need one. I.e., it's taken care
+      // of by the compact unwind encoding.
+      continue;
+
     CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
                Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple);
     const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
@@ -1541,9 +1562,6 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB,
                                   Frame.IsSimple);
 
     FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
-
-    if (i != n - 1)
-      Streamer.EmitLabel(FDEEnd);
   }
 
   Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
index 87ff0d359d1ad1b6d0059f4142c6aec693bc3655..e808d0ca6e6aa2c498a4ee7b213fcc1ea8e3eb79 100644 (file)
@@ -743,6 +743,7 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm,
   CommDirectiveSupportsAlignment = true;
   SupportsWeakOmittedEHFrame = true;
   IsFunctionEHFrameSymbolPrivate = true;
+  SupportsCompactUnwindWithoutEHFrame = false;
 
   PersonalityEncoding = LSDAEncoding = FDEEncoding = FDECFIEncoding =
     TTypeEncoding = dwarf::DW_EH_PE_absptr;