dwarfdump: Dump the contents of DWP indexes
authorDavid Blaikie <dblaikie@gmail.com>
Thu, 12 Nov 2015 01:41:52 +0000 (01:41 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Thu, 12 Nov 2015 01:41:52 +0000 (01:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252842 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
test/DebugInfo/Inputs/dwarfdump-dwp.x86_64.o
test/DebugInfo/dwarfdump-dwp.test

index 647838217ca3b9d132598d09c30a286f370337c1..dab7f2918c2e23a2817b52db99bacc070fd408e8 100644 (file)
 namespace llvm {
 
 class DWARFUnitIndex {
-  class Header {
+  struct Header {
     uint32_t Version;
     uint32_t NumColumns;
     uint32_t NumUnits;
     uint32_t NumBuckets;
 
-  public:
     bool parse(DataExtractor IndexData, uint32_t *OffsetPtr);
     void dump(raw_ostream &OS) const;
   };
 
-  class Header Header;
+  struct HashRow {
+    uint64_t Signature;
+    struct SectionContribution {
+      uint32_t Offset;
+      uint32_t Size;
+    };
+    std::unique_ptr<SectionContribution[]> Contributions;
+  };
+
+  enum DwarfSection {
+    DW_SECT_INFO = 1,
+    DW_SECT_TYPES,
+    DW_SECT_ABBREV,
+    DW_SECT_LINE,
+    DW_SECT_LOC,
+    DW_SECT_STR_OFFSETS,
+    DW_SECT_MACINFO,
+    DW_SECT_MACRO,
+  };
+
+  struct Header Header;
+
+  std::unique_ptr<DwarfSection[]> ColumnKinds;
+  std::unique_ptr<HashRow[]> Rows;
+
+  static StringRef getColumnHeader(DwarfSection DS);
 
 public:
   bool parse(DataExtractor IndexData);
index 172fb9279d4d22e07560054a60fabc6fd288018b..a050d82c295b9c9b7d08c094e5dfcc5247ad8bea 100644 (file)
@@ -9,6 +9,9 @@
 
 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
 
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorHandling.h"
+
 namespace llvm {
 
 bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
@@ -21,10 +24,7 @@ bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
 }
 
 void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
-  OS << "Index header:\n" << format("   version: %u\n", Version)
-     << format("   columns: %u\n", NumColumns)
-     << format("     units: %u\n", NumUnits)
-     << format("   buckets: %u\n", NumBuckets);
+  OS << format("version = %u slots = %u\n\n", Version, NumBuckets);
 }
 
 bool DWARFUnitIndex::parse(DataExtractor IndexData) {
@@ -32,8 +32,85 @@ bool DWARFUnitIndex::parse(DataExtractor IndexData) {
   if (!Header.parse(IndexData, &Offset))
     return false;
 
+  Rows = llvm::make_unique<HashRow[]>(Header.NumBuckets);
+  auto Contribs =
+      llvm::make_unique<HashRow::SectionContribution *[]>(Header.NumUnits);
+  ColumnKinds = llvm::make_unique<DwarfSection[]>(Header.NumColumns);
+
+  // Read Hash Table of Signatures
+  for (unsigned i = 0; i != Header.NumBuckets; ++i)
+    Rows[i].Signature = IndexData.getU64(&Offset);
+
+  // Read Parallel Table of Indexes
+  for (unsigned i = 0; i != Header.NumBuckets; ++i) {
+    auto Index = IndexData.getU32(&Offset);
+    if (!Index)
+      continue;
+    Rows[i].Contributions =
+        llvm::make_unique<HashRow::SectionContribution[]>(Header.NumColumns);
+    Contribs[Index - 1] = Rows[i].Contributions.get();
+  }
+
+  // Read the Column Headers
+  for (unsigned i = 0; i != Header.NumColumns; ++i)
+    ColumnKinds[i] = static_cast<DwarfSection>(IndexData.getU32(&Offset));
+
+  // Read Table of Section Offsets
+  for (unsigned i = 0; i != Header.NumUnits; ++i) {
+    auto *Contrib = Contribs[i];
+    for (unsigned i = 0; i != Header.NumColumns; ++i) {
+      Contrib[i].Offset = IndexData.getU32(&Offset);
+    }
+  }
+
+  // Read Table of Section Sizes
+  for (unsigned i = 0; i != Header.NumUnits; ++i) {
+    auto *Contrib = Contribs[i];
+    for (unsigned i = 0; i != Header.NumColumns; ++i) {
+      Contrib[i].Size = IndexData.getU32(&Offset);
+    }
+  }
+
   return true;
 }
 
-void DWARFUnitIndex::dump(raw_ostream &OS) const { Header.dump(OS); }
+StringRef DWARFUnitIndex::getColumnHeader(DwarfSection DS) {
+#define CASE(DS)                                                               \
+  case DW_SECT_##DS:                                                           \
+    return #DS;
+  switch (DS) {
+    CASE(INFO);
+    CASE(TYPES);
+    CASE(ABBREV);
+    CASE(LINE);
+    CASE(LOC);
+    CASE(STR_OFFSETS);
+    CASE(MACINFO);
+    CASE(MACRO);
+  }
+  llvm_unreachable("unknown DwarfSection");
+}
+
+void DWARFUnitIndex::dump(raw_ostream &OS) const {
+  Header.dump(OS);
+  OS << "Index Signature         ";
+  for (unsigned i = 0; i != Header.NumColumns; ++i)
+    OS << format(" %-24s", getColumnHeader(ColumnKinds[i]));
+  OS << "\n----- ------------------";
+  for (unsigned i = 0; i != Header.NumColumns; ++i)
+    OS << " ------------------------";
+  OS << '\n';
+  for (unsigned i = 0; i != Header.NumBuckets; ++i) {
+    auto &Row = Rows[i];
+    if (auto *Contribs = Row.Contributions.get()) {
+      OS << format("%5u 0x%016" PRIx64 " ", i, Row.Signature);
+      for (unsigned i = 0; i != Header.NumColumns; ++i) {
+        auto &Contrib = Contribs[i];
+        OS << format("[0x%08u, 0x%08u) ", Contrib.Offset,
+                     Contrib.Offset + Contrib.Size);
+      }
+      OS << '\n';
+    }
+  }
+}
 }
index 3588369af4785a6d244f5e20ca6328be2a548432..2b7ed526ca927a9ba25170880f1be857c2c9f456 100644 (file)
Binary files a/test/DebugInfo/Inputs/dwarfdump-dwp.x86_64.o and b/test/DebugInfo/Inputs/dwarfdump-dwp.x86_64.o differ
index c3b8e1c4f9fa4d7bbfb8cb62312318953dff5234..953a58cb4af1f03a6e3fbb0f00de40ae5ae3365c 100644 (file)
@@ -5,22 +5,21 @@ RUN: llvm-dwarfdump %p/Inputs/dwarfdump-dwp.x86_64.o | FileCheck %s
 ;   struct foo { };
 ;   foo a;
 ; b.cpp:
-;   struct foo { };
-;   foo b;
+;   struct bar { };
+;   bar b;
 
 ; CHECK: .debug_cu_index contents:
-; CHECK-NEXT: Index header:
-; CHECK-NEXT: version: 2
-; CHECK-NEXT: columns: 4
-; CHECK-NEXT:   units: 2
-; CHECK-NEXT: buckets: 16
+; CHECK-NEXT: version = 2 slots = 16
+; CHECK:      Index Signature          INFO                     ABBREV                   LINE                     STR_OFFSETS            
+; CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------
+; CHECK-NEXT:     8 0x03c30756e2d45008 [0x00000000, 0x00000045) [0x00000000, 0x00000067) [0x00000000, 0x00000026) [0x00000000, 0x00000016)
+; CHECK-NEXT:    12 0x9aeb3a61ed48510c [0x00000045, 0x00000090) [0x00000067, 0x00000134) [0x00000026, 0x00000052) [0x00000016, 0x00000032)
 
 ; CHECK: .debug_tu_index contents:
-; CHECK-NEXT: Index header:
-; CHECK-NEXT: version: 2
-; CHECK-NEXT: columns: 4
-; CHECK-NEXT:   units: 1
-; CHECK-NEXT: buckets: 16
+; CHECK-NEXT: version = 2 slots = 16
+; CHECK:      Index Signature          TYPES                    ABBREV                   LINE                     STR_OFFSETS
+; CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------
+; CHECK-NEXT:     8 0x1d02f3be30cc5688 [0x00000036, 0x00000072) [0x00000067, 0x00000134) [0x00000026, 0x00000052) [0x00000016, 0x00000032)
+; CHECK-NEXT:    12 0x3875c0e21cda63fc [0x00000000, 0x00000036) [0x00000000, 0x00000067) [0x00000000, 0x00000026) [0x00000000, 0x00000016)
 
-; TODO: dump the index contents
 ; TODO: use the index section offset info to correctly dump debug_info