dwarfdump: Reference the appropriate line table segment when dumping dwp files
authorDavid Blaikie <dblaikie@gmail.com>
Tue, 17 Nov 2015 21:08:05 +0000 (21:08 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Tue, 17 Nov 2015 21:08:05 +0000 (21:08 +0000)
Also improves .dwo type unit dumping which didn't handle this either.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253377 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
include/llvm/DebugInfo/DWARF/DWARFUnit.h
lib/DebugInfo/DWARF/DWARFContext.cpp
lib/DebugInfo/DWARF/DWARFUnit.cpp
test/DebugInfo/dwarfdump-dwp.test

index 84f12a52062c0a0b58b0164968fbebb84c305df4..bae3154b3b5f25ec80539fce8fd03186032a1999 100644 (file)
@@ -18,10 +18,10 @@ class DWARFCompileUnit : public DWARFUnit {
 public:
   DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
                    const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
-                   StringRef SOS, StringRef AOS, bool LE,
+                   StringRef SOS, StringRef AOS, StringRef LS, bool LE,
                    const DWARFUnitSectionBase &UnitSection,
                    const DWARFUnitIndex::Entry *Entry)
-      : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LE, UnitSection,
+      : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, UnitSection,
                   Entry) {}
   void dump(raw_ostream &OS);
   static const DWARFSectionKind Section = DW_SECT_INFO;
index 5265ea49d68786600f1c57305ff3e6d7a3e181f3..894a88dce440ba1277cd67bb2cd60e14c120649c 100644 (file)
@@ -21,10 +21,10 @@ private:
 public:
   DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
                 const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
-                StringRef SOS, StringRef AOS, bool LE,
+                StringRef SOS, StringRef AOS, StringRef LS, bool LE,
                 const DWARFUnitSectionBase &UnitSection,
                 const DWARFUnitIndex::Entry *Entry)
-      : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LE, UnitSection,
+      : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, UnitSection,
                   Entry) {}
   uint32_t getHeaderSize() const override {
     return DWARFUnit::getHeaderSize() + 12;
index 4fb8ba077373fab4c66cf40bb9a7b7a3b51e1bad..681b2aa19a79d42427e717cd386c55c814a14a4f 100644 (file)
@@ -46,7 +46,8 @@ public:
 protected:
   virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
                          const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
-                         StringRef SOS, StringRef AOS, bool isLittleEndian) = 0;
+                         StringRef SOS, StringRef AOS, StringRef LS,
+                         bool isLittleEndian) = 0;
 
   ~DWARFUnitSectionBase() = default;
 };
@@ -83,16 +84,16 @@ public:
 private:
   void parseImpl(DWARFContext &Context, const DWARFSection &Section,
                  const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
-                 StringRef SOS, StringRef AOS, bool LE) override {
+                 StringRef SOS, StringRef AOS, StringRef LS, bool LE) override {
     if (Parsed)
       return;
     const auto &Index = getDWARFUnitIndex(Context, UnitType::Section);
     DataExtractor Data(Section.Data, LE, 0);
     uint32_t Offset = 0;
     while (Data.isValidOffset(Offset)) {
-      auto U =
-          llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS, AOS,
-                                      LE, *this, Index.getFromOffset(Offset));
+      auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
+                                           AOS, LS, LE, *this,
+                                           Index.getFromOffset(Offset));
       if (!U->extract(Data, &Offset))
         break;
       this->push_back(std::move(U));
@@ -110,6 +111,7 @@ class DWARFUnit {
   const DWARFDebugAbbrev *Abbrev;
   StringRef RangeSection;
   uint32_t RangeSectionBase;
+  StringRef LineSection;
   StringRef StringSection;
   StringRef StringOffsetSection;
   StringRef AddrOffsetSection;
@@ -146,7 +148,7 @@ protected:
 public:
   DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
             const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
-            StringRef SOS, StringRef AOS, bool LE,
+            StringRef SOS, StringRef AOS, StringRef LS, bool LE,
             const DWARFUnitSectionBase &UnitSection,
             const DWARFUnitIndex::Entry *IndexEntry = nullptr);
 
@@ -154,6 +156,7 @@ public:
 
   DWARFContext& getContext() const { return Context; }
 
+  StringRef getLineSection() const { return LineSection; }
   StringRef getStringSection() const { return StringSection; }
   StringRef getStringOffsetSection() const { return StringOffsetSection; }
   void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
@@ -251,12 +254,19 @@ public:
     assert(!DieArray.empty());
     auto it = std::lower_bound(
         DieArray.begin(), DieArray.end(), Offset,
-        [=](const DWARFDebugInfoEntryMinimal &LHS, uint32_t Offset) {
+        [](const DWARFDebugInfoEntryMinimal &LHS, uint32_t Offset) {
           return LHS.getOffset() < Offset;
         });
     return it == DieArray.end() ? nullptr : &*it;
   }
 
