From 11fd7a22694465be63bb09a2f79d2b039df18d2a Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Fri, 18 Dec 2015 19:45:38 +0000 Subject: [PATCH] Revert "Improve DWARFDebugFrame::parse to also handle __eh_frame." This reverts commit r256008. Its breaking multiple buildbots, although works for me locally. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256013 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/DIContext.h | 3 +- include/llvm/DebugInfo/DWARF/DWARFContext.h | 10 +- .../llvm/DebugInfo/DWARF/DWARFDebugFrame.h | 6 +- include/llvm/DebugInfo/PDB/PDBContext.h | 3 +- lib/DebugInfo/DWARF/DWARFContext.cpp | 20 +- lib/DebugInfo/DWARF/DWARFDebugFrame.cpp | 182 ++---------- lib/DebugInfo/PDB/PDBContext.cpp | 3 +- test/tools/llvm-objdump/eh_frame-arm64.test | 44 +-- tools/llvm-objdump/MachODump.cpp | 264 +++++++++++++++++- tools/llvm-objdump/llvm-objdump.cpp | 14 +- tools/llvm-objdump/llvm-objdump.h | 2 - 11 files changed, 305 insertions(+), 246 deletions(-) diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 769c45d4b20..6659a97a042 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -140,8 +140,7 @@ public: DIContext(DIContextKind K) : Kind(K) {} virtual ~DIContext() {} - virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All, - bool DumpEH = false) = 0; + virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0; virtual DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index 71d5f25a420..ce253a05bf8 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -48,7 +48,6 @@ class DWARFContext : public DIContext { std::unique_ptr Aranges; std::unique_ptr Line; std::unique_ptr DebugFrame; - std::unique_ptr EHFrame; std::unique_ptr Macro; DWARFUnitSection DWOCUs; @@ -82,8 +81,7 @@ public: return DICtx->getKind() == CK_DWARF; } - void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All, - bool DumpEH = false) override; + void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override; typedef DWARFUnitSection::iterator_range cu_iterator_range; typedef DWARFUnitSection::iterator_range tu_iterator_range; @@ -170,9 +168,6 @@ public: /// Get a pointer to the parsed frame information object. const DWARFDebugFrame *getDebugFrame(); - /// Get a pointer to the parsed eh frame information object. - const DWARFDebugFrame *getEHFrame(); - /// Get a pointer to the parsed DebugMacro object. const DWARFDebugMacro *getDebugMacro(); @@ -196,7 +191,6 @@ public: virtual const DWARFSection &getLocSection() = 0; virtual StringRef getARangeSection() = 0; virtual StringRef getDebugFrameSection() = 0; - virtual StringRef getEHFrameSection() = 0; virtual const DWARFSection &getLineSection() = 0; virtual StringRef getStringSection() = 0; virtual StringRef getRangeSection() = 0; @@ -248,7 +242,6 @@ class DWARFContextInMemory : public DWARFContext { DWARFSection LocSection; StringRef ARangeSection; StringRef DebugFrameSection; - StringRef EHFrameSection; DWARFSection LineSection; StringRef StringSection; StringRef RangeSection; @@ -288,7 +281,6 @@ public: const DWARFSection &getLocSection() override { return LocSection; } StringRef getARangeSection() override { return ARangeSection; } StringRef getDebugFrameSection() override { return DebugFrameSection; } - StringRef getEHFrameSection() override { return EHFrameSection; } const DWARFSection &getLineSection() override { return LineSection; } StringRef getStringSection() override { return StringSection; } StringRef getRangeSection() override { return RangeSection; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h index cd76c909dda..be925cbe751 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -19,13 +19,11 @@ namespace llvm { class FrameEntry; -/// \brief A parsed .debug_frame or .eh_frame section +/// \brief A parsed .debug_frame section /// class DWARFDebugFrame { - // True if this is parsing an eh_frame section. - bool IsEH; public: - DWARFDebugFrame(bool IsEH); + DWARFDebugFrame(); ~DWARFDebugFrame(); /// \brief Dump the section data into the given stream. diff --git a/include/llvm/DebugInfo/PDB/PDBContext.h b/include/llvm/DebugInfo/PDB/PDBContext.h index 2034e3b004b..9404a592244 100644 --- a/include/llvm/DebugInfo/PDB/PDBContext.h +++ b/include/llvm/DebugInfo/PDB/PDBContext.h @@ -38,8 +38,7 @@ public: return DICtx->getKind() == CK_PDB; } - void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All, - bool DumpEH = false) override; + void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override; DILineInfo getLineInfoForAddress( uint64_t Address, diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index 6aa4675630f..a4195b75c47 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -72,7 +72,7 @@ static void dumpAccelSection(raw_ostream &OS, StringRef Name, Accel.dump(OS); } -void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH) { +void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) { if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) { OS << ".debug_abbrev contents:\n"; getDebugAbbrev()->dump(OS); @@ -125,10 +125,6 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH) { if (DumpType == DIDT_All || DumpType == DIDT_Frames) { OS << "\n.debug_frame contents:\n"; getDebugFrame()->dump(OS); - if (DumpEH) { - OS << "\n.eh_frame contents:\n"; - getEHFrame()->dump(OS); - } } if (DumpType == DIDT_All || DumpType == DIDT_Macro) { @@ -359,18 +355,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() { // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(), getAddressSize()); - DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */)); - DebugFrame->parse(debugFrameData); - return DebugFrame.get(); -} - -const DWARFDebugFrame *DWARFContext::getEHFrame() { - if (EHFrame) - return EHFrame.get(); - - DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(), - getAddressSize()); - DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */)); + DebugFrame.reset(new DWARFDebugFrame()); DebugFrame->parse(debugFrameData); return DebugFrame.get(); } @@ -656,7 +641,6 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, .Case("debug_line", &LineSection.Data) .Case("debug_aranges", &ARangeSection) .Case("debug_frame", &DebugFrameSection) - .Case("eh_frame", &EHFrameSection) .Case("debug_str", &StringSection) .Case("debug_ranges", &RangeSection) .Case("debug_macinfo", &MacinfoSection) diff --git a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index eff48708301..1aa31be71fe 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -10,7 +10,6 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" @@ -192,31 +191,19 @@ public: CIE(uint64_t Offset, uint64_t Length, uint8_t Version, SmallString<8> Augmentation, uint8_t AddressSize, uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor, - int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister, - SmallString<8> AugmentationData, Optional FDEPointerEncoding, - Optional LSDAPointerEncoding) + int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister) : FrameEntry(FK_CIE, Offset, Length), Version(Version), Augmentation(std::move(Augmentation)), AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize), CodeAlignmentFactor(CodeAlignmentFactor), DataAlignmentFactor(DataAlignmentFactor), - ReturnAddressRegister(ReturnAddressRegister), - AugmentationData(AugmentationData), - FDEPointerEncoding(FDEPointerEncoding), - LSDAPointerEncoding(LSDAPointerEncoding) { } + ReturnAddressRegister(ReturnAddressRegister) {} ~CIE() override {} - StringRef getAugmentationString() const { return Augmentation; } uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; } int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; } - Optional getFDEPointerEncoding() const { - return FDEPointerEncoding; - } - Optional getLSDAPointerEncoding() const { - return LSDAPointerEncoding; - } void dumpHeader(raw_ostream &OS) const override { OS << format("%08x %08x %08x CIE", @@ -236,8 +223,6 @@ public: (int32_t)DataAlignmentFactor); OS << format(" Return address column: %d\n", (int32_t)ReturnAddressRegister); - if (!AugmentationData.empty()) - OS << " Augmentation data: " << AugmentationData << "\n"; OS << "\n"; } @@ -254,11 +239,6 @@ private: uint64_t CodeAlignmentFactor; int64_t DataAlignmentFactor; uint64_t ReturnAddressRegister; - - // The following are used when the CIE represents an EH frame entry. - SmallString<8> AugmentationData; - Optional FDEPointerEncoding; - Optional LSDAPointerEncoding; }; @@ -443,7 +423,7 @@ void FrameEntry::dumpInstructions(raw_ostream &OS) const { } } -DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) { +DWARFDebugFrame::DWARFDebugFrame() { } DWARFDebugFrame::~DWARFDebugFrame() { @@ -459,39 +439,6 @@ static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, errs() << "\n"; } -static unsigned getSizeForEncoding(const DataExtractor &Data, - unsigned symbolEncoding) { - unsigned format = symbolEncoding & 0x0f; - switch (format) { - default: llvm_unreachable("Unknown Encoding"); - case dwarf::DW_EH_PE_absptr: - case dwarf::DW_EH_PE_signed: - return Data.getAddressSize(); - case dwarf::DW_EH_PE_udata2: - case dwarf::DW_EH_PE_sdata2: - return 2; - case dwarf::DW_EH_PE_udata4: - case dwarf::DW_EH_PE_sdata4: - return 4; - case dwarf::DW_EH_PE_udata8: - case dwarf::DW_EH_PE_sdata8: - return 8; - } -} - -static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset, - unsigned Encoding) { - switch (getSizeForEncoding(Data, Encoding)) { - case 2: - return Data.getU16(&Offset); - case 4: - return Data.getU32(&Offset); - case 8: - return Data.getU64(&Offset); - default: - llvm_unreachable("Illegal data size"); - } -} void DWARFDebugFrame::parse(DataExtractor Data) { uint32_t Offset = 0; @@ -500,14 +447,6 @@ void DWARFDebugFrame::parse(DataExtractor Data) { while (Data.isValidOffset(Offset)) { uint32_t StartOffset = Offset; - auto ReportError = [StartOffset](const char *ErrorMsg) { - std::string Str; - raw_string_ostream OS(Str); - OS << format(ErrorMsg, StartOffset); - OS.flush(); - report_fatal_error(Str); - }; - bool IsDWARF64 = false; uint64_t Length = Data.getU32(&Offset); uint64_t Id; @@ -526,136 +465,47 @@ void DWARFDebugFrame::parse(DataExtractor Data) { // read). // TODO: For honest DWARF64 support, DataExtractor will have to treat // offset_ptr as uint64_t* - uint32_t StartStructureOffset = Offset; uint32_t EndStructureOffset = Offset + static_cast(Length); // The Id field's size depends on the DWARF format - Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4); - bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || - Id == DW_CIE_ID || - (IsEH && !Id)); + Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4); + bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID); if (IsCIE) { uint8_t Version = Data.getU8(&Offset); const char *Augmentation = Data.getCStr(&Offset); - StringRef AugmentationString(Augmentation ? Augmentation : ""); - uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : - Data.getU8(&Offset); + uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : Data.getU8(&Offset); Data.setAddressSize(AddressSize); uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset); uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset); int64_t DataAlignmentFactor = Data.getSLEB128(&Offset); uint64_t ReturnAddressRegister = Data.getULEB128(&Offset); - // Parse the augmentation data for EH CIEs - StringRef AugmentationData; - Optional FDEPointerEncoding; - Optional LSDAPointerEncoding; - if (IsEH) { - Optional PersonalityEncoding; - Optional Personality; - - uint64_t AugmentationLength = 0; - uint32_t StartAugmentationOffset = 0; - uint32_t EndAugmentationOffset = 0; - - // Walk the augmentation string to get all the augmentation data. - for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) { - switch (AugmentationString[i]) { - default: - ReportError("Unknown augmentation character in entry at %lx"); - case 'L': - if (LSDAPointerEncoding) - ReportError("Duplicate LSDA encoding in entry at %lx"); - LSDAPointerEncoding = Data.getU8(&Offset); - break; - case 'P': { - if (Personality) - ReportError("Duplicate personality in entry at %lx"); - PersonalityEncoding = Data.getU8(&Offset); - Personality = readPointer(Data, Offset, *PersonalityEncoding); - break; - } - case 'R': - if (FDEPointerEncoding) - ReportError("Duplicate FDE encoding in entry at %lx"); - FDEPointerEncoding = Data.getU8(&Offset); - break; - case 'z': - if (i) - ReportError("'z' must be the first character at %lx"); - // Parse the augmentation length first. We only parse it if - // the string contains a 'z'. - AugmentationLength = Data.getULEB128(&Offset); - StartAugmentationOffset = Offset; - EndAugmentationOffset = - Offset + static_cast(AugmentationLength); - } - } - - if (Offset != EndAugmentationOffset) - ReportError("Parsing augmentation data at %lx failed"); - - AugmentationData = Data.getData().slice(StartAugmentationOffset, - EndAugmentationOffset); - } - auto Cie = make_unique(StartOffset, Length, Version, StringRef(Augmentation), AddressSize, SegmentDescriptorSize, CodeAlignmentFactor, - DataAlignmentFactor, ReturnAddressRegister, - AugmentationData, FDEPointerEncoding, - LSDAPointerEncoding); + DataAlignmentFactor, ReturnAddressRegister); CIEs[StartOffset] = Cie.get(); Entries.emplace_back(std::move(Cie)); } else { // FDE uint64_t CIEPointer = Id; - uint64_t InitialLocation = 0; - uint64_t AddressRange = 0; - CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer]; - - if (IsEH) { - // The address size is encoded in the CIE we reference. - if (!Cie) - ReportError("Parsing FDE data at %lx failed due to missing CIE"); - - Optional FDEPointerEncoding = Cie->getFDEPointerEncoding(); - if (!FDEPointerEncoding) - ReportError("Parsing at %lx failed due to missing pointer encoding"); - - InitialLocation = readPointer(Data, Offset, *FDEPointerEncoding); - AddressRange = readPointer(Data, Offset, *FDEPointerEncoding); - StringRef AugmentationString = Cie->getAugmentationString(); - if (!AugmentationString.empty()) { - // Parse the augmentation length and data for this FDE. - uint64_t AugmentationLength = Data.getULEB128(&Offset); - - uint32_t EndAugmentationOffset = - Offset + static_cast(AugmentationLength); - - // Decode the LSDA if the CIE augmentation string said we should. - uint64_t LSDA = 0; - if (Optional Encoding = Cie->getLSDAPointerEncoding()) - LSDA = readPointer(Data, Offset, *Encoding); - - if (Offset != EndAugmentationOffset) - ReportError("Parsing augmentation data at %lx failed"); - } - } else { - InitialLocation = Data.getAddress(&Offset); - AddressRange = Data.getAddress(&Offset); - } + uint64_t InitialLocation = Data.getAddress(&Offset); + uint64_t AddressRange = Data.getAddress(&Offset); Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer, InitialLocation, AddressRange, - Cie)); + CIEs[CIEPointer])); } Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset); - if (Offset != EndStructureOffset) - ReportError("Parsing entry instructions at %lx failed"); + if (Offset != EndStructureOffset) { + std::string Str; + raw_string_ostream OS(Str); + OS << format("Parsing entry instructions at %lx failed", StartOffset); + report_fatal_error(Str); + } } } diff --git a/lib/DebugInfo/PDB/PDBContext.cpp b/lib/DebugInfo/PDB/PDBContext.cpp index 561a91ea08b..ca2ae6665ce 100644 --- a/lib/DebugInfo/PDB/PDBContext.cpp +++ b/lib/DebugInfo/PDB/PDBContext.cpp @@ -28,8 +28,7 @@ PDBContext::PDBContext(const COFFObjectFile &Object, Session->setLoadAddress(ImageBase.get()); } -void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType, - bool DumpEH) {} +void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {} DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier) { diff --git a/test/tools/llvm-objdump/eh_frame-arm64.test b/test/tools/llvm-objdump/eh_frame-arm64.test index adfd4cc4f26..f25e035a266 100644 --- a/test/tools/llvm-objdump/eh_frame-arm64.test +++ b/test/tools/llvm-objdump/eh_frame-arm64.test @@ -1,23 +1,23 @@ -# RUN: llvm-objdump -dwarf=frames %p/Inputs/eh_frame.macho-arm64 2>/dev/null | FileCheck %s +# RUN: llvm-objdump -unwind-info %p/Inputs/eh_frame.macho-arm64 2>/dev/null | FileCheck %s -# CHECK: .eh_frame contents: - -# CHECK: 00000000 00000010 ffffffff CIE -# CHECK: Version: 1 -# CHECK: Augmentation: "zR" -# CHECK: Code alignment factor: 1 -# CHECK: Data alignment factor: -8 -# CHECK: Return address column: 30 -# CHECK: Augmentation data: - -# CHECK: DW_CFA_def_cfa: reg31 +0 - -# CHECK: 00000014 00000020 00000018 FDE cie=00000018 pc=ffffffe4...00000004 -# CHECK: DW_CFA_advance_loc: 8 -# CHECK: DW_CFA_def_cfa_offset: +16 -# CHECK: DW_CFA_offset: reg30 -8 -# CHECK: DW_CFA_offset: reg29 -16 -# CHECK: DW_CFA_nop: -# CHECK: DW_CFA_nop: -# CHECK: DW_CFA_nop: -# CHECK: DW_CFA_nop: +# CHECK: Contents of __eh_frame section: +# CHECK: CIE: +# CHECK: Length: 16 +# CHECK: CIE ID: 0 +# CHECK: Version: 1 +# CHECK: Augmentation String: zR +# CHECK: Code Alignment Factor: 1 +# CHECK: Data Alignment Factor: -8 +# CHECK: Return Address Register: 30 +# CHECK: Augmentation Data Length: 1 +# CHECK: FDE Address Pointer Encoding: 16 +# CHECK: Instructions: +# CHECK: 0c 1f 00 +# CHECK: FDE: +# CHECK: Length: 32 +# CHECK: CIE Offset: 0 +# CHECK: PC Begin: ffffffffffffffe4 +# CHECK: PC Range: 0000000000000020 +# CHECK: Augmentation Data Length: 0 +# CHECK: Instructions: +# CHECK: 48 0e 10 9e 01 9d 02 00 00 00 00 diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index e68a1432249..defd2d48a9f 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -1210,12 +1210,6 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF, printLazyBindTable(MachOOF); if (WeakBind) printWeakBindTable(MachOOF); - - if (DwarfDumpType != DIDT_Null) { - std::unique_ptr DICtx(new DWARFContextInMemory(*MachOOF)); - // Dump the complete DWARF structure. - DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */); - } } // printUnknownCPUType() helps print_fat_headers for unknown CPU's. @@ -6754,6 +6748,262 @@ static void printMachOUnwindInfoSection(const MachOObjectFile *Obj, } } +static unsigned getSizeForEncoding(bool is64Bit, + unsigned symbolEncoding) { + unsigned format = symbolEncoding & 0x0f; + switch (format) { + default: llvm_unreachable("Unknown Encoding"); + case dwarf::DW_EH_PE_absptr: + case dwarf::DW_EH_PE_signed: + return is64Bit ? 8 : 4; + case dwarf::DW_EH_PE_udata2: + case dwarf::DW_EH_PE_sdata2: + return 2; + case dwarf::DW_EH_PE_udata4: + case dwarf::DW_EH_PE_sdata4: + return 4; + case dwarf::DW_EH_PE_udata8: + case dwarf::DW_EH_PE_sdata8: + return 8; + } +} + +static uint64_t readPointer(const char *&Pos, bool is64Bit, unsigned Encoding) { + switch (getSizeForEncoding(is64Bit, Encoding)) { + case 2: + return readNext(Pos); + break; + case 4: + return readNext(Pos); + break; + case 8: + return readNext(Pos); + break; + default: + llvm_unreachable("Illegal data size"); + } +} + +static void printMachOEHFrameSection(const MachOObjectFile *Obj, + std::map &Symbols, + const SectionRef &EHFrame) { + if (!Obj->isLittleEndian()) { + outs() << "warning: cannot handle big endian __eh_frame section\n"; + return; + } + + bool is64Bit = Obj->is64Bit(); + + outs() << "Contents of __eh_frame section:\n"; + + StringRef Contents; + EHFrame.getContents(Contents); + + /// A few fields of the CIE are used when decoding the FDE's. This struct + /// will cache those fields we need so that we don't have to decode it + /// repeatedly for each FDE that references it. + struct DecodedCIE { + Optional FDEPointerEncoding; + Optional LSDAPointerEncoding; + bool hasAugmentationLength; + }; + + // Map from the start offset of the CIE to the cached data for that CIE. + DenseMap CachedCIEs; + + for (const char *Pos = Contents.data(), *End = Contents.end(); Pos != End; ) { + + const char *EntryStartPos = Pos; + + uint64_t Length = readNext(Pos); + if (Length == 0xffffffff) + Length = readNext(Pos); + + // Save the Pos so that we can check the length we encoded against what we + // end up decoding. + const char *PosAfterLength = Pos; + const char *EntryEndPos = PosAfterLength + Length; + + assert(EntryEndPos <= End && + "__eh_frame entry length exceeds section size"); + + uint32_t ID = readNext(Pos); + if (ID == 0) { + // This is a CIE. + + uint32_t Version = readNext(Pos); + + // Parse a null terminated augmentation string + SmallString<8> AugmentationString; + for (uint8_t Char = readNext(Pos); Char; + Char = readNext(Pos)) + AugmentationString.push_back(Char); + + // Optionally parse the EH data if the augmentation string says it's there. + Optional EHData; + if (StringRef(AugmentationString).count("eh")) + EHData = is64Bit ? readNext(Pos) : readNext(Pos); + + unsigned ULEBByteCount; + uint64_t CodeAlignmentFactor = decodeULEB128((const uint8_t *)Pos, + &ULEBByteCount); + Pos += ULEBByteCount; + + int64_t DataAlignmentFactor = decodeSLEB128((const uint8_t *)Pos, + &ULEBByteCount); + Pos += ULEBByteCount; + + uint32_t ReturnAddressRegister = readNext(Pos); + + Optional AugmentationLength; + Optional LSDAPointerEncoding; + Optional PersonalityEncoding; + Optional Personality; + Optional FDEPointerEncoding; + if (!AugmentationString.empty() && AugmentationString.front() == 'z') { + AugmentationLength = decodeULEB128((const uint8_t *)Pos, + &ULEBByteCount); + Pos += ULEBByteCount; + + // Walk the augmentation string to get all the augmentation data. + for (unsigned i = 1, e = AugmentationString.size(); i != e; ++i) { + char Char = AugmentationString[i]; + switch (Char) { + case 'e': + assert((i + 1) != e && AugmentationString[i + 1] == 'h' && + "Expected 'eh' in augmentation string"); + break; + case 'L': + assert(!LSDAPointerEncoding && "Duplicate LSDA encoding"); + LSDAPointerEncoding = readNext(Pos); + break; + case 'P': { + assert(!Personality && "Duplicate personality"); + PersonalityEncoding = readNext(Pos); + Personality = readPointer(Pos, is64Bit, *PersonalityEncoding); + break; + } + case 'R': + assert(!FDEPointerEncoding && "Duplicate FDE encoding"); + FDEPointerEncoding = readNext(Pos); + break; + case 'z': + llvm_unreachable("'z' must be first in the augmentation string"); + } + } + } + + outs() << "CIE:\n"; + outs() << " Length: " << Length << "\n"; + outs() << " CIE ID: " << ID << "\n"; + outs() << " Version: " << Version << "\n"; + outs() << " Augmentation String: " << AugmentationString << "\n"; + if (EHData) + outs() << " EHData: " << *EHData << "\n"; + outs() << " Code Alignment Factor: " << CodeAlignmentFactor << "\n"; + outs() << " Data Alignment Factor: " << DataAlignmentFactor << "\n"; + outs() << " Return Address Register: " << ReturnAddressRegister << "\n"; + if (AugmentationLength) { + outs() << " Augmentation Data Length: " << *AugmentationLength << "\n"; + if (LSDAPointerEncoding) { + outs() << " FDE LSDA Pointer Encoding: " + << *LSDAPointerEncoding << "\n"; + } + if (Personality) { + outs() << " Personality Encoding: " << *PersonalityEncoding << "\n"; + outs() << " Personality: " << *Personality << "\n"; + } + if (FDEPointerEncoding) { + outs() << " FDE Address Pointer Encoding: " + << *FDEPointerEncoding << "\n"; + } + } + // FIXME: Handle instructions. + // For now just emit some bytes + outs() << " Instructions:\n "; + dumpBytes(makeArrayRef((const uint8_t*)Pos, (const uint8_t*)EntryEndPos), + outs()); + outs() << "\n"; + Pos = EntryEndPos; + + // Cache this entry. + uint64_t Offset = EntryStartPos - Contents.data(); + CachedCIEs[Offset] = { FDEPointerEncoding, LSDAPointerEncoding, + AugmentationLength.hasValue() }; + continue; + } + + // This is an FDE. + // The CIE pointer for an FDE is the same location as the ID which we + // already read. + uint32_t CIEPointer = ID; + + const char *CIEStart = PosAfterLength - CIEPointer; + assert(CIEStart >= Contents.data() && + "FDE points to CIE before the __eh_frame start"); + + uint64_t CIEOffset = CIEStart - Contents.data(); + auto CIEIt = CachedCIEs.find(CIEOffset); + if (CIEIt == CachedCIEs.end()) + llvm_unreachable("Couldn't find CIE at offset in to __eh_frame section"); + + const DecodedCIE &CIE = CIEIt->getSecond(); + assert(CIE.FDEPointerEncoding && + "FDE references CIE which did not set pointer encoding"); + + uint64_t PCPointerSize = getSizeForEncoding(is64Bit, + *CIE.FDEPointerEncoding); + + uint64_t PCBegin = readPointer(Pos, is64Bit, *CIE.FDEPointerEncoding); + uint64_t PCRange = readPointer(Pos, is64Bit, *CIE.FDEPointerEncoding); + + Optional AugmentationLength; + uint32_t LSDAPointerSize; + Optional LSDAPointer; + if (CIE.hasAugmentationLength) { + unsigned ULEBByteCount; + AugmentationLength = decodeULEB128((const uint8_t *)Pos, + &ULEBByteCount); + Pos += ULEBByteCount; + + // Decode the LSDA if the CIE augmentation string said we should. + if (CIE.LSDAPointerEncoding) { + LSDAPointerSize = getSizeForEncoding(is64Bit, *CIE.LSDAPointerEncoding); + LSDAPointer = readPointer(Pos, is64Bit, *CIE.LSDAPointerEncoding); + } + } + + outs() << "FDE:\n"; + outs() << " Length: " << Length << "\n"; + outs() << " CIE Offset: " << CIEOffset << "\n"; + + if (PCPointerSize == 8) { + outs() << format(" PC Begin: %016" PRIx64, PCBegin) << "\n"; + outs() << format(" PC Range: %016" PRIx64, PCRange) << "\n"; + } else { + outs() << format(" PC Begin: %08" PRIx64, PCBegin) << "\n"; + outs() << format(" PC Range: %08" PRIx64, PCRange) << "\n"; + } + if (AugmentationLength) { + outs() << " Augmentation Data Length: " << *AugmentationLength << "\n"; + if (LSDAPointer) { + if (LSDAPointerSize == 8) + outs() << format(" LSDA Pointer: %016\n" PRIx64, *LSDAPointer); + else + outs() << format(" LSDA Pointer: %08\n" PRIx64, *LSDAPointer); + } + } + + // FIXME: Handle instructions. + // For now just emit some bytes + outs() << " Instructions:\n "; + dumpBytes(makeArrayRef((const uint8_t*)Pos, (const uint8_t*)EntryEndPos), + outs()); + outs() << "\n"; + Pos = EntryEndPos; + } +} + void llvm::printMachOUnwindInfo(const MachOObjectFile *Obj) { std::map Symbols; for (const SymbolRef &SymRef : Obj->symbols()) { @@ -6774,6 +7024,8 @@ void llvm::printMachOUnwindInfo(const MachOObjectFile *Obj) { printMachOCompactUnwindSection(Obj, Symbols, Section); else if (SectName == "__unwind_info") printMachOUnwindInfoSection(Obj, Symbols, Section); + else if (SectName == "__eh_frame") + printMachOEHFrameSection(Obj, Symbols, Section); } } diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 970fc617ccb..d46ea38d1d1 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -22,7 +22,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/CodeGen/FaultMaps.h" -#include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler.h" @@ -177,11 +176,6 @@ cl::opt cl::opt PrintFaultMaps("fault-map-section", cl::desc("Display contents of faultmap section")); -cl::opt llvm::DwarfDumpType( - "dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"), - cl::values(clEnumValN(DIDT_Frames, "frames", ".debug_frame"), - clEnumValEnd)); - static StringRef ToolName; namespace { @@ -1578,11 +1572,6 @@ static void DumpObject(const ObjectFile *o) { printRawClangAST(o); if (PrintFaultMaps) printFaultMaps(o); - if (DwarfDumpType != DIDT_Null) { - std::unique_ptr DICtx(new DWARFContextInMemory(*o)); - // Dump the complete DWARF structure. - DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */); - } } /// @brief Dump each object file in \a a; @@ -1675,8 +1664,7 @@ int main(int argc, char **argv) { && !(DylibId && MachOOpt) && !(ObjcMetaData && MachOOpt) && !(FilterSections.size() != 0 && MachOOpt) - && !PrintFaultMaps - && DwarfDumpType == DIDT_Null) { + && !PrintFaultMaps) { cl::PrintHelpMessage(); return 2; } diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h index 7303c3a0418..f74ed010d1d 100644 --- a/tools/llvm-objdump/llvm-objdump.h +++ b/tools/llvm-objdump/llvm-objdump.h @@ -10,7 +10,6 @@ #define LLVM_TOOLS_LLVM_OBJDUMP_LLVM_OBJDUMP_H #include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/DIContext.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DataTypes.h" @@ -54,7 +53,6 @@ extern cl::opt SectionContents; extern cl::opt SymbolTable; extern cl::opt UnwindInfo; extern cl::opt PrintImmHex; -extern cl::opt DwarfDumpType; // Various helper functions. void error(std::error_code ec); -- 2.34.1