[llvm] r258811 - Re-submit r256008 "Improve DWARFDebugFrame::parse to also handle __eh_frame."
Rafael EspĂndola via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 26 08:50:49 PST 2016
Thanks!
On 26 January 2016 at 07:09, Igor Laevsky via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: igor.laevsky
> Date: Tue Jan 26 09:09:42 2016
> New Revision: 258811
>
> URL: http://llvm.org/viewvc/llvm-project?rev=258811&view=rev
> Log:
> Re-submit r256008 "Improve DWARFDebugFrame::parse to also handle __eh_frame."
>
> Originally this change was causing failures on windows buildbots.
> But those problems were fixed in r258806.
>
>
> Modified:
> llvm/trunk/include/llvm/DebugInfo/DIContext.h
> llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
> llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
> llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h
> llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
> llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
> llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp
> llvm/trunk/test/tools/llvm-objdump/eh_frame-arm64.test
> llvm/trunk/tools/llvm-objdump/MachODump.cpp
> llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
> llvm/trunk/tools/llvm-objdump/llvm-objdump.h
>
> Modified: llvm/trunk/include/llvm/DebugInfo/DIContext.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DIContext.h?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/DIContext.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/DIContext.h Tue Jan 26 09:09:42 2016
> @@ -140,7 +140,8 @@ public:
> DIContext(DIContextKind K) : Kind(K) {}
> virtual ~DIContext() {}
>
> - virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0;
> + virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
> + bool DumpEH = false) = 0;
>
> virtual DILineInfo getLineInfoForAddress(uint64_t Address,
> DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
>
> Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h Tue Jan 26 09:09:42 2016
> @@ -48,6 +48,7 @@ class DWARFContext : public DIContext {
> std::unique_ptr<DWARFDebugAranges> Aranges;
> std::unique_ptr<DWARFDebugLine> Line;
> std::unique_ptr<DWARFDebugFrame> DebugFrame;
> + std::unique_ptr<DWARFDebugFrame> EHFrame;
> std::unique_ptr<DWARFDebugMacro> Macro;
>
> DWARFUnitSection<DWARFCompileUnit> DWOCUs;
> @@ -81,7 +82,8 @@ public:
> return DICtx->getKind() == CK_DWARF;
> }
>
> - void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
> + void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
> + bool DumpEH = false) override;
>
> typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range;
> typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range;
> @@ -168,6 +170,9 @@ 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();
>
> @@ -191,6 +196,7 @@ 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;
> @@ -242,6 +248,7 @@ class DWARFContextInMemory : public DWAR
> DWARFSection LocSection;
> StringRef ARangeSection;
> StringRef DebugFrameSection;
> + StringRef EHFrameSection;
> DWARFSection LineSection;
> StringRef StringSection;
> StringRef RangeSection;
> @@ -281,6 +288,7 @@ 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; }
>
> Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h Tue Jan 26 09:09:42 2016
> @@ -19,11 +19,13 @@ namespace llvm {
>
> class FrameEntry;
>
> -/// \brief A parsed .debug_frame section
> +/// \brief A parsed .debug_frame or .eh_frame section
> ///
> class DWARFDebugFrame {
> + // True if this is parsing an eh_frame section.
> + bool IsEH;
> public:
> - DWARFDebugFrame();
> + DWARFDebugFrame(bool IsEH);
> ~DWARFDebugFrame();
>
> /// \brief Dump the section data into the given stream.
>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBContext.h Tue Jan 26 09:09:42 2016
> @@ -38,7 +38,8 @@ public:
> return DICtx->getKind() == CK_PDB;
> }
>
> - void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
> + void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
> + bool DumpEH = false) override;
>
> DILineInfo getLineInfoForAddress(
> uint64_t Address,
>
> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Tue Jan 26 09:09:42 2016
> @@ -72,7 +72,7 @@ static void dumpAccelSection(raw_ostream
> Accel.dump(OS);
> }
>
> -void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
> +void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH) {
> if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
> OS << ".debug_abbrev contents:\n";
> getDebugAbbrev()->dump(OS);
> @@ -125,6 +125,10 @@ void DWARFContext::dump(raw_ostream &OS,
> 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) {
> @@ -355,7 +359,18 @@ const DWARFDebugFrame *DWARFContext::get
> // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
> DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
> getAddressSize());
> - DebugFrame.reset(new DWARFDebugFrame());
> + 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->parse(debugFrameData);
> return DebugFrame.get();
> }
> @@ -641,6 +656,7 @@ DWARFContextInMemory::DWARFContextInMemo
> .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)
>
> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp Tue Jan 26 09:09:42 2016
> @@ -10,6 +10,7 @@
> #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"
> @@ -199,19 +200,31 @@ 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)
> + int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
> + SmallString<8> AugmentationData, Optional<uint32_t> FDEPointerEncoding,
> + Optional<uint32_t> LSDAPointerEncoding)
> : FrameEntry(FK_CIE, Offset, Length), Version(Version),
> Augmentation(std::move(Augmentation)),
> AddressSize(AddressSize),
> SegmentDescriptorSize(SegmentDescriptorSize),
> CodeAlignmentFactor(CodeAlignmentFactor),
> DataAlignmentFactor(DataAlignmentFactor),
> - ReturnAddressRegister(ReturnAddressRegister) {}
> + ReturnAddressRegister(ReturnAddressRegister),
> + AugmentationData(AugmentationData),
> + FDEPointerEncoding(FDEPointerEncoding),
> + LSDAPointerEncoding(LSDAPointerEncoding) { }
>
> ~CIE() override {}
>
> + StringRef getAugmentationString() const { return Augmentation; }
> uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
> int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
> + Optional<uint32_t> getFDEPointerEncoding() const {
> + return FDEPointerEncoding;
> + }
> + Optional<uint32_t> getLSDAPointerEncoding() const {
> + return LSDAPointerEncoding;
> + }
>
> void dumpHeader(raw_ostream &OS) const override {
> OS << format("%08x %08x %08x CIE",
> @@ -231,6 +244,8 @@ public:
> (int32_t)DataAlignmentFactor);
> OS << format(" Return address column: %d\n",
> (int32_t)ReturnAddressRegister);
> + if (!AugmentationData.empty())
> + OS << " Augmentation data: " << AugmentationData << "\n";
> OS << "\n";
> }
>
> @@ -247,6 +262,11 @@ 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<uint32_t> FDEPointerEncoding;
> + Optional<uint32_t> LSDAPointerEncoding;
> };
>
>
> @@ -431,7 +451,7 @@ void FrameEntry::dumpInstructions(raw_os
> }
> }
>
> -DWARFDebugFrame::DWARFDebugFrame() {
> +DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) {
> }
>
> DWARFDebugFrame::~DWARFDebugFrame() {
> @@ -447,6 +467,39 @@ static void LLVM_ATTRIBUTE_UNUSED dumpDa
> 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;
> @@ -455,6 +508,14 @@ void DWARFDebugFrame::parse(DataExtracto
> 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;
> @@ -473,47 +534,136 @@ void DWARFDebugFrame::parse(DataExtracto
> // 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<uint32_t>(Length);
>
> // The Id field's size depends on the DWARF format
> - Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4);
> - bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID);
> + Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
> + bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) ||
> + Id == DW_CIE_ID ||
> + (IsEH && !Id));
>
> if (IsCIE) {
> uint8_t Version = Data.getU8(&Offset);
> const char *Augmentation = Data.getCStr(&Offset);
> - uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : Data.getU8(&Offset);
> + StringRef AugmentationString(Augmentation ? Augmentation : "");
> + 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<uint32_t> FDEPointerEncoding;
> + Optional<uint32_t> LSDAPointerEncoding;
> + if (IsEH) {
> + Optional<uint32_t> PersonalityEncoding;
> + Optional<uint64_t> 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<uint32_t>(AugmentationLength);
> + }
> + }
> +
> + if (Offset != EndAugmentationOffset)
> + ReportError("Parsing augmentation data at %lx failed");
> +
> + AugmentationData = Data.getData().slice(StartAugmentationOffset,
> + EndAugmentationOffset);
> + }
> +
> auto Cie = make_unique<CIE>(StartOffset, Length, Version,
> StringRef(Augmentation), AddressSize,
> SegmentDescriptorSize, CodeAlignmentFactor,
> - DataAlignmentFactor, ReturnAddressRegister);
> + DataAlignmentFactor, ReturnAddressRegister,
> + AugmentationData, FDEPointerEncoding,
> + LSDAPointerEncoding);
> CIEs[StartOffset] = Cie.get();
> Entries.emplace_back(std::move(Cie));
> } else {
> // FDE
> uint64_t CIEPointer = Id;
> - uint64_t InitialLocation = Data.getAddress(&Offset);
> - uint64_t AddressRange = Data.getAddress(&Offset);
> + 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<uint32_t> 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<uint32_t>(AugmentationLength);
> +
> + // Decode the LSDA if the CIE augmentation string said we should.
> + uint64_t LSDA = 0;
> + if (Optional<uint32_t> 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);
> + }
>
> Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
> InitialLocation, AddressRange,
> - CIEs[CIEPointer]));
> + Cie));
> }
>
> Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
>
> - if (Offset != EndStructureOffset) {
> - std::string Str;
> - raw_string_ostream OS(Str);
> - OS << format("Parsing entry instructions at %lx failed", StartOffset);
> - report_fatal_error(Str);
> - }
> + if (Offset != EndStructureOffset)
> + ReportError("Parsing entry instructions at %lx failed");
> }
> }
>
>
> Modified: llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/PDB/PDBContext.cpp Tue Jan 26 09:09:42 2016
> @@ -28,7 +28,8 @@ PDBContext::PDBContext(const COFFObjectF
> Session->setLoadAddress(ImageBase.get());
> }
>
> -void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}
> +void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType,
> + bool DumpEH) {}
>
> DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
> DILineInfoSpecifier Specifier) {
>
> Modified: llvm/trunk/test/tools/llvm-objdump/eh_frame-arm64.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/eh_frame-arm64.test?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-objdump/eh_frame-arm64.test (original)
> +++ llvm/trunk/test/tools/llvm-objdump/eh_frame-arm64.test Tue Jan 26 09:09:42 2016
> @@ -1,23 +1,23 @@
> -# RUN: llvm-objdump -unwind-info %p/Inputs/eh_frame.macho-arm64 2>/dev/null | FileCheck %s
> +# RUN: llvm-objdump -dwarf=frames %p/Inputs/eh_frame.macho-arm64 2>/dev/null | FileCheck %s
>
> -# 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
> +# 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:
>
> Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
> +++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Tue Jan 26 09:09:42 2016
> @@ -1214,6 +1214,12 @@ static void ProcessMachO(StringRef Filen
> printLazyBindTable(MachOOF);
> if (WeakBind)
> printWeakBindTable(MachOOF);
> +
> + if (DwarfDumpType != DIDT_Null) {
> + std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*MachOOF));
> + // Dump the complete DWARF structure.
> + DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */);
> + }
> }
>
> // printUnknownCPUType() helps print_fat_headers for unknown CPU's.
> @@ -6750,262 +6756,6 @@ static void printMachOUnwindInfoSection(
> }
> }
>
> -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<uint16_t>(Pos);
> - break;
> - case 4:
> - return readNext<uint32_t>(Pos);
> - break;
> - case 8:
> - return readNext<uint64_t>(Pos);
> - break;
> - default:
> - llvm_unreachable("Illegal data size");
> - }
> -}
> -
> -static void printMachOEHFrameSection(const MachOObjectFile *Obj,
> - std::map<uint64_t, SymbolRef> &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<uint32_t> FDEPointerEncoding;
> - Optional<uint32_t> LSDAPointerEncoding;
> - bool hasAugmentationLength;
> - };
> -
> - // Map from the start offset of the CIE to the cached data for that CIE.
> - DenseMap<uint64_t, DecodedCIE> CachedCIEs;
> -
> - for (const char *Pos = Contents.data(), *End = Contents.end(); Pos != End; ) {
> -
> - const char *EntryStartPos = Pos;
> -
> - uint64_t Length = readNext<uint32_t>(Pos);
> - if (Length == 0xffffffff)
> - Length = readNext<uint64_t>(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<uint32_t>(Pos);
> - if (ID == 0) {
> - // This is a CIE.
> -
> - uint32_t Version = readNext<uint8_t>(Pos);
> -
> - // Parse a null terminated augmentation string
> - SmallString<8> AugmentationString;
> - for (uint8_t Char = readNext<uint8_t>(Pos); Char;
> - Char = readNext<uint8_t>(Pos))
> - AugmentationString.push_back(Char);
> -
> - // Optionally parse the EH data if the augmentation string says it's there.
> - Optional<uint64_t> EHData;
> - if (StringRef(AugmentationString).count("eh"))
> - EHData = is64Bit ? readNext<uint64_t>(Pos) : readNext<uint32_t>(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<uint8_t>(Pos);
> -
> - Optional<uint64_t> AugmentationLength;
> - Optional<uint32_t> LSDAPointerEncoding;
> - Optional<uint32_t> PersonalityEncoding;
> - Optional<uint64_t> Personality;
> - Optional<uint32_t> 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<uint8_t>(Pos);
> - break;
> - case 'P': {
> - assert(!Personality && "Duplicate personality");
> - PersonalityEncoding = readNext<uint8_t>(Pos);
> - Personality = readPointer(Pos, is64Bit, *PersonalityEncoding);
> - break;
> - }
> - case 'R':
> - assert(!FDEPointerEncoding && "Duplicate FDE encoding");
> - FDEPointerEncoding = readNext<uint8_t>(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<uint64_t> AugmentationLength;
> - uint32_t LSDAPointerSize;
> - Optional<uint64_t> 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<uint64_t, SymbolRef> Symbols;
> for (const SymbolRef &SymRef : Obj->symbols()) {
> @@ -7026,8 +6776,6 @@ void llvm::printMachOUnwindInfo(const Ma
> printMachOCompactUnwindSection(Obj, Symbols, Section);
> else if (SectName == "__unwind_info")
> printMachOUnwindInfoSection(Obj, Symbols, Section);
> - else if (SectName == "__eh_frame")
> - printMachOEHFrameSection(Obj, Symbols, Section);
> }
> }
>
>
> Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
> +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Tue Jan 26 09:09:42 2016
> @@ -22,6 +22,7 @@
> #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"
> @@ -181,6 +182,11 @@ cl::opt<bool>
> cl::opt<bool> PrintFaultMaps("fault-map-section",
> cl::desc("Display contents of faultmap section"));
>
> +cl::opt<DIDumpType> 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 {
> @@ -1561,6 +1567,11 @@ static void DumpObject(const ObjectFile
> printRawClangAST(o);
> if (PrintFaultMaps)
> printFaultMaps(o);
> + if (DwarfDumpType != DIDT_Null) {
> + std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*o));
> + // Dump the complete DWARF structure.
> + DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */);
> + }
> }
>
> /// @brief Dump each object file in \a a;
> @@ -1654,7 +1665,8 @@ int main(int argc, char **argv) {
> && !(DylibId && MachOOpt)
> && !(ObjcMetaData && MachOOpt)
> && !(FilterSections.size() != 0 && MachOOpt)
> - && !PrintFaultMaps) {
> + && !PrintFaultMaps
> + && DwarfDumpType == DIDT_Null) {
> cl::PrintHelpMessage();
> return 2;
> }
>
> Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=258811&r1=258810&r2=258811&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original)
> +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Tue Jan 26 09:09:42 2016
> @@ -10,6 +10,7 @@
> #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/Compiler.h"
> #include "llvm/Support/DataTypes.h"
> @@ -55,6 +56,7 @@ extern cl::opt<bool> SectionContents;
> extern cl::opt<bool> SymbolTable;
> extern cl::opt<bool> UnwindInfo;
> extern cl::opt<bool> PrintImmHex;
> +extern cl::opt<DIDumpType> DwarfDumpType;
>
> // Various helper functions.
> void error(std::error_code ec);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list