diff options
author | Bill Wendling <isanbard@gmail.com> | 2011-07-22 21:18:59 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2011-07-22 21:18:59 +0000 |
commit | 1424c3c3e696868775ac5bfc57d27a0ac3bc6c63 (patch) | |
tree | a1fd477e6005ddadf4d7dee6b9770bea2887376d /lib/MC/MCDwarf.cpp | |
parent | 1359c6d71858c0de618474e5a51efaced42deca6 (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.cpp | 41 |
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; |