blob: 4b844e999ebf0bc29743622b20c31a159ec71814 [file] [log] [blame]
Frederic Risse837ec22014-11-14 16:15:53 +00001#include "DWARFAcceleratorTable.h"
2
3#include "llvm/Support/Dwarf.h"
4#include "llvm/Support/Format.h"
5#include "llvm/Support/raw_ostream.h"
6
7namespace llvm {
8
9bool DWARFAcceleratorTable::extract() {
10 uint32_t Offset = 0;
11
12 // Check that we can at least read the header.
13 if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4))
14 return false;
15
16 Hdr.Magic = AccelSection.getU32(&Offset);
17 Hdr.Version = AccelSection.getU16(&Offset);
18 Hdr.HashFunction = AccelSection.getU16(&Offset);
19 Hdr.NumBuckets = AccelSection.getU32(&Offset);
20 Hdr.NumHashes = AccelSection.getU32(&Offset);
21 Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
22
23 // Check that we can read all the hashes and offsets from the
24 // section (see SourceLevelDebugging.rst for the structure of the index).
25 if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
26 Hdr.NumBuckets*4 + Hdr.NumHashes*8))
27 return false;
28
29 HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
30 uint32_t NumAtoms = AccelSection.getU32(&Offset);
31
32 for (unsigned i = 0; i < NumAtoms; ++i) {
33 uint16_t AtomType = AccelSection.getU16(&Offset);
34 DWARFFormValue AtomForm(AccelSection.getU16(&Offset));
35 HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
36 }
37
38 return true;
39}
40
41void DWARFAcceleratorTable::dump(raw_ostream &OS) {
42 // Dump the header.
43 OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
44 << "Version = " << format("0x%04x", Hdr.Version) << '\n'
45 << "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n'
46 << "Bucket count = " << Hdr.NumBuckets << '\n'
47 << "Hashes count = " << Hdr.NumHashes << '\n'
48 << "HeaderData length = " << Hdr.HeaderDataLength << '\n'
49 << "DIE offset base = " << HdrData.DIEOffsetBase << '\n'
50 << "Number of atoms = " << HdrData.Atoms.size() << '\n';
51
52 unsigned i = 0;
53 for (const auto &Atom: HdrData.Atoms) {
54 OS << format("Atom[%d] Type: ", i++);
55 if (const char *TypeString = dwarf::AtomTypeString(Atom.first))
56 OS << TypeString;
57 else
58 OS << format("DW_ATOM_Unknown_0x%x", Atom.first);
59 OS << " Form: ";
60 if (const char *FormString = dwarf::FormEncodingString(Atom.second.getForm()))
61 OS << FormString;
62 else
63 OS << format("DW_FORM_Unknown_0x%x", Atom.second.getForm());
64 OS << '\n';
65 }
66
67 // Now go through the actual tables and dump them.
68 uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
69 unsigned HashesBase = Offset + Hdr.NumBuckets * 4;
70 unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
71
72 for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) {
73 unsigned Index = AccelSection.getU32(&Offset);
74
75 OS << format("Bucket[%d]\n", Bucket);
76 if (Index == UINT32_MAX) {
77 OS << " EMPTY\n";
78 continue;
79 }
80
81 for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
82 unsigned HashOffset = HashesBase + HashIdx*4;
83 unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
84 uint32_t Hash = AccelSection.getU32(&HashOffset);
85
86 if (Hash % Hdr.NumBuckets != Bucket)
87 break;
88
89 unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
90 OS << format(" Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset);
91 if (!AccelSection.isValidOffset(DataOffset)) {
92 OS << " Invalid section offset\n";
93 continue;
94 }
95 while (unsigned StringOffset = AccelSection.getU32(&DataOffset)) {
96 OS << format(" Name: %08x \"%s\"\n", StringOffset,
97 StringSection.getCStr(&StringOffset));
98 unsigned NumData = AccelSection.getU32(&DataOffset);
99 for (unsigned Data = 0; Data < NumData; ++Data) {
100 OS << format(" Data[%d] => ", Data);
101 unsigned i = 0;
102 for (auto &Atom : HdrData.Atoms) {
103 OS << format("{Atom[%d]: ", i++);
104 if (Atom.second.extractValue(AccelSection, &DataOffset, nullptr))
105 Atom.second.dump(OS, nullptr);
106 else
107 OS << "Error extracting the value";
108 OS << "} ";
109 }
110 OS << '\n';
111 }
112 }
113 }
114 }
115}
116}