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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205087 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tim Northover 2014-03-29 09:03:13 +00:00
parent 1db780ba22
commit bc702ae152
3 changed files with 30 additions and 3 deletions

View 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;
}

View 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());

View 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;