LLVM  8.0.1
DWARFGdbIndex.cpp
Go to the documentation of this file.
1 //===- DWARFGdbIndex.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/ADT/SmallVector.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/Format.h"
16 #include <algorithm>
17 #include <cassert>
18 #include <cinttypes>
19 #include <cstdint>
20 #include <utility>
21 
22 using namespace llvm;
23 
24 // .gdb_index section format reference:
25 // https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
26 
27 void DWARFGdbIndex::dumpCUList(raw_ostream &OS) const {
28  OS << format("\n CU list offset = 0x%x, has %" PRId64 " entries:",
29  CuListOffset, (uint64_t)CuList.size())
30  << '\n';
31  uint32_t I = 0;
32  for (const CompUnitEntry &CU : CuList)
33  OS << format(" %d: Offset = 0x%llx, Length = 0x%llx\n", I++, CU.Offset,
34  CU.Length);
35 }
36 
37 void DWARFGdbIndex::dumpTUList(raw_ostream &OS) const {
38  OS << formatv("\n Types CU list offset = {0:x}, has {1} entries:\n",
39  TuListOffset, TuList.size());
40  uint32_t I = 0;
41  for (const TypeUnitEntry &TU : TuList)
42  OS << formatv(" {0}: offset = {1:x8}, type_offset = {2:x8}, "
43  "type_signature = {3:x16}\n",
44  I++, TU.Offset, TU.TypeOffset, TU.TypeSignature);
45 }
46 
47 void DWARFGdbIndex::dumpAddressArea(raw_ostream &OS) const {
48  OS << format("\n Address area offset = 0x%x, has %" PRId64 " entries:",
49  AddressAreaOffset, (uint64_t)AddressArea.size())
50  << '\n';
51  for (const AddressEntry &Addr : AddressArea)
52  OS << format(
53  " Low/High address = [0x%llx, 0x%llx) (Size: 0x%llx), CU id = %d\n",
54  Addr.LowAddress, Addr.HighAddress, Addr.HighAddress - Addr.LowAddress,
55  Addr.CuIndex);
56 }
57 
58 void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const {
59  OS << format("\n Symbol table offset = 0x%x, size = %" PRId64
60  ", filled slots:",
61  SymbolTableOffset, (uint64_t)SymbolTable.size())
62  << '\n';
63  uint32_t I = -1;
64  for (const SymTableEntry &E : SymbolTable) {
65  ++I;
66  if (!E.NameOffset && !E.VecOffset)
67  continue;
68 
69  OS << format(" %d: Name offset = 0x%x, CU vector offset = 0x%x\n", I,
70  E.NameOffset, E.VecOffset);
71 
72  StringRef Name = ConstantPoolStrings.substr(
73  ConstantPoolOffset - StringPoolOffset + E.NameOffset);
74 
75  auto CuVector = std::find_if(
76  ConstantPoolVectors.begin(), ConstantPoolVectors.end(),
77  [&](const std::pair<uint32_t, SmallVector<uint32_t, 0>> &V) {
78  return V.first == E.VecOffset;
79  });
80  assert(CuVector != ConstantPoolVectors.end() && "Invalid symbol table");
81  uint32_t CuVectorId = CuVector - ConstantPoolVectors.begin();
82  OS << format(" String name: %s, CU vector index: %d\n", Name.data(),
83  CuVectorId);
84  }
85 }
86 
87 void DWARFGdbIndex::dumpConstantPool(raw_ostream &OS) const {
88  OS << format("\n Constant pool offset = 0x%x, has %" PRId64 " CU vectors:",
89  ConstantPoolOffset, (uint64_t)ConstantPoolVectors.size());
90  uint32_t I = 0;
91  for (const auto &V : ConstantPoolVectors) {
92  OS << format("\n %d(0x%x): ", I++, V.first);
93  for (uint32_t Val : V.second)
94  OS << format("0x%x ", Val);
95  }
96  OS << '\n';
97 }
98 
100  if (HasError) {
101  OS << "\n<error parsing>\n";
102  return;
103  }
104 
105  if (HasContent) {
106  OS << " Version = " << Version << '\n';
107  dumpCUList(OS);
108  dumpTUList(OS);
109  dumpAddressArea(OS);
110  dumpSymbolTable(OS);
111  dumpConstantPool(OS);
112  }
113 }
114 
115 bool DWARFGdbIndex::parseImpl(DataExtractor Data) {
116  uint32_t Offset = 0;
117 
118  // Only version 7 is supported at this moment.
119  Version = Data.getU32(&Offset);
120  if (Version != 7)
121  return false;
122 
123  CuListOffset = Data.getU32(&Offset);
124  uint32_t CuTypesOffset = Data.getU32(&Offset);
125  AddressAreaOffset = Data.getU32(&Offset);
126  SymbolTableOffset = Data.getU32(&Offset);
127  ConstantPoolOffset = Data.getU32(&Offset);
128 
129  if (Offset != CuListOffset)
130  return false;
131 
132  uint32_t CuListSize = (CuTypesOffset - CuListOffset) / 16;
133  CuList.reserve(CuListSize);
134  for (uint32_t i = 0; i < CuListSize; ++i) {
135  uint64_t CuOffset = Data.getU64(&Offset);
136  uint64_t CuLength = Data.getU64(&Offset);
137  CuList.push_back({CuOffset, CuLength});
138  }
139 
140  // CU Types are no longer needed as DWARF skeleton type units never made it
141  // into the standard.
142  uint32_t TuListSize = (AddressAreaOffset - CuTypesOffset) / 24;
143  TuList.resize(TuListSize);
144  for (uint32_t I = 0; I < TuListSize; ++I) {
145  uint64_t CuOffset = Data.getU64(&Offset);
146  uint64_t TypeOffset = Data.getU64(&Offset);
147  uint64_t Signature = Data.getU64(&Offset);
148  TuList[I] = {CuOffset, TypeOffset, Signature};
149  }
150 
151  uint32_t AddressAreaSize = (SymbolTableOffset - AddressAreaOffset) / 20;
152  AddressArea.reserve(AddressAreaSize);
153  for (uint32_t i = 0; i < AddressAreaSize; ++i) {
154  uint64_t LowAddress = Data.getU64(&Offset);
155  uint64_t HighAddress = Data.getU64(&Offset);
156  uint32_t CuIndex = Data.getU32(&Offset);
157  AddressArea.push_back({LowAddress, HighAddress, CuIndex});
158  }
159 
160  // The symbol table. This is an open addressed hash table. The size of the
161  // hash table is always a power of 2.
162  // Each slot in the hash table consists of a pair of offset_type values. The
163  // first value is the offset of the symbol's name in the constant pool. The
164  // second value is the offset of the CU vector in the constant pool.
165  // If both values are 0, then this slot in the hash table is empty. This is ok
166  // because while 0 is a valid constant pool index, it cannot be a valid index
167  // for both a string and a CU vector.
168  uint32_t SymTableSize = (ConstantPoolOffset - SymbolTableOffset) / 8;
169  SymbolTable.reserve(SymTableSize);
170  uint32_t CuVectorsTotal = 0;
171  for (uint32_t i = 0; i < SymTableSize; ++i) {
172  uint32_t NameOffset = Data.getU32(&Offset);
173  uint32_t CuVecOffset = Data.getU32(&Offset);
174  SymbolTable.push_back({NameOffset, CuVecOffset});
175  if (NameOffset || CuVecOffset)
176  ++CuVectorsTotal;
177  }
178 
179  // The constant pool. CU vectors are stored first, followed by strings.
180  // The first value is the number of CU indices in the vector. Each subsequent
181  // value is the index and symbol attributes of a CU in the CU list.
182  for (uint32_t i = 0; i < CuVectorsTotal; ++i) {
183  ConstantPoolVectors.emplace_back(0, SmallVector<uint32_t, 0>());
184  auto &Vec = ConstantPoolVectors.back();
185  Vec.first = Offset - ConstantPoolOffset;
186 
187  uint32_t Num = Data.getU32(&Offset);
188  for (uint32_t j = 0; j < Num; ++j)
189  Vec.second.push_back(Data.getU32(&Offset));
190  }
191 
192  ConstantPoolStrings = Data.getData().drop_front(Offset);
193  StringPoolOffset = Offset;
194  return true;
195 }
196 
198  HasContent = !Data.getData().empty();
199  HasError = HasContent && !parseImpl(Data);
200 }
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void push_back(const T &Elt)
Definition: SmallVector.h:218
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
StringRef getData() const
Get the data pointed to by this extractor.
Definition: DataExtractor.h:55
void reserve(size_type N)
Definition: SmallVector.h:376
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:128
amdgpu Simplify well known AMD library false Value Value const Twine & Name
uint32_t getU32(uint32_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:598
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void dump(raw_ostream &OS)
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1214
uint64_t getU64(uint32_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
size_t size() const
Definition: SmallVector.h:53
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the first N elements dropped.
Definition: StringRef.h:645
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
void parse(DataExtractor Data)
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
void resize(size_type N)
Definition: SmallVector.h:351