aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCDwarf.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-07-22 21:18:59 +0000
committerBill Wendling <isanbard@gmail.com>2011-07-22 21:18:59 +0000
commit1424c3c3e696868775ac5bfc57d27a0ac3bc6c63 (patch)
treea1fd477e6005ddadf4d7dee6b9770bea2887376d /lib/MC/MCDwarf.cpp
parent1359c6d71858c0de618474e5a51efaced42deca6 (diff)
Emit the __compact_unwind section first. If there are any frames which weren't
emitted, emit them next as CIE/FDEs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135807 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCDwarf.cpp')
-rw-r--r--lib/MC/MCDwarf.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index a200128ab6..06ce502d57 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -504,10 +504,11 @@ namespace {
bool IsEH;
const MCSymbol *SectionStart;
public:
- FrameEmitterImpl(bool usingCFI, bool isEH, const MCSymbol *sectionStart) :
- CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH),
- SectionStart(sectionStart) {
- }
+ FrameEmitterImpl(bool usingCFI, bool isEH)
+ : CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH),
+ SectionStart(0) {}
+
+ void setSectionStart(const MCSymbol *Label) { SectionStart = Label; }
/// EmitCompactUnwind - Emit the unwind information in a compact way. If
/// we're successful, return 'true'. Otherwise, return 'false' and it will
@@ -1011,26 +1012,38 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer,
MCContext &Context = Streamer.getContext();
MCObjectFileInfo *MOFI =
const_cast<MCObjectFileInfo*>(Context.getObjectFileInfo());
+ FrameEmitterImpl Emitter(UsingCFI, IsEH);
+ SmallVector<MCDwarfFrameInfo, 8> RequiresFDE;
+ ArrayRef<MCDwarfFrameInfo> FrameArray;
+
+ if (IsEH && MOFI->getCompactUnwindSection()) {
+ for (unsigned i = 0, n = Streamer.getNumFrameInfos(); i < n; ++i) {
+ const MCDwarfFrameInfo &Frame = Streamer.getFrameInfo(i);
+ if (!Frame.CompactUnwindEncoding ||
+ !Emitter.EmitCompactUnwind(Streamer, Frame))
+ RequiresFDE.push_back(Streamer.getFrameInfo(i));
+ }
+
+ // Early exit if we don't need to emit FDEs.
+ if (RequiresFDE.empty()) return;
+ FrameArray = RequiresFDE;
+ } else {
+ FrameArray = Streamer.getFrameInfos();
+ }
+
const MCSection &Section = IsEH ? *MOFI->getEHFrameSection() :
*MOFI->getDwarfFrameSection();
Streamer.SwitchSection(&Section);
MCSymbol *SectionStart = Context.CreateTempSymbol();
Streamer.EmitLabel(SectionStart);
+ Emitter.setSectionStart(SectionStart);
MCSymbol *FDEEnd = NULL;
DenseMap<CIEKey, const MCSymbol*> CIEStarts;
- FrameEmitterImpl Emitter(UsingCFI, IsEH, SectionStart);
const MCSymbol *DummyDebugKey = NULL;
- for (unsigned i = 0, n = Streamer.getNumFrameInfos(); i < n; ++i) {
- const MCDwarfFrameInfo &Frame = Streamer.getFrameInfo(i);
- if (IsEH && MOFI->getCompactUnwindSection() &&
- Frame.CompactUnwindEncoding &&
- Emitter.EmitCompactUnwind(Streamer, Frame)) {
- FDEEnd = NULL;
- continue;
- }
-
+ for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
+ const MCDwarfFrameInfo &Frame = FrameArray[i];
CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
Frame.LsdaEncoding);
const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;