1 //===-- DWARFUnitIndex.cpp ------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/ErrorHandling.h"
17 bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
18 uint32_t *OffsetPtr) {
19 if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16))
21 Version = IndexData.getU32(OffsetPtr);
22 NumColumns = IndexData.getU32(OffsetPtr);
23 NumUnits = IndexData.getU32(OffsetPtr);
24 NumBuckets = IndexData.getU32(OffsetPtr);
28 void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
29 OS << format("version = %u slots = %u\n\n", Version, NumBuckets);
32 bool DWARFUnitIndex::parse(DataExtractor IndexData) {
33 bool b = parseImpl(IndexData);
35 *this = DWARFUnitIndex(InfoColumnKind);
39 bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
41 if (!Header.parse(IndexData, &Offset))
44 if (!IndexData.isValidOffsetForDataOfSize(
45 Offset, Header.NumBuckets * (8 + 4) +
46 (2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
49 Rows = llvm::make_unique<Entry[]>(Header.NumBuckets);
51 llvm::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
52 ColumnKinds = llvm::make_unique<DWARFSectionKind[]>(Header.NumColumns);
54 // Read Hash Table of Signatures
55 for (unsigned i = 0; i != Header.NumBuckets; ++i)
56 Rows[i].Signature = IndexData.getU64(&Offset);
58 // Read Parallel Table of Indexes
59 for (unsigned i = 0; i != Header.NumBuckets; ++i) {
60 auto Index = IndexData.getU32(&Offset);
64 Rows[i].Contributions =
65 llvm::make_unique<Entry::SectionContribution[]>(Header.NumColumns);
66 Contribs[Index - 1] = Rows[i].Contributions.get();
69 // Read the Column Headers
70 for (unsigned i = 0; i != Header.NumColumns; ++i) {
71 ColumnKinds[i] = static_cast<DWARFSectionKind>(IndexData.getU32(&Offset));
72 if (ColumnKinds[i] == InfoColumnKind) {
82 // Read Table of Section Offsets
83 for (unsigned i = 0; i != Header.NumUnits; ++i) {
84 auto *Contrib = Contribs[i];
85 for (unsigned i = 0; i != Header.NumColumns; ++i)
86 Contrib[i].Offset = IndexData.getU32(&Offset);
89 // Read Table of Section Sizes
90 for (unsigned i = 0; i != Header.NumUnits; ++i) {
91 auto *Contrib = Contribs[i];
92 for (unsigned i = 0; i != Header.NumColumns; ++i)
93 Contrib[i].Length = IndexData.getU32(&Offset);
99 StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) {
113 llvm_unreachable("unknown DWARFSectionKind");
116 void DWARFUnitIndex::dump(raw_ostream &OS) const {
117 if (!Header.NumBuckets)
121 OS << "Index Signature ";
122 for (unsigned i = 0; i != Header.NumColumns; ++i)
123 OS << ' ' << left_justify(getColumnHeader(ColumnKinds[i]), 24);
124 OS << "\n----- ------------------";
125 for (unsigned i = 0; i != Header.NumColumns; ++i)
126 OS << " ------------------------";
128 for (unsigned i = 0; i != Header.NumBuckets; ++i) {
130 if (auto *Contribs = Row.Contributions.get()) {
131 OS << format("%5u 0x%016" PRIx64 " ", i, Row.Signature);
132 for (unsigned i = 0; i != Header.NumColumns; ++i) {
133 auto &Contrib = Contribs[i];
134 OS << format("[0x%08x, 0x%08x) ", Contrib.Offset,
135 Contrib.Offset + Contrib.Length);
142 const DWARFUnitIndex::Entry::SectionContribution *
143 DWARFUnitIndex::Entry::getOffset(DWARFSectionKind Sec) const {
145 for (; i != Index->Header.NumColumns; ++i)
146 if (Index->ColumnKinds[i] == Sec)
147 return &Contributions[i];
150 const DWARFUnitIndex::Entry::SectionContribution *
151 DWARFUnitIndex::Entry::getOffset() const {
152 return &Contributions[Index->InfoColumn];
155 const DWARFUnitIndex::Entry *
156 DWARFUnitIndex::getFromOffset(uint32_t Offset) const {
157 for (uint32_t i = 0; i != Header.NumBuckets; ++i)
158 if (const auto &Contribs = Rows[i].Contributions)
159 if (Contribs[InfoColumn].Offset == Offset)