LLVM: lib/CodeGen/AsmPrinter/DIEHash.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
23
24using namespace llvm;
25
26#define DEBUG_TYPE "dwarfdebug"
27
28
29
31
32
33 for (const auto &V : Die.values())
34 if (V.getAttribute() == Attr)
35 return V.getDIEString().getString();
36
38}
39
40
41
42void DIEHash::addString(StringRef Str) {
43 LLVM_DEBUG(dbgs() << "Adding string " << Str << " to hash.\n");
44 Hash.update(Str);
45 Hash.update(ArrayRef((uint8_t)'\0'));
46}
47
48
49
50
51
54 do {
58 Byte |= 0x80;
59 Hash.update(Byte);
60 } while (Value != 0);
61}
62
65 bool More;
66 do {
69 More = !((((Value == 0) && ((Byte & 0x40) == 0)) ||
70 ((Value == -1) && ((Byte & 0x40) != 0))));
71 if (More)
72 Byte |= 0x80;
73 Hash.update(Byte);
74 } while (More);
75}
76
77
78void DIEHash::addParentContext(const DIE &Parent) {
79
80 LLVM_DEBUG(dbgs() << "Adding parent context to hash...\n");
81
82
83
85 const DIE *Cur = &Parent;
87 Parents.push_back(Cur);
89 }
90 assert(Cur->getTag() == dwarf::DW_TAG_compile_unit ||
91 Cur->getTag() == dwarf::DW_TAG_type_unit);
92
93
94
96
98
99
101
102
104 LLVM_DEBUG(dbgs() << "... adding context: " << Name << "\n");
105 if (!Name.empty())
106 addString(Name);
107 }
108}
109
110
111void DIEHash::collectAttributes(const DIE &Die, DIEAttrs &Attrs) {
112
113 for (const auto &V : Die.values()) {
116 << " added.\n");
117 switch (V.getAttribute()) {
118#define HANDLE_DIE_HASH_ATTR(NAME) \
119 case dwarf::NAME: \
120 Attrs.NAME = V; \
121 break;
122#include "DIEHashAttributes.def"
123 default:
124 break;
125 }
126 }
127}
128
131
133
134
136
137
138 if (const DIE *Parent = Entry.getParent())
139 addParentContext(*Parent);
140
141
143
144
145 addString(Name);
146
147
148
149
150
151
152
153}
154
156 unsigned DieNumber) {
157
158
160
162
163
164
166}
167
169 const DIE &Entry) {
170 assert(Tag != dwarf::DW_TAG_friend && "No current LLVM clients emit friend "
171 "tags. Add support here when there's "
172 "a use case");
173
174
175 if ((Tag == dwarf::DW_TAG_pointer_type ||
176 Tag == dwarf::DW_TAG_reference_type ||
177 Tag == dwarf::DW_TAG_rvalue_reference_type ||
178 Tag == dwarf::DW_TAG_ptr_to_member_type) &&
179
180
181
182
183 Attribute == dwarf::DW_AT_type) {
184
186 if (.empty()) {
187 hashShallowTypeReference(Attribute, Entry, Name);
188 return;
189 }
190 }
191
192 unsigned &DieNumber = Numbering[&Entry];
193 if (DieNumber) {
194 hashRepeatedTypeReference(Attribute, DieNumber);
195 return;
196 }
197
198
200
202
203
204
205 DieNumber = Numbering.size();
206 computeHash(Entry);
207}
208
210 unsigned &DieNumber = Numbering[&Entry];
211 if (DieNumber) {
214 return;
215 }
216 DieNumber = Numbering.size();
218 computeHash(Entry);
219}
220
221
222
224 for (const auto &V : Values)
225 if (V.getType() == DIEValue::isBaseTypeRef) {
227 *CU->ExprRefedBaseTypes[V.getDIEBaseTypeRef().getIndex()].Die;
229 assert(!Name.empty() &&
230 "Base types referenced from DW_OP_convert should have a name");
231 hashNestedType(C, Name);
232 } else
233 Hash.update(V.getDIEInteger().getValue());
234}
235
236
237void DIEHash::hashLocList(const DIELocList &LocList) {
238 HashingByteStreamer Streamer(*this);
239 DwarfDebug &DD = *AP->getDwarfDebug();
240 const DebugLocStream &Locs = DD.getDebugLocs();
242 for (const DebugLocStream::Entry &Entry : Locs.getEntries(List))
244}
245
246
247
250
251
252
253
254
255
256
257
258 switch (Value.getType()) {
261
262
263
264
265 case DIEValue::isEntry:
267 break;
268 case DIEValue::isInteger: {
271 switch (Value.getForm()) {
272 case dwarf::DW_FORM_data1:
273 case dwarf::DW_FORM_data2:
274 case dwarf::DW_FORM_data4:
275 case dwarf::DW_FORM_data8:
276 case dwarf::DW_FORM_udata:
277 case dwarf::DW_FORM_sdata:
280 break;
281
282
283 case dwarf::DW_FORM_flag_present:
284 case dwarf::DW_FORM_flag:
287 break;
288 default:
290 }
291 break;
292 }
293 case DIEValue::isString:
297 addString(Value.getDIEString().getString());
298 break;
299 case DIEValue::isInlineString:
303 addString(Value.getDIEInlineString().getString());
304 break;
305 case DIEValue::isBlock:
306 case DIEValue::isLoc:
307 case DIEValue::isLocList:
311 if (Value.getType() == DIEValue::isBlock) {
312 addULEB128(Value.getDIEBlock().computeSize(AP->getDwarfFormParams()));
313 hashBlockData(Value.getDIEBlock().values());
314 } else if (Value.getType() == DIEValue::isLoc) {
315 addULEB128(Value.getDIELoc().computeSize(AP->getDwarfFormParams()));
316 hashBlockData(Value.getDIELoc().values());
317 } else {
318
319
320
321 hashLocList(Value.getDIELocList());
322 }
323 break;
324
325 case DIEValue::isExpr:
326 case DIEValue::isLabel:
327 case DIEValue::isBaseTypeRef:
328 case DIEValue::isDelta:
329 case DIEValue::isAddrOffset:
331 }
332}
333
334
335
336void DIEHash::hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag) {
337#define HANDLE_DIE_HASH_ATTR(NAME) \
338 { \
339 if (Attrs.NAME) \
340 hashAttribute(Attrs.NAME, Tag); \
341 }
342#include "DIEHashAttributes.def"
343
344}
345
346
347void DIEHash::addAttributes(const DIE &Die) {
348 DIEAttrs Attrs = {};
349 collectAttributes(Die, Attrs);
350 hashAttributes(Attrs, Die.getTag());
351}
352
353void DIEHash::hashNestedType(const DIE &Die, StringRef Name) {
354
355
357
358
360
361
362 addString(Name);
363}
364
365
366
367
368void DIEHash::computeHash(const DIE &Die) {
369
372
373
374 addAttributes(Die);
375
376
377 for (const auto &C : Die.children()) {
378
379
380 if (isType(C.getTag()) || (C.getTag() == dwarf::DW_TAG_subprogram && isType(C.getParent()->getTag()))) {
382
383 if (.empty()) {
384 hashNestedType(C, Name);
385 continue;
386 }
387 }
388 computeHash(C);
389 }
390
391
392 Hash.update(ArrayRef((uint8_t)'\0'));
393}
394
395
396
397
398
400 Numbering.clear();
401 Numbering[&Die] = 1;
402
403 if (!DWOName.empty())
404 Hash.update(DWOName);
405
406 computeHash(Die);
407
408
410 Hash.final(Result);
411
412
413
414
415 return Result.high();
416}
417
418
419
420
421
423 Numbering.clear();
424 Numbering[&Die] = 1;
425
427 addParentContext(*Parent);
428
429
430 computeHash(Die);
431
432
434 Hash.final(Result);
435
436
437
438
439 return Result.high();
440}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr)
Grabs the string in whichever attribute is passed in and returns a reference to it.
Definition DIEHash.cpp:30
This file contains constants used for implementing Dwarf debug support.
static bool isType(const Metadata *MD)
Functions, function parameters, and return types can have attributes to indicate how they should be t...
void hashRawTypeReference(const DIE &Entry)
Definition DIEHash.cpp:209
LLVM_ABI_FOR_TEST uint64_t computeTypeSignature(const DIE &Die)
Computes the type signature.
Definition DIEHash.cpp:422
void addSLEB128(int64_t Value)
Encodes and adds.
Definition DIEHash.cpp:63
uint64_t computeCUSignature(StringRef DWOName, const DIE &Die)
Computes the CU signature.
Definition DIEHash.cpp:399
void addULEB128(uint64_t Value)
Encodes and adds.
Definition DIEHash.cpp:52
Represents a pointer to a location list in the debug_loc section.
size_t getValue() const
Grab the current index out.
iterator_range< const_value_iterator > const_value_range
A structured debug information entry.
dwarf::Tag getTag() const
LLVM_ABI DIE * getParent() const
const List & getList(size_t LI) const
ArrayRef< Entry > getEntries(const List &L) const
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit an entry for the debug loc section.
const DebugLocStream & getDebugLocs() const
Returns the entries for the .debug_loc section.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
LLVM Value Representation.
LLVM_ABI StringRef AttributeString(unsigned Attribute)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
ArrayRef(const T &OneElt) -> ArrayRef< T >