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