summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-03-29 09:03:13 +0000
committerTim Northover <tnorthover@apple.com>2014-03-29 09:03:13 +0000
commitd1c6f51730514611c3b112df9b911e5abdab9775 (patch)
tree10ebff61ac17c603c1474ab7b2283cd3495446f8 /llvm/lib/MC
parentcea0abb60a6c075941017733fb1e4c789c7ee1e3 (diff)
downloadbcm5719-llvm-d1c6f51730514611c3b112df9b911e5abdab9775.tar.gz
bcm5719-llvm-d1c6f51730514611c3b112df9b911e5abdab9775.zip
MC-exceptions: add support for compact-unwind without .eh_frame
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. llvm-svn: 205087
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/MCDwarf.cpp24
-rw-r--r--llvm/lib/MC/MCObjectFileInfo.cpp1
2 files changed, 22 insertions, 3 deletions
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 79f1312fcaa..5fa8f66422b 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -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());
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 87ff0d359d1..e808d0ca6e6 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -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;
OpenPOWER on IntegriCloud