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