+  uint32_t getLineTableOffset() const {
+    if (IndexEntry)
+      if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE))
+        return Contrib->Offset;
+    return 0;
+  }
+
 private:
   /// Size in bytes of the .debug_info data associated with this compile unit.
   size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
index 8313cacb4f6cbd05b9650b108da73597f4b5df73..18c4e8e4cafdbf44635f5dae65db454251fcc436 100644 (file)
@@ -382,20 +382,23 @@ const DWARFLineTable *
 DWARFContext::getLineTableForUnit(DWARFUnit *U) {
   if (!Line)
     Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
+
   const auto *UnitDIE = U->getUnitDIE();
   if (UnitDIE == nullptr)
     return nullptr;
+
   unsigned stmtOffset =
       UnitDIE->getAttributeValueAsSectionOffset(U, DW_AT_stmt_list, -1U);
   if (stmtOffset == -1U)
     return nullptr; // No line table for this compile unit.
 
+  stmtOffset += U->getLineTableOffset();
   // See if the line table is cached.
   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
     return lt;
 
   // We have to parse it first.
-  DataExtractor lineData(getLineSection().Data, isLittleEndian(),
+  DataExtractor lineData(U->getLineSection(), isLittleEndian(),
                          U->getAddressByteSize());
   return Line->getOrParseLineTable(lineData, stmtOffset);
 }
index 169acee62d79408ac2bf0cc0094c75d38197a0df..51c6c090eb31ebee9e620fbc8e955ec30dc42ebb 100644 (file)
@@ -20,7 +20,7 @@ using namespace dwarf;
 void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
   parseImpl(C, Section, C.getDebugAbbrev(), C.getRangeSection(),
             C.getStringSection(), StringRef(), C.getAddrSection(),
-            C.isLittleEndian());
+            C.getLineSection().Data, C.isLittleEndian());
 }
 
 void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
@@ -28,17 +28,18 @@ void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
                                     DWARFUnitIndex *Index) {
   parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), C.getRangeDWOSection(),
             C.getStringDWOSection(), C.getStringOffsetDWOSection(),
-            C.getAddrSection(), C.isLittleEndian());
+            C.getAddrSection(), C.getLineDWOSection().Data, C.isLittleEndian());
 }
 
 DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
                      const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS,
-                     StringRef SOS, StringRef AOS, bool LE,
+                     StringRef SOS, StringRef AOS, StringRef LS, bool LE,
                      const DWARFUnitSectionBase &UnitSection,
                      const DWARFUnitIndex::Entry *IndexEntry)
     : Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
-      StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
-      isLittleEndian(LE), UnitSection(UnitSection), IndexEntry(IndexEntry) {
+      LineSection(LS), StringSection(SS), StringOffsetSection(SOS),
+      AddrOffsetSection(AOS), isLittleEndian(LE), UnitSection(UnitSection),
+      IndexEntry(IndexEntry) {
   clear();
 }
 
index 0dbe1edf24616534c6e7a4814d9c31233f4547ab..e766cbc2bd91180e5f46ee12eb022d92898ab66b 100644 (file)
@@ -9,7 +9,7 @@ RUN: llvm-dwarfdump %p/Inputs/dwarfdump-dwp.x86_64.o | FileCheck %s
 ;   bar b() {
 ;   }
 
-; CHECK: .debug_info.dwo contents:
+; CHECK-LABEL: .debug_info.dwo contents:
 ; CHECK: Compile Unit
 
 ; Verify that the second CU uses the index for its abbrev offset
@@ -21,8 +21,20 @@ RUN: llvm-dwarfdump %p/Inputs/dwarfdump-dwp.x86_64.o | FileCheck %s
 ; CHECK:   DW_AT_name {{.*}} "a.cpp"
 
 ; Verify that abbreviations are decoded using the abbrev offset in the index
-; CHECK:   DW_TAG_subprogram
 ; CHECK:   DW_TAG_structure_type
+; CHECK:   DW_TAG_subprogram
+
+; CHECK-LABEL: .debug_types.dwo contents:
+; CHECK: Type Unit
+; CHECK:   DW_TAG_type_unit
+; CHECK:     DW_AT_stmt_list {{.*}}(0x00000000)
+; CHECK:     DW_TAG_structure_type
+; CHECK:       DW_AT_decl_file {{.*}} ("a.cpp")
+; CHECK: Type Unit
+; CHECK:   DW_TAG_type_unit
+; CHECK:     DW_AT_stmt_list {{.*}}(0x00000000)
+; CHECK:     DW_TAG_structure_type
+; CHECK:       DW_AT_decl_file {{.*}} ("b.cpp")
 
 ; CHECK: .debug_cu_index contents:
 ; CHECK-NEXT: version = 2 slots = 16