dwarfdump: Add support for dumping the table contents of DWP indexes
[oota-llvm.git] / lib / DebugInfo / DWARF / DWARFUnitIndex.cpp
1 //===-- DWARFUnitIndex.cpp ------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
11
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/ErrorHandling.h"
14
15 namespace llvm {
16
17 bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
18                                    uint32_t *OffsetPtr) {
19   if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16))
20     return false;
21   Version = IndexData.getU32(OffsetPtr);
22   NumColumns = IndexData.getU32(OffsetPtr);
23   NumUnits = IndexData.getU32(OffsetPtr);
24   NumBuckets = IndexData.getU32(OffsetPtr);
25   return Version <= 2;
26 }
27
28 void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
29   OS << format("version = %u slots = %u\n\n", Version, NumBuckets);
30 }
31
32 bool DWARFUnitIndex::parse(DataExtractor IndexData) {
33   uint32_t Offset = 0;
34   if (!Header.parse(IndexData, &Offset))
35     return false;
36
37   if (!IndexData.isValidOffsetForDataOfSize(
38           Offset, Header.NumBuckets * (8 + 4) +
39                       (2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
40     return false;
41
42   Rows = llvm::make_unique<HashRow[]>(Header.NumBuckets);
43   auto Contribs =
44       llvm::make_unique<HashRow::SectionContribution *[]>(Header.NumUnits);
45   ColumnKinds = llvm::make_unique<DwarfSection[]>(Header.NumColumns);
46
47   // Read Hash Table of Signatures
48   for (unsigned i = 0; i != Header.NumBuckets; ++i)
49     Rows[i].Signature = IndexData.getU64(&Offset);
50
51   // Read Parallel Table of Indexes
52   for (unsigned i = 0; i != Header.NumBuckets; ++i) {
53     auto Index = IndexData.getU32(&Offset);
54     if (!Index)
55       continue;
56     Rows[i].Contributions =
57         llvm::make_unique<HashRow::SectionContribution[]>(Header.NumColumns);
58     Contribs[Index - 1] = Rows[i].Contributions.get();
59   }
60
61   // Read the Column Headers
62   for (unsigned i = 0; i != Header.NumColumns; ++i)
63     ColumnKinds[i] = static_cast<DwarfSection>(IndexData.getU32(&Offset));
64
65   // Read Table of Section Offsets
66   for (unsigned i = 0; i != Header.NumUnits; ++i) {
67     auto *Contrib = Contribs[i];
68     for (unsigned i = 0; i != Header.NumColumns; ++i) {
69       Contrib[i].Offset = IndexData.getU32(&Offset);
70     }
71   }
72
73   // Read Table of Section Sizes
74   for (unsigned i = 0; i != Header.NumUnits; ++i) {
75     auto *Contrib = Contribs[i];
76     for (unsigned i = 0; i != Header.NumColumns; ++i) {
77       Contrib[i].Size = IndexData.getU32(&Offset);
78     }
79   }
80
81   return true;
82 }
83
84 StringRef DWARFUnitIndex::getColumnHeader(DwarfSection DS) {
85 #define CASE(DS)                                                               \
86   case DW_SECT_##DS:                                                           \
87     return #DS;
88   switch (DS) {
89     CASE(INFO);
90     CASE(TYPES);
91     CASE(ABBREV);
92     CASE(LINE);
93     CASE(LOC);
94     CASE(STR_OFFSETS);
95     CASE(MACINFO);
96     CASE(MACRO);
97   }
98   llvm_unreachable("unknown DwarfSection");
99 }
100
101 void DWARFUnitIndex::dump(raw_ostream &OS) const {
102   Header.dump(OS);
103   OS << "Index Signature         ";
104   for (unsigned i = 0; i != Header.NumColumns; ++i)
105     OS << ' ' << left_justify(getColumnHeader(ColumnKinds[i]), 24);
106   OS << "\n----- ------------------";
107   for (unsigned i = 0; i != Header.NumColumns; ++i)
108     OS << " ------------------------";
109   OS << '\n';
110   for (unsigned i = 0; i != Header.NumBuckets; ++i) {
111     auto &Row = Rows[i];
112     if (auto *Contribs = Row.Contributions.get()) {
113       OS << format("%5u 0x%016" PRIx64 " ", i, Row.Signature);
114       for (unsigned i = 0; i != Header.NumColumns; ++i) {
115         auto &Contrib = Contribs[i];
116         OS << format("[0x%08u, 0x%08u) ", Contrib.Offset,
117                      Contrib.Offset + Contrib.Size);
118       }
119       OS << '\n';
120     }
121   }
122 }
123 }