LLVM  3.7.0
DWARFAcceleratorTable.cpp
Go to the documentation of this file.
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 
11 #include "llvm/Support/Dwarf.h"
12 #include "llvm/Support/Format.h"
14 
15 namespace llvm {
16 
18  uint32_t Offset = 0;
19 
20  // Check that we can at least read the header.
21  if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4))
22  return false;
23 
24  Hdr.Magic = AccelSection.getU32(&Offset);
25  Hdr.Version = AccelSection.getU16(&Offset);
26  Hdr.HashFunction = AccelSection.getU16(&Offset);
27  Hdr.NumBuckets = AccelSection.getU32(&Offset);
28  Hdr.NumHashes = AccelSection.getU32(&Offset);
29  Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
30 
31  // Check that we can read all the hashes and offsets from the
32  // section (see SourceLevelDebugging.rst for the structure of the index).
33  if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
34  Hdr.NumBuckets*4 + Hdr.NumHashes*8))
35  return false;
36 
37  HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
38  uint32_t NumAtoms = AccelSection.getU32(&Offset);
39 
40  for (unsigned i = 0; i < NumAtoms; ++i) {
41  uint16_t AtomType = AccelSection.getU16(&Offset);
42  uint16_t AtomForm = AccelSection.getU16(&Offset);
43  HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
44  }
45 
46  return true;
47 }
48 
50  // Dump the header.
51  OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
52  << "Version = " << format("0x%04x", Hdr.Version) << '\n'
53  << "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n'
54  << "Bucket count = " << Hdr.NumBuckets << '\n'
55  << "Hashes count = " << Hdr.NumHashes << '\n'
56  << "HeaderData length = " << Hdr.HeaderDataLength << '\n'
57  << "DIE offset base = " << HdrData.DIEOffsetBase << '\n'
58  << "Number of atoms = " << HdrData.Atoms.size() << '\n';
59 
60  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))
70  OS << FormString;
71  else
72  OS << format("DW_FORM_Unknown_0x%x", Atom.second);
73  OS << '\n';
74  AtomForms.push_back(DWARFFormValue(Atom.second));
75  }
76 
77  // Now go through the actual tables and dump them.
78  uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
79  unsigned HashesBase = Offset + Hdr.NumBuckets * 4;
80  unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
81 
82  for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) {
83  unsigned Index = AccelSection.getU32(&Offset);
84 
85  OS << format("Bucket[%d]\n", Bucket);
86  if (Index == UINT32_MAX) {
87  OS << " EMPTY\n";
88  continue;
89  }
90 
91  for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
92  unsigned HashOffset = HashesBase + HashIdx*4;
93  unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
94  uint32_t Hash = AccelSection.getU32(&HashOffset);
95 
96  if (Hash % Hdr.NumBuckets != Bucket)
97  break;
98 
99  unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
100  OS << format(" Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset);
101  if (!AccelSection.isValidOffset(DataOffset)) {
102  OS << " Invalid section offset\n";
103  continue;
104  }
105  while (AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
106  unsigned StringOffset = AccelSection.getU32(&DataOffset);
107  RelocAddrMap::const_iterator Reloc = Relocs.find(DataOffset-4);
108  if (Reloc != Relocs.end())
109  StringOffset += Reloc->second.second;
110  if (!StringOffset)
111  break;
112  OS << format(" Name: %08x \"%s\"\n", StringOffset,
113  StringSection.getCStr(&StringOffset));
114  unsigned NumData = AccelSection.getU32(&DataOffset);
115  for (unsigned Data = 0; Data < NumData; ++Data) {
116  OS << format(" Data[%d] => ", Data);
117  unsigned i = 0;
118  for (auto &Atom : AtomForms) {
119  OS << format("{Atom[%d]: ", i++);
120  if (Atom.extractValue(AccelSection, &DataOffset, nullptr))
121  Atom.dump(OS, nullptr);
122  else
123  OS << "Error extracting the value";
124  OS << "} ";
125  }
126  OS << '\n';
127  }
128  }
129  }
130  }
131 }
132 }
bool isValidOffset(uint32_t offset) const
Test the validity of offset.
uint32_t getU32(uint32_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const
Test the availability of length bytes of data from offset.
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:111
const char * AtomTypeString(unsigned Atom)
Definition: Dwarf.cpp:516
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
const char * getCStr(uint32_t *offset_ptr) const
Extract a C string from *offset_ptr.
for(unsigned i=0, e=MI->getNumOperands();i!=e;++i)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
uint16_t getU16(uint32_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
void dump(raw_ostream &OS) const
iterator end()
Definition: DenseMap.h:68
iterator find(const KeyT &Val)
Definition: DenseMap.h:124
const char * FormEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:208
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
std::string Hash(const Unit &U)
Definition: FuzzerUtil.cpp:39