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
/// non-.globl label. This defaults to true.
bool IsFunctionEHFrameSymbolPrivate;
/// 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;
/// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some
/// encoding values for EH.
unsigned PersonalityEncoding;
bool getSupportsWeakOmittedEHFrame() const {
return SupportsWeakOmittedEHFrame;
}
bool getSupportsWeakOmittedEHFrame() const {
return SupportsWeakOmittedEHFrame;
}
+ bool getSupportsCompactUnwindWithoutEHFrame() const {
+ return SupportsCompactUnwindWithoutEHFrame;
+ }
bool getCommDirectiveSupportsAlignment() const {
return CommDirectiveSupportsAlignment;
}
bool getCommDirectiveSupportsAlignment() const {
return CommDirectiveSupportsAlignment;
}
ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos();
// Emit the compact unwind info if available.
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) {
if (IsEH && MOFI->getCompactUnwindSection()) {
bool SectionEmitted = false;
for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
SectionEmitted = true;
}
Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
SectionEmitted = true;
}
+ NeedsEHFrameSection |=
+ Frame.CompactUnwindEncoding ==
+ MOFI->getCompactUnwindDwarfEHFrameOnly();
Emitter.EmitCompactUnwind(Streamer, Frame);
}
}
Emitter.EmitCompactUnwind(Streamer, Frame);
}
}
+ if (!NeedsEHFrameSection) return;
+
const MCSection &Section =
IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() :
*MOFI->getDwarfFrameSection();
const MCSection &Section =
IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() :
*MOFI->getDwarfFrameSection();
Streamer.SwitchSection(&Section);
MCSymbol *SectionStart = Context.CreateTempSymbol();
Streamer.EmitLabel(SectionStart);
Streamer.SwitchSection(&Section);
MCSymbol *SectionStart = Context.CreateTempSymbol();
Streamer.EmitLabel(SectionStart);
DenseMap<CIEKey, const MCSymbol*> CIEStarts;
const MCSymbol *DummyDebugKey = NULL;
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];
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;
CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple);
const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
Frame.IsSimple);
FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
Frame.IsSimple);
FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
-
- if (i != n - 1)
- Streamer.EmitLabel(FDEEnd);
}
Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
}
Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
CommDirectiveSupportsAlignment = true;
SupportsWeakOmittedEHFrame = true;
IsFunctionEHFrameSymbolPrivate = true;
CommDirectiveSupportsAlignment = true;
SupportsWeakOmittedEHFrame = true;
IsFunctionEHFrameSymbolPrivate = true;
+ SupportsCompactUnwindWithoutEHFrame = false;
PersonalityEncoding = LSDAEncoding = FDEEncoding = FDECFIEncoding =
TTypeEncoding = dwarf::DW_EH_PE_absptr;
PersonalityEncoding = LSDAEncoding = FDEEncoding = FDECFIEncoding =
TTypeEncoding = dwarf::DW_EH_PE_absptr;