1 /*========================== begin_copyright_notice ============================
2
3 Copyright (C) 2017-2021 Intel Corporation
4
5 SPDX-License-Identifier: MIT
6
7 ============================= end_copyright_notice ===========================*/
8
9 /*========================== begin_copyright_notice ============================
10
11 This file is distributed under the University of Illinois Open Source License.
12 See LICENSE.TXT for details.
13
14 ============================= end_copyright_notice ===========================*/
15
16 ///////////////////////////////////////////////////////////////////////////////
17 // This file is based on llvm-3.4\lib\CodeGen\AsmPrinter\DIE.cpp
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include "llvm/Config/llvm-config.h"
21 #include "common/LLVMWarningsPush.hpp"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/MC/MCAsmInfo.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCExpr.h"
27 #include "llvm/Support/Allocator.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/Format.h"
30 #include "llvm/Support/FormattedStream.h"
31 #include "llvm/Support/LEB128.h"
32 #include "common/LLVMWarningsPop.hpp"
33
34 #include "DIE.hpp"
35 #include "DwarfDebug.hpp"
36 #include "StreamEmitter.hpp"
37
38 #include "Probe/Assertion.h"
39
40 using namespace llvm;
41 using namespace ::IGC;
42
43 //===----------------------------------------------------------------------===//
44 // DIEAbbrevData Implementation
45 //===----------------------------------------------------------------------===//
46
47 /// Profile - Used to gather unique data for the abbreviation folding set.
48 ///
Profile(FoldingSetNodeID & ID) const49 void DIEAbbrevData::Profile(FoldingSetNodeID& ID) const
50 {
51 // Explicitly cast to an integer type for which FoldingSetNodeID has
52 // overloads. Otherwise MSVC 2010 thinks this call is ambiguous.
53 ID.AddInteger(unsigned(Attribute));
54 ID.AddInteger(unsigned(Form));
55 }
56
57 //===----------------------------------------------------------------------===//
58 // DIEAbbrev Implementation
59 //===----------------------------------------------------------------------===//
60
61 /// Profile - Used to gather unique data for the abbreviation folding set.
62 ///
Profile(FoldingSetNodeID & ID) const63 void DIEAbbrev::Profile(FoldingSetNodeID& ID) const
64 {
65 ID.AddInteger(unsigned(Tag));
66 ID.AddInteger(ChildrenFlag);
67
68 // For each attribute description.
69 for (unsigned i = 0, N = Data.size(); i < N; ++i)
70 {
71 Data[i].Profile(ID);
72 }
73 }
74
75 /// Emit - Print the abbreviation using the specified asm printer.
76 ///
Emit(StreamEmitter * AP) const77 void DIEAbbrev::Emit(StreamEmitter* AP) const
78 {
79 // Emit its Dwarf tag type.
80 AP->EmitULEB128(Tag, dwarf::TagString(Tag));
81
82 // Emit whether it has children DIEs.
83 AP->EmitULEB128(ChildrenFlag, dwarf::ChildrenString(ChildrenFlag));
84
85 // For each attribute description.
86 for (unsigned i = 0, N = Data.size(); i < N; ++i)
87 {
88 const DIEAbbrevData& AttrData = Data[i];
89
90 // Emit attribute type.
91 AP->EmitULEB128(AttrData.getAttribute(), dwarf::AttributeString(AttrData.getAttribute()));
92
93 // Emit form type.
94 AP->EmitULEB128(AttrData.getForm(), dwarf::FormEncodingString(AttrData.getForm()));
95 }
96
97 // Mark end of abbreviation.
98 AP->EmitULEB128(0, "EOM(1)");
99 AP->EmitULEB128(0, "EOM(2)");
100 }
101
102 #ifndef NDEBUG
print(raw_ostream & O)103 void DIEAbbrev::print(raw_ostream& O)
104 {
105 O << "Abbreviation @"
106 << format("0x%lx", (long)(intptr_t)this)
107 << " "
108 << dwarf::TagString(Tag)
109 << " "
110 << dwarf::ChildrenString(ChildrenFlag)
111 << '\n';
112
113 for (unsigned i = 0, N = Data.size(); i < N; ++i)
114 {
115 O << " "
116 << dwarf::AttributeString(Data[i].getAttribute())
117 << " "
118 << dwarf::FormEncodingString(Data[i].getForm())
119 << '\n';
120 }
121 }
122
dump()123 void DIEAbbrev::dump()
124 {
125 print(dbgs());
126 }
127 #endif
128
129 //===----------------------------------------------------------------------===//
130 // DIE Implementation
131 //===----------------------------------------------------------------------===//
132
~DIE()133 DIE::~DIE()
134 {
135 for (unsigned i = 0, N = Children.size(); i < N; ++i)
136 delete Children[i];
137 }
138
139 /// Climb up the parent chain to get the compile unit DIE to which this DIE
140 /// belongs.
getCompileUnit() const141 const DIE* DIE::getCompileUnit() const
142 {
143 const DIE* const Cu = getCompileUnitOrNull();
144 IGC_ASSERT_MESSAGE(nullptr != Cu, "We should not have orphaned DIEs.");
145 return Cu;
146 }
147
148 /// Climb up the parent chain to get the compile unit DIE this DIE belongs
149 /// to. Return NULL if DIE is not added to an owner yet.
getCompileUnitOrNull() const150 const DIE* DIE::getCompileUnitOrNull() const
151 {
152 const DIE* p = this;
153 while (p)
154 {
155 if (p->getTag() == dwarf::DW_TAG_compile_unit)
156 return p;
157 p = p->getParent();
158 }
159 return NULL;
160 }
161
findAttribute(uint16_t Attribute)162 DIEValue* DIE::findAttribute(uint16_t Attribute)
163 {
164 const SmallVectorImpl<DIEValue*>& Values = getValues();
165 const DIEAbbrev& Abbrevs = getAbbrev();
166
167 // Iterate through all the attributes until we find the one we're
168 // looking for, if we can't find it return NULL.
169 for (size_t i = 0; i < Values.size(); ++i)
170 if (Abbrevs.getData()[i].getAttribute() == Attribute)
171 return Values[i];
172 return NULL;
173 }
174
175 #ifndef NDEBUG
print(raw_ostream & O,unsigned IndentCount) const176 void DIE::print(raw_ostream& O, unsigned IndentCount) const
177 {
178 const std::string Indent(IndentCount, ' ');
179 bool isBlock = Abbrev.getTag() == 0;
180
181 if (!isBlock)
182 {
183 O << Indent
184 << "Die: "
185 << format("0x%lx", (long)(intptr_t)this)
186 << ", Offset: " << Offset
187 << ", Size: " << Size << "\n";
188
189 O << Indent
190 << dwarf::TagString(Abbrev.getTag())
191 << " "
192 << dwarf::ChildrenString(Abbrev.getChildrenFlag()) << "\n";
193 }
194 else {
195 O << "Size: " << Size << "\n";
196 }
197
198 const SmallVectorImpl<DIEAbbrevData>& Data = Abbrev.getData();
199
200 IndentCount += 2;
201 for (unsigned i = 0, N = Data.size(); i < N; ++i)
202 {
203 O << Indent;
204
205 if (!isBlock)
206 O << dwarf::AttributeString(Data[i].getAttribute());
207 else
208 O << "Blk[" << i << "]";
209
210 O << " "
211 << dwarf::FormEncodingString(Data[i].getForm())
212 << " ";
213 Values[i]->print(O);
214 O << "\n";
215 }
216 IndentCount -= 2;
217
218 for (unsigned j = 0, M = Children.size(); j < M; ++j)
219 {
220 Children[j]->print(O, IndentCount + 4);
221 }
222
223 if (!isBlock) O << "\n";
224 }
225
dump()226 void DIE::dump()
227 {
228 print(dbgs());
229 }
230 #endif
231
232 #ifndef NDEBUG
dump() const233 void DIEValue::dump() const
234 {
235 print(dbgs());
236 }
237 #endif
238
239 //===----------------------------------------------------------------------===//
240 // DIEInteger Implementation
241 //===----------------------------------------------------------------------===//
242
243 /// EmitValue - Emit integer of appropriate size.
244 ///
EmitValue(StreamEmitter * Asm,dwarf::Form Form) const245 void DIEInteger::EmitValue(StreamEmitter* Asm, dwarf::Form Form) const
246 {
247 unsigned Size = ~0U;
248 switch (Form)
249 {
250 case dwarf::DW_FORM_flag_present:
251 return;
252 case dwarf::DW_FORM_flag: // Fall thru
253 case dwarf::DW_FORM_ref1: // Fall thru
254 case dwarf::DW_FORM_data1: Size = 1; break;
255 case dwarf::DW_FORM_ref2: // Fall thru
256 case dwarf::DW_FORM_data2: Size = 2; break;
257 case dwarf::DW_FORM_sec_offset: // Fall thru
258 case dwarf::DW_FORM_ref4: // Fall thru
259 case dwarf::DW_FORM_data4: Size = 4; break;
260 case dwarf::DW_FORM_ref8: // Fall thru
261 case dwarf::DW_FORM_data8: Size = 8; break;
262 case dwarf::DW_FORM_GNU_str_index: Asm->EmitULEB128(Integer); return;
263 case dwarf::DW_FORM_GNU_addr_index: Asm->EmitULEB128(Integer); return;
264 case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return;
265 case dwarf::DW_FORM_sdata: Asm->EmitSLEB128(Integer); return;
266 case dwarf::DW_FORM_addr:
267 Size = Asm->GetPointerSize(); break;
268 default: IGC_ASSERT_EXIT_MESSAGE(0, "DIE Value form not supported yet");
269 }
270 Asm->EmitIntValue(Integer, Size);
271 }
272
273 /// SizeOf - Determine size of integer value in bytes.
274 ///
SizeOf(StreamEmitter * AP,dwarf::Form Form) const275 unsigned DIEInteger::SizeOf(StreamEmitter* AP, dwarf::Form Form) const
276 {
277 switch (Form)
278 {
279 case dwarf::DW_FORM_flag_present: return 0;
280 case dwarf::DW_FORM_flag: // Fall thru
281 case dwarf::DW_FORM_ref1: // Fall thru
282 case dwarf::DW_FORM_data1: return sizeof(int8_t);
283 case dwarf::DW_FORM_ref2: // Fall thru
284 case dwarf::DW_FORM_data2: return sizeof(int16_t);
285 case dwarf::DW_FORM_sec_offset: // Fall thru
286 case dwarf::DW_FORM_ref4: // Fall thru
287 case dwarf::DW_FORM_data4: return sizeof(int32_t);
288 case dwarf::DW_FORM_ref8: // Fall thru
289 case dwarf::DW_FORM_data8: return sizeof(int64_t);
290 case dwarf::DW_FORM_GNU_str_index: return getULEB128Size(Integer);
291 case dwarf::DW_FORM_GNU_addr_index: return getULEB128Size(Integer);
292 case dwarf::DW_FORM_udata: return getULEB128Size(Integer);
293 case dwarf::DW_FORM_sdata: return getSLEB128Size(Integer);
294 case dwarf::DW_FORM_addr: return AP->GetPointerSize();
295 default: IGC_ASSERT_EXIT_MESSAGE(0, "DIE Value form not supported yet");
296 }
297 }
298
299 #ifndef NDEBUG
print(raw_ostream & O) const300 void DIEInteger::print(raw_ostream& O) const
301 {
302 O << "Int: " << (int64_t)Integer << " 0x";
303 O.write_hex(Integer);
304 }
305 #endif
306
307 //===----------------------------------------------------------------------===//
308 // DIEExpr Implementation
309 //===----------------------------------------------------------------------===//
310
311 /// EmitValue - Emit expression value.
312 ///
EmitValue(StreamEmitter * AP,dwarf::Form Form) const313 void DIEExpr::EmitValue(StreamEmitter* AP, dwarf::Form Form) const
314 {
315 AP->EmitValue(Expr, SizeOf(AP, Form));
316 }
317
318 /// SizeOf - Determine size of expression value in bytes.
319 ///
SizeOf(StreamEmitter * AP,dwarf::Form Form) const320 unsigned DIEExpr::SizeOf(StreamEmitter* AP, dwarf::Form Form) const
321 {
322 if (Form == dwarf::DW_FORM_data4) return 4;
323 if (Form == dwarf::DW_FORM_sec_offset) return 4;
324 if (Form == dwarf::DW_FORM_strp) return 4;
325 return AP->GetPointerSize();
326 }
327
328 #ifndef NDEBUG
print(raw_ostream & O) const329 void DIEExpr::print(raw_ostream& O) const
330 {
331 O << "Expr: ";
332 //Expr->print(O);
333 }
334 #endif
335
336 //===----------------------------------------------------------------------===//
337 // DIELabel Implementation
338 //===----------------------------------------------------------------------===//
339
340 /// EmitValue - Emit label value.
341 ///
EmitValue(StreamEmitter * AP,dwarf::Form Form) const342 void DIELabel::EmitValue(StreamEmitter* AP, dwarf::Form Form) const
343 {
344 AP->EmitLabelReference(Label, SizeOf(AP, Form),
345 Form == dwarf::DW_FORM_strp ||
346 Form == dwarf::DW_FORM_sec_offset ||
347 Form == dwarf::DW_FORM_ref_addr);
348 }
349
350 /// SizeOf - Determine size of label value in bytes.
351 ///
SizeOf(StreamEmitter * AP,dwarf::Form Form) const352 unsigned DIELabel::SizeOf(StreamEmitter* AP, dwarf::Form Form) const
353 {
354 if (Form == dwarf::DW_FORM_data4) return 4;
355 if (Form == dwarf::DW_FORM_sec_offset) return 4;
356 if (Form == dwarf::DW_FORM_strp) return 4;
357 return AP->GetPointerSize();
358 }
359
360 #ifndef NDEBUG
print(raw_ostream & O) const361 void DIELabel::print(raw_ostream& O) const
362 {
363 O << "Lbl: " << Label->getName();
364 }
365 #endif
366
367 //===----------------------------------------------------------------------===//
368 // DIEDelta Implementation
369 //===----------------------------------------------------------------------===//
370
371 /// EmitValue - Emit delta value.
372 ///
EmitValue(StreamEmitter * AP,dwarf::Form Form) const373 void DIEDelta::EmitValue(StreamEmitter* AP, dwarf::Form Form) const
374 {
375 AP->EmitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form));
376 }
377
378 /// SizeOf - Determine size of delta value in bytes.
379 ///
SizeOf(StreamEmitter * AP,dwarf::Form Form) const380 unsigned DIEDelta::SizeOf(StreamEmitter* AP, dwarf::Form Form) const
381 {
382 if (Form == dwarf::DW_FORM_data4) return 4;
383 if (Form == dwarf::DW_FORM_strp) return 4;
384 return AP->GetPointerSize();
385 }
386
387 #ifndef NDEBUG
print(raw_ostream & O) const388 void DIEDelta::print(raw_ostream& O) const
389 {
390 O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();
391 }
392 #endif
393
394 //===----------------------------------------------------------------------===//
395 // DIEString Implementation
396 //===----------------------------------------------------------------------===//
397
398 /// EmitValue - Emit string value.
399 ///
EmitValue(StreamEmitter * AP,dwarf::Form Form) const400 void DIEString::EmitValue(StreamEmitter* AP, dwarf::Form Form) const
401 {
402 Access->EmitValue(AP, Form);
403 }
404
405 /// SizeOf - Determine size of delta value in bytes.
406 ///
SizeOf(StreamEmitter * AP,dwarf::Form Form) const407 unsigned DIEString::SizeOf(StreamEmitter* AP, dwarf::Form Form) const
408 {
409 return Access->SizeOf(AP, Form);
410 }
411
412 #ifndef NDEBUG
print(raw_ostream & O) const413 void DIEString::print(raw_ostream& O) const
414 {
415 O << "String: " << Str << "\tSymbol: ";
416 Access->print(O);
417 }
418 #endif
419
420 //===----------------------------------------------------------------------===//
421 // DIEInlinedString Implementation
422 //===----------------------------------------------------------------------===//
423
424 /// EmitValue - Emit string value.
425 ///
EmitValue(StreamEmitter * AP,dwarf::Form Form) const426 void DIEInlinedString::EmitValue(StreamEmitter* AP, dwarf::Form Form) const
427 {
428 AP->EmitBytes(Str);
429 AP->EmitInt8(0);
430 }
431
432 /// SizeOf - Determine size of delta value in bytes.
433 ///
SizeOf(StreamEmitter * AP,dwarf::Form Form) const434 unsigned DIEInlinedString::SizeOf(StreamEmitter* AP, dwarf::Form Form) const
435 {
436 return Str.size() + 1;
437 }
438
439 #ifndef NDEBUG
print(raw_ostream & O) const440 void DIEInlinedString::print(raw_ostream& O) const
441 {
442 O << "Inlined string: " << Str << "\tSymbol: ";
443 }
444 #endif
445
446 //===----------------------------------------------------------------------===//
447 // DIEEntry Implementation
448 //===----------------------------------------------------------------------===//
449
450 /// EmitValue - Emit debug information entry offset.
451 ///
EmitValue(StreamEmitter * AP,dwarf::Form Form) const452 void DIEEntry::EmitValue(StreamEmitter* AP, dwarf::Form Form) const
453 {
454 AP->EmitInt32(Entry->getOffset());
455 }
456
getRefAddrSize(StreamEmitter * AP,unsigned DwarfVersion)457 unsigned DIEEntry::getRefAddrSize(StreamEmitter* AP, unsigned DwarfVersion)
458 {
459 // DWARF4: References that use the attribute form DW_FORM_ref_addr are
460 // specified to be four bytes in the DWARF 32-bit format and eight bytes
461 // in the DWARF 64-bit format, while DWARF Version 2 specifies that such
462 // references have the same size as an address on the target system.
463 if (DwarfVersion == 2)
464 return AP->GetPointerSize();
465 return sizeof(int32_t);
466 }
467
468 #ifndef NDEBUG
print(raw_ostream & O) const469 void DIEEntry::print(raw_ostream& O) const
470 {
471 O << format("Die: 0x%lx", (long)(intptr_t)Entry);
472 }
473 #endif
474
475 //===----------------------------------------------------------------------===//
476 // DIEBlock Implementation
477 //===----------------------------------------------------------------------===//
478
479 /// ComputeSize - calculate the size of the block.
480 ///
ComputeSize(StreamEmitter * AP)481 unsigned DIEBlock::ComputeSize(StreamEmitter* AP)
482 {
483 if (!Size)
484 {
485 const SmallVectorImpl<DIEAbbrevData>& AbbrevData = Abbrev.getData();
486 for (unsigned i = 0, N = Values.size(); i < N; ++i)
487 Size += Values[i]->SizeOf(AP, AbbrevData[i].getForm());
488 }
489
490 return Size;
491 }
492
493 /// ComputeSizeOnTheFly - calculate size of block on the fly.
494 /// This function is used to compute size of abbrevs already
495 /// emitted this far. It doesnt update Size method.
ComputeSizeOnTheFly(StreamEmitter * AP) const496 unsigned DIEBlock::ComputeSizeOnTheFly(StreamEmitter* AP) const
497 {
498 unsigned S = 0;
499 const SmallVectorImpl<DIEAbbrevData>& AbbrevData = Abbrev.getData();
500 for (unsigned i = 0, N = Values.size(); i < N; ++i)
501 S += Values[i]->SizeOf(AP, AbbrevData[i].getForm());
502
503 return S;
504 }
505
506 /// EmitToRawBuffer - emit data to raw buffer for encoding in debug_loc.
EmitToRawBuffer(std::vector<unsigned char> & buffer)507 void DIEBlock::EmitToRawBuffer(std::vector<unsigned char>& buffer)
508 {
509 auto insertData = [](const void* ptr, unsigned size, std::vector<unsigned char>& vec)
510 {
511 for (unsigned i = 0; i < size; ++i)
512 {
513 vec.push_back(*(((const unsigned char*)ptr) + i));
514 }
515 };
516
517 const SmallVectorImpl<DIEAbbrevData>& AbbrevData = Abbrev.getData();
518 for (unsigned i = 0, N = Values.size(); i < N; ++i)
519 {
520 uint64_t intVal = 0;
521 switch (Values[i]->getType())
522 {
523 case DIEValue::isInteger:
524 intVal = cast<DIEInteger>(Values[i])->getValue();
525 if (AbbrevData[i].getForm() == dwarf::DW_FORM_data1)
526 insertData(&intVal, sizeof(uint8_t), buffer);
527 else if(AbbrevData[i].getForm() == dwarf::DW_FORM_data2)
528 insertData(&intVal, sizeof(uint16_t), buffer);
529 else if (AbbrevData[i].getForm() == dwarf::DW_FORM_data4)
530 insertData(&intVal, sizeof(uint32_t), buffer);
531 else if (AbbrevData[i].getForm() == dwarf::DW_FORM_data8)
532 insertData(&intVal, sizeof(uint64_t), buffer);
533 else if (AbbrevData[i].getForm() == dwarf::DW_FORM_sdata)
534 {
535 auto slebsize = getSLEB128Size(intVal);
536 auto sleb = malloc(slebsize);
537 encodeSLEB128((int64_t)intVal, (uint8_t*)sleb);
538 insertData(sleb, slebsize, buffer);
539 free(sleb);
540 }
541 else if (AbbrevData[i].getForm() == dwarf::DW_FORM_udata)
542 {
543 auto ulebsize = getULEB128Size(intVal);
544 auto uleb = malloc(ulebsize);
545 encodeULEB128(intVal, (uint8_t*)uleb);
546 insertData(uleb, ulebsize, buffer);
547 free(uleb);
548 }
549 else
550 {
551 IGC_ASSERT_MESSAGE(false, "Unexpected dwarf encoding form");
552 }
553 break;
554 default:
555 IGC_ASSERT_MESSAGE(false, "Unexpected condition");
556 break;
557 }
558 }
559 }
560
561 /// EmitValue - Emit block data.
562 ///
EmitValue(StreamEmitter * Asm,dwarf::Form Form) const563 void DIEBlock::EmitValue(StreamEmitter* Asm, dwarf::Form Form) const
564 {
565 switch (Form)
566 {
567 default: IGC_ASSERT_EXIT_MESSAGE(0, "Improper form for block");
568 case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
569 case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
570 case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
571 case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break;
572 }
573
574 const SmallVectorImpl<DIEAbbrevData>& AbbrevData = Abbrev.getData();
575 for (unsigned i = 0, N = Values.size(); i < N; ++i)
576 Values[i]->EmitValue(Asm, AbbrevData[i].getForm());
577 }
578
579 /// SizeOf - Determine size of block data in bytes.
580 ///
SizeOf(StreamEmitter *,dwarf::Form Form) const581 unsigned DIEBlock::SizeOf(StreamEmitter* /*AP*/, dwarf::Form Form) const
582 {
583 switch (Form)
584 {
585 case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
586 case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
587 case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
588 case dwarf::DW_FORM_block: return Size + getULEB128Size(Size);
589 default: IGC_ASSERT_EXIT_MESSAGE(0, "Improper form for block");
590 }
591 }
592
593 #ifndef NDEBUG
print(raw_ostream & O) const594 void DIEBlock::print(raw_ostream& O) const
595 {
596 O << "Blk: ";
597 DIE::print(O, 5);
598 }
599 #endif
600