[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