LLVM  9.0.0svn
DWARFDie.cpp
Go to the documentation of this file.
1 //===- DWARFDie.cpp -------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/None.h"
11 #include "llvm/ADT/Optional.h"
12 #include "llvm/ADT/SmallSet.h"
13 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Object/ObjectFile.h"
23 #include "llvm/Support/Format.h"
26 #include "llvm/Support/WithColor.h"
28 #include <algorithm>
29 #include <cassert>
30 #include <cinttypes>
31 #include <cstdint>
32 #include <string>
33 #include <utility>
34 
35 using namespace llvm;
36 using namespace dwarf;
37 using namespace object;
38 
39 static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
40  OS << " (";
41  do {
42  uint64_t Shift = countTrailingZeros(Val);
43  assert(Shift < 64 && "undefined behavior");
44  uint64_t Bit = 1ULL << Shift;
45  auto PropName = ApplePropertyString(Bit);
46  if (!PropName.empty())
47  OS << PropName;
48  else
49  OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit);
50  if (!(Val ^= Bit))
51  break;
52  OS << ", ";
53  } while (true);
54  OS << ")";
55 }
56 
57 static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS,
58  const DWARFAddressRangesVector &Ranges,
59  unsigned AddressSize, unsigned Indent,
60  const DIDumpOptions &DumpOpts) {
61  if (!DumpOpts.ShowAddresses)
62  return;
63 
64  ArrayRef<SectionName> SectionNames;
65  if (DumpOpts.Verbose)
66  SectionNames = Obj.getSectionNames();
67 
68  for (const DWARFAddressRange &R : Ranges) {
69  OS << '\n';
70  OS.indent(Indent);
71  R.dump(OS, AddressSize);
72 
73  DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, R.SectionIndex);
74  }
75 }
76 
77 static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
78  DWARFUnit *U, unsigned Indent,
79  DIDumpOptions DumpOpts) {
80  DWARFContext &Ctx = U->getContext();
81  const DWARFObject &Obj = Ctx.getDWARFObj();
82  const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
83  if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
85  ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
86  DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
87  Ctx.isLittleEndian(), 0);
89  .print(OS, MRI, U);
90  return;
91  }
92 
93  FormValue.dump(OS, DumpOpts);
95  uint32_t Offset = *FormValue.getAsSectionOffset();
96  if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) {
99  Obj.getAddressSize());
100  auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
101  if (LL) {
102  uint64_t BaseAddr = 0;
104  BaseAddr = BA->Address;
105  LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U,
106  BaseAddr, Indent);
107  } else
108  OS << "error extracting location list.";
109  return;
110  }
111 
112  bool UseLocLists = !U->isDWOUnit();
113  StringRef LoclistsSectionData =
114  UseLocLists ? Obj.getLoclistsSection().Data : U->getLocSectionData();
115 
116  if (!LoclistsSectionData.empty()) {
117  DataExtractor Data(LoclistsSectionData, Ctx.isLittleEndian(),
118  Obj.getAddressSize());
119 
120  // Old-style location list were used in DWARF v4 (.debug_loc.dwo section).
121  // Modern locations list (.debug_loclists) are used starting from v5.
122  // Ideally we should take the version from the .debug_loclists section
123  // header, but using CU's version for simplicity.
125  Data, &Offset, UseLocLists ? U->getVersion() : 4);
126 
127  uint64_t BaseAddr = 0;
129  BaseAddr = BA->Address;
130 
131  if (LL)
132  LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI,
133  U, Indent);
134  else
135  OS << "error extracting location list.";
136  }
137  }
138 }
139 
140 /// Dump the name encoded in the type tag.
142  StringRef TagStr = TagString(T);
143  if (!TagStr.startswith("DW_TAG_") || !TagStr.endswith("_type"))
144  return;
145  OS << TagStr.substr(7, TagStr.size() - 12) << " ";
146 }
147 
148 static void dumpArrayType(raw_ostream &OS, const DWARFDie &D) {
149  Optional<uint64_t> Bound;
150  for (const DWARFDie &C : D.children())
151  if (C.getTag() == DW_TAG_subrange_type) {
153  Optional<uint64_t> Count;
155  Optional<unsigned> DefaultLB;
156  if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
157  LB = L->getAsUnsignedConstant();
158  if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
159  Count = CountV->getAsUnsignedConstant();
160  if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
161  UB = UpperV->getAsUnsignedConstant();
162  if (Optional<DWARFFormValue> LV =
163  D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
164  if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
165  if ((DefaultLB =
166  LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
167  if (LB && *LB == *DefaultLB)
168  LB = None;
169  if (!LB && !Count && !UB)
170  OS << "[]";
171  else if (!LB && (Count || UB) && DefaultLB)
172  OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
173  else {
174  OS << "[[";
175  if (LB)
176  OS << *LB;
177  else
178  OS << '?';
179  OS << ", ";
180  if (Count)
181  if (LB)
182  OS << *LB + *Count;
183  else
184  OS << "? + " << *Count;
185  else if (UB)
186  OS << *UB + 1;
187  else
188  OS << '?';
189  OS << ")]";
190  }
191  }
192 }
193 
194 /// Recursively dump the DIE type name when applicable.
195 static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) {
196  if (!D.isValid())
197  return;
198 
199  if (const char *Name = D.getName(DINameKind::LinkageName)) {
200  OS << Name;
201  return;
202  }
203 
204  // FIXME: We should have pretty printers per language. Currently we print
205  // everything as if it was C++ and fall back to the TAG type name.
206  const dwarf::Tag T = D.getTag();
207  switch (T) {
208  case DW_TAG_array_type:
209  case DW_TAG_pointer_type:
210  case DW_TAG_ptr_to_member_type:
211  case DW_TAG_reference_type:
212  case DW_TAG_rvalue_reference_type:
213  case DW_TAG_subroutine_type:
214  break;
215  default:
216  dumpTypeTagName(OS, T);
217  }
218 
219  // Follow the DW_AT_type if possible.
220  DWARFDie TypeDie = D.getAttributeValueAsReferencedDie(DW_AT_type);
221  dumpTypeName(OS, TypeDie);
222 
223  switch (T) {
224  case DW_TAG_subroutine_type: {
225  if (!TypeDie)
226  OS << "void";
227  OS << '(';
228  bool First = true;
229  for (const DWARFDie &C : D.children()) {
230  if (C.getTag() == DW_TAG_formal_parameter) {
231  if (!First)
232  OS << ", ";
233  First = false;
234  dumpTypeName(OS, C.getAttributeValueAsReferencedDie(DW_AT_type));
235  }
236  }
237  OS << ')';
238  break;
239  }
240  case DW_TAG_array_type: {
241  dumpArrayType(OS, D);
242  break;
243  }
244  case DW_TAG_pointer_type:
245  OS << '*';
246  break;
247  case DW_TAG_ptr_to_member_type:
248  if (DWARFDie Cont =
249  D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
250  dumpTypeName(OS << ' ', Cont);
251  OS << "::";
252  }
253  OS << '*';
254  break;
255  case DW_TAG_reference_type:
256  OS << '&';
257  break;
258  case DW_TAG_rvalue_reference_type:
259  OS << "&&";
260  break;
261  default:
262  break;
263  }
264 }
265 
266 static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
267  uint32_t *OffsetPtr, dwarf::Attribute Attr,
268  dwarf::Form Form, unsigned Indent,
269  DIDumpOptions DumpOpts) {
270  if (!Die.isValid())
271  return;
272  const char BaseIndent[] = " ";
273  OS << BaseIndent;
274  OS.indent(Indent + 2);
275  WithColor(OS, HighlightColor::Attribute) << formatv("{0}", Attr);
276 
277  if (DumpOpts.Verbose || DumpOpts.ShowForm)
278  OS << formatv(" [{0}]", Form);
279 
280  DWARFUnit *U = Die.getDwarfUnit();
281  DWARFFormValue FormValue = DWARFFormValue::createFromUnit(Form, U, OffsetPtr);
282 
283  OS << "\t(";
284 
285  StringRef Name;
286  std::string File;
288  if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
290  if (const auto *LT = U->getContext().getLineTableForUnit(U))
291  if (LT->getFileNameByIndex(
292  FormValue.getAsUnsignedConstant().getValue(),
293  U->getCompilationDir(),
295  File = '"' + File + '"';
296  Name = File;
297  }
298  } else if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant())
299  Name = AttributeValueString(Attr, *Val);
300 
301  if (!Name.empty())
302  WithColor(OS, Color) << Name;
303  else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
304  OS << *FormValue.getAsUnsignedConstant();
305  else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
306  FormValue.getAsUnsignedConstant()) {
307  if (DumpOpts.ShowAddresses) {
308  // Print the actual address rather than the offset.
309  uint64_t LowPC, HighPC, Index;
310  if (Die.getLowAndHighPC(LowPC, HighPC, Index))
311  OS << format("0x%016" PRIx64, HighPC);
312  else
313  FormValue.dump(OS, DumpOpts);
314  }
316  dumpLocation(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
317  else
318  FormValue.dump(OS, DumpOpts);
319 
320  std::string Space = DumpOpts.ShowAddresses ? " " : "";
321 
322  // We have dumped the attribute raw value. For some attributes
323  // having both the raw value and the pretty-printed value is
324  // interesting. These attributes are handled below.
325  if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
326  if (const char *Name =
329  OS << Space << "\"" << Name << '\"';
330  } else if (Attr == DW_AT_type) {
331  OS << Space << "\"";
333  OS << '"';
334  } else if (Attr == DW_AT_APPLE_property_attribute) {
335  if (Optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant())
336  dumpApplePropertyAttribute(OS, *OptVal);
337  } else if (Attr == DW_AT_ranges) {
338  const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj();
339  // For DW_FORM_rnglistx we need to dump the offset separately, since
340  // we have only dumped the index so far.
341  if (FormValue.getForm() == DW_FORM_rnglistx)
342  if (auto RangeListOffset =
343  U->getRnglistOffset(*FormValue.getAsSectionOffset())) {
345  dwarf::DW_FORM_sec_offset, *RangeListOffset);
346  FV.dump(OS, DumpOpts);
347  }
348  if (auto RangesOrError = Die.getAddressRanges())
349  dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(),
350  sizeof(BaseIndent) + Indent + 4, DumpOpts);
351  else
352  WithColor::error() << "decoding address ranges: "
353  << toString(RangesOrError.takeError()) << '\n';
354  }
355 
356  OS << ")\n";
357 }
358 
359 bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram; }
360 
362  auto Tag = getTag();
363  return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine;
364 }
365 
367  if (!isValid())
368  return None;
369  auto AbbrevDecl = getAbbreviationDeclarationPtr();
370  if (AbbrevDecl)
371  return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U);
372  return None;
373 }
374 
377  if (!isValid())
378  return None;
379  auto AbbrevDecl = getAbbreviationDeclarationPtr();
380  if (AbbrevDecl) {
381  for (auto Attr : Attrs) {
382  if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U))
383  return Value;
384  }
385  }
386  return None;
387 }
388 
391  std::vector<DWARFDie> Worklist;
392  Worklist.push_back(*this);
393 
394  // Keep track if DIEs already seen to prevent infinite recursion.
395  // Empirically we rarely see a depth of more than 3 when dealing with valid
396  // DWARF. This corresponds to following the DW_AT_abstract_origin and
397  // DW_AT_specification just once.
399  Seen.insert(*this);
400 
401  while (!Worklist.empty()) {
402  DWARFDie Die = Worklist.back();
403  Worklist.pop_back();
404 
405  if (!Die.isValid())
406  continue;
407 
408  if (auto Value = Die.find(Attrs))
409  return Value;
410 
411  if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
412  if (Seen.insert(D).second)
413  Worklist.push_back(D);
414 
415  if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
416  if (Seen.insert(D).second)
417  Worklist.push_back(D);
418  }
419 
420  return None;
421 }
422 
423 DWARFDie
425  if (Optional<DWARFFormValue> F = find(Attr))
426  return getAttributeValueAsReferencedDie(*F);
427  return DWARFDie();
428 }
429 
430 DWARFDie
432  if (auto SpecRef = V.getAsRelativeReference()) {
433  if (SpecRef->Unit)
434  return SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() + SpecRef->Offset);
435  if (auto SpecUnit = U->getUnitVector().getUnitForOffset(SpecRef->Offset))
436  return SpecUnit->getDIEForOffset(SpecRef->Offset);
437  }
438  return DWARFDie();
439 }
440 
442  return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
443 }
444 
446  if (auto FormValue = find(DW_AT_high_pc)) {
447  if (auto Address = FormValue->getAsAddress()) {
448  // High PC is an address.
449  return Address;
450  }
451  if (auto Offset = FormValue->getAsUnsignedConstant()) {
452  // High PC is an offset from LowPC.
453  return LowPC + *Offset;
454  }
455  }
456  return None;
457 }
458 
459 bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
460  uint64_t &SectionIndex) const {
461  auto F = find(DW_AT_low_pc);
462  auto LowPcAddr = toSectionedAddress(F);
463  if (!LowPcAddr)
464  return false;
465  if (auto HighPcAddr = getHighPC(LowPcAddr->Address)) {
466  LowPC = LowPcAddr->Address;
467  HighPC = *HighPcAddr;
468  SectionIndex = LowPcAddr->SectionIndex;
469  return true;
470  }
471  return false;
472 }
473 
475  if (isNULL())
476  return DWARFAddressRangesVector();
477  // Single range specified by low/high PC.
478  uint64_t LowPC, HighPC, Index;
479  if (getLowAndHighPC(LowPC, HighPC, Index))
480  return DWARFAddressRangesVector{{LowPC, HighPC, Index}};
481 
482  Optional<DWARFFormValue> Value = find(DW_AT_ranges);
483  if (Value) {
484  if (Value->getForm() == DW_FORM_rnglistx)
485  return U->findRnglistFromIndex(*Value->getAsSectionOffset());
486  return U->findRnglistFromOffset(*Value->getAsSectionOffset());
487  }
488  return DWARFAddressRangesVector();
489 }
490 
492  DWARFAddressRangesVector &Ranges) const {
493  if (isNULL())
494  return;
495  if (isSubprogramDIE()) {
496  if (auto DIERangesOrError = getAddressRanges())
497  Ranges.insert(Ranges.end(), DIERangesOrError.get().begin(),
498  DIERangesOrError.get().end());
499  else
500  llvm::consumeError(DIERangesOrError.takeError());
501  }
502 
503  for (auto Child : children())
504  Child.collectChildrenAddressRanges(Ranges);
505 }
506 
507 bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
508  auto RangesOrError = getAddressRanges();
509  if (!RangesOrError) {
510  llvm::consumeError(RangesOrError.takeError());
511  return false;
512  }
513 
514  for (const auto &R : RangesOrError.get())
515  if (R.LowPC <= Address && Address < R.HighPC)
516  return true;
517  return false;
518 }
519 
521  if (!isSubroutineDIE())
522  return nullptr;
523  return getName(Kind);
524 }
525 
526 const char *DWARFDie::getName(DINameKind Kind) const {
527  if (!isValid() || Kind == DINameKind::None)
528  return nullptr;
529  // Try to get mangled name only if it was asked for.
530  if (Kind == DINameKind::LinkageName) {
531  if (auto Name = dwarf::toString(
532  findRecursively({DW_AT_MIPS_linkage_name, DW_AT_linkage_name}),
533  nullptr))
534  return Name;
535  }
536  if (auto Name = dwarf::toString(findRecursively(DW_AT_name), nullptr))
537  return Name;
538  return nullptr;
539 }
540 
541 uint64_t DWARFDie::getDeclLine() const {
542  return toUnsigned(findRecursively(DW_AT_decl_line), 0);
543 }
544 
545 void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
546  uint32_t &CallColumn,
547  uint32_t &CallDiscriminator) const {
548  CallFile = toUnsigned(find(DW_AT_call_file), 0);
549  CallLine = toUnsigned(find(DW_AT_call_line), 0);
550  CallColumn = toUnsigned(find(DW_AT_call_column), 0);
551  CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0);
552 }
553 
554 /// Helper to dump a DIE with all of its parents, but no siblings.
555 static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent,
556  DIDumpOptions DumpOpts, unsigned Depth = 0) {
557  if (!Die)
558  return Indent;
559  if (DumpOpts.ParentRecurseDepth > 0 && Depth >= DumpOpts.ParentRecurseDepth)
560  return Indent;
561  Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts, Depth + 1);
562  Die.dump(OS, Indent, DumpOpts);
563  return Indent + 2;
564 }
565 
566 void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
567  DIDumpOptions DumpOpts) const {
568  if (!isValid())
569  return;
570  DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
571  const uint32_t Offset = getOffset();
572  uint32_t offset = Offset;
573  if (DumpOpts.ShowParents) {
574  DIDumpOptions ParentDumpOpts = DumpOpts;
575  ParentDumpOpts.ShowParents = false;
576  ParentDumpOpts.ShowChildren = false;
577  Indent = dumpParentChain(getParent(), OS, Indent, ParentDumpOpts);
578  }
579 
580  if (debug_info_data.isValidOffset(offset)) {
581  uint32_t abbrCode = debug_info_data.getULEB128(&offset);
582  if (DumpOpts.ShowAddresses)
584  << format("\n0x%8.8x: ", Offset);
585 
586  if (abbrCode) {
587  auto AbbrevDecl = getAbbreviationDeclarationPtr();
588  if (AbbrevDecl) {
589  WithColor(OS, HighlightColor::Tag).get().indent(Indent)
590  << formatv("{0}", getTag());
591  if (DumpOpts.Verbose)
592  OS << format(" [%u] %c", abbrCode,
593  AbbrevDecl->hasChildren() ? '*' : ' ');
594  OS << '\n';
595 
596  // Dump all data in the DIE for the attributes.
597  for (const auto &AttrSpec : AbbrevDecl->attributes()) {
598  if (AttrSpec.Form == DW_FORM_implicit_const) {
599  // We are dumping .debug_info section ,
600  // implicit_const attribute values are not really stored here,
601  // but in .debug_abbrev section. So we just skip such attrs.
602  continue;
603  }
604  dumpAttribute(OS, *this, &offset, AttrSpec.Attr, AttrSpec.Form,
605  Indent, DumpOpts);
606  }
607 
608  DWARFDie child = getFirstChild();
609  if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) {
610  DumpOpts.ChildRecurseDepth--;
611  DIDumpOptions ChildDumpOpts = DumpOpts;
612  ChildDumpOpts.ShowParents = false;
613  while (child) {
614  child.dump(OS, Indent + 2, ChildDumpOpts);
615  child = child.getSibling();
616  }
617  }
618  } else {
619  OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
620  << abbrCode << '\n';
621  }
622  } else {
623  OS.indent(Indent) << "NULL\n";
624  }
625  }
626 }
627 
629 
631  if (isValid())
632  return U->getParent(Die);
633  return DWARFDie();
634 }
635 
637  if (isValid())
638  return U->getSibling(Die);
639  return DWARFDie();
640 }
641 
643  if (isValid())
644  return U->getPreviousSibling(Die);
645  return DWARFDie();
646 }
647 
649  if (isValid())
650  return U->getFirstChild(Die);
651  return DWARFDie();
652 }
653 
655  if (isValid())
656  return U->getLastChild(Die);
657  return DWARFDie();
658 }
659 
661  return make_range(attribute_iterator(*this, false),
662  attribute_iterator(*this, true));
663 }
664 
666  : Die(D), AttrValue(0), Index(0) {
667  auto AbbrDecl = Die.getAbbreviationDeclarationPtr();
668  assert(AbbrDecl && "Must have abbreviation declaration");
669  if (End) {
670  // This is the end iterator so we set the index to the attribute count.
671  Index = AbbrDecl->getNumAttributes();
672  } else {
673  // This is the begin iterator so we extract the value for this->Index.
674  AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize();
675  updateForIndex(*AbbrDecl, 0);
676  }
677 }
678 
679 void DWARFDie::attribute_iterator::updateForIndex(
680  const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) {
681  Index = I;
682  // AbbrDecl must be valid before calling this function.
683  auto NumAttrs = AbbrDecl.getNumAttributes();
684  if (Index < NumAttrs) {
685  AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
686  // Add the previous byte size of any previous attribute value.
687  AttrValue.Offset += AttrValue.ByteSize;
688  uint32_t ParseOffset = AttrValue.Offset;
689  auto U = Die.getDwarfUnit();
690  assert(U && "Die must have valid DWARF unit");
692  AbbrDecl.getFormByIndex(Index), U, &ParseOffset);
693  AttrValue.ByteSize = ParseOffset - AttrValue.Offset;
694  } else {
695  assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only");
696  AttrValue.clear();
697  }
698 }
699 
701  if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr())
702  updateForIndex(*AbbrDecl, Index + 1);
703  return *this;
704 }
705 
707  switch (Attr) {
708  // From the DWARF v5 specification.
709  case DW_AT_location:
710  case DW_AT_byte_size:
711  case DW_AT_bit_size:
712  case DW_AT_string_length:
713  case DW_AT_lower_bound:
714  case DW_AT_return_addr:
715  case DW_AT_bit_stride:
716  case DW_AT_upper_bound:
717  case DW_AT_count:
718  case DW_AT_data_member_location:
719  case DW_AT_frame_base:
720  case DW_AT_segment:
721  case DW_AT_static_link:
722  case DW_AT_use_location:
723  case DW_AT_vtable_elem_location:
724  case DW_AT_allocated:
725  case DW_AT_associated:
726  case DW_AT_byte_stride:
727  case DW_AT_rank:
728  case DW_AT_call_value:
729  case DW_AT_call_origin:
730  case DW_AT_call_target:
731  case DW_AT_call_target_clobbered:
732  case DW_AT_call_data_location:
733  case DW_AT_call_data_value:
734  // Extensions.
735  case DW_AT_GNU_call_site_value:
736  return true;
737  default:
738  return false;
739  }
740 }
void dump(raw_ostream &OS, DIDumpOptions DumpOpts=DIDumpOptions()) const
const NoneType None
Definition: None.h:23
uint64_t CallInst * C
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
Definition: GraphTraits.h:121
StringRef ApplePropertyString(unsigned)
Definition: Dwarf.cpp:501
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFUnit * getDwarfUnit() const
Definition: DWARFDie.h:53
bool isValid() const
Definition: DWARFDie.h:50
uint64_t getULEB128(uint32_t *offset_ptr) const
Extract a unsigned LEB128 value from *offset_ptr.
LLVM_NODISCARD bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:267
Optional< UnitOffset > getAsRelativeReference() const
dwarf::Attribute Attr
The attribute enumeration of this attribute.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:473
bool isSubprogramDIE() const
Returns true if DIE represents a subprogram (not inlined).
Definition: DWARFDie.cpp:359
An RAII object that temporarily switches an output stream to a specific color.
Definition: WithColor.h:37
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
bool addressRangeContainsAddress(const uint64_t Address) const
Definition: DWARFDie.cpp:507
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:256
Attribute
Attributes.
Definition: Dwarf.h:114
static raw_ostream & error()
Convenience method for printing "error: " to stderr.
Definition: WithColor.cpp:60
attribute_iterator & operator++()
Definition: DWARFDie.cpp:700
uint32_t ByteSize
The debug info/types section byte size of the data for this attribute.
void collectChildrenAddressRanges(DWARFAddressRangesVector &Ranges) const
Get all address ranges for any DW_TAG_subprogram DIEs in this DIE or any of its children.
Definition: DWARFDie.cpp:491
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:123
const DWARFSection * getLocSection() const
Definition: DWARFUnit.h:276
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Get the abbreviation declaration for this DIE.
Definition: DWARFDie.h:58
raw_ostream & indent(unsigned NumSpaces)
indent - Insert &#39;NumSpaces&#39; spaces.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)
Get a pointer to a parsed line table corresponding to a compile unit.
DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
Definition: DWARFDie.cpp:424
A debug info location.
Definition: DebugLoc.h:33
static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit, uint32_t *OffsetPtr)
F(f)
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
Definition: DIContext.h:117
Optional< unsigned > LanguageLowerBound(SourceLanguage L)
Definition: Dwarf.cpp:343
bool isFormClass(FormClass FC) const
void dump(raw_ostream &OS, unsigned indent=0, DIDumpOptions DumpOpts=DIDumpOptions()) const
Dump the DIE and all of its attributes to the supplied stream.
Definition: DWARFDie.cpp:566
dwarf::Form getForm() const
DWARFFormValue Value
The form and value for this attribute.
iterator_range< iterator > children() const
Definition: DWARFDie.h:382
const char * getCompilationDir()
Definition: DWARFUnit.cpp:345
Optional< uint64_t > getRangesBaseAttribute() const
Extract the range base attribute from this DIE as absolute section offset.
Definition: DWARFDie.cpp:441
Optional< ArrayRef< uint8_t > > getAsBlock() const
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, uint32_t *OffsetPtr, dwarf::Attribute Attr, dwarf::Form Form, unsigned Indent, DIDumpOptions DumpOpts)
Definition: DWARFDie.cpp:266
static StringRef getName(Value *V)
void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn, uint32_t &CallDiscriminator) const
Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column from DIE (or zeroes if the...
Definition: DWARFDie.cpp:545
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:578
const MCRegisterInfo * getRegisterInfo() const
Definition: DWARFContext.h:341
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:126
uint32_t getOffset() const
Get the absolute offset into the debug info or types section.
Definition: DWARFDie.h:66
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:283
Optional< object::SectionedAddress > toSectionedAddress(const Optional< DWARFFormValue > &V)
bool isDWOUnit() const
Definition: DWARFUnit.h:273
static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val)
Definition: DWARFDie.cpp:39
dwarf::Form getFormByIndex(uint32_t idx) const
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:255
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
llvm::Optional< object::SectionedAddress > getBaseAddress()
Definition: DWARFUnit.cpp:756
static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS, const DWARFAddressRangesVector &Ranges, unsigned AddressSize, unsigned Indent, const DIDumpOptions &DumpOpts)
Definition: DWARFDie.cpp:57
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC, uint64_t &SectionIndex) const
Retrieves DW_AT_low_pc and DW_AT_high_pc from CU.
Definition: DWARFDie.cpp:459
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
uint16_t getVersion() const
Definition: DWARFUnit.h:282
DWARFDie getSibling() const
Get the sibling of this DIE object.
Definition: DWARFDie.cpp:636
StringRef AttributeValueString(uint16_t Attr, unsigned Val)
Returns the symbolic string representing Val when used as a value for attribute Attr.
Definition: Dwarf.cpp:575
uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
Definition: DWARFDie.cpp:541
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
unsigned ParentRecurseDepth
Definition: DIContext.h:160
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:157
raw_ostream & get()
Definition: WithColor.h:64
Optional< uint64_t > toSectionOffset(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
Utility class that carries the DWARF compile/type unit and the debug info entry in an object...
Definition: DWARFDie.h:42
DWARFDie getLastChild() const
Get the last child of this DIE object.
Definition: DWARFDie.cpp:654
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
unsigned const MachineRegisterInfo * MRI
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0&#39;s from the least significant bit to the most stopping at the first 1...
Definition: MathExtras.h:119
virtual uint8_t getAddressSize() const
Definition: DWARFObject.h:34
Instrumentation for Order File
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
bool isSubroutineDIE() const
Returns true if DIE represents a subprogram or an inlined subroutine.
Definition: DWARFDie.cpp:361
static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS, DIDumpOptions DumpOpts, uint64_t SectionIndex)
Optional< DWARFFormValue > findRecursively(ArrayRef< dwarf::Attribute > Attrs) const
Extract the first value of any attribute in Attrs from this DIE and recurse into any DW_AT_specificat...
Definition: DWARFDie.cpp:390
static Optional< LocationList > parseOneLocationList(DataExtractor Data, unsigned *Offset, unsigned Version)
Optional< uint64_t > getAsUnsignedConstant() const
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
DWARFContext & getContext() const
Definition: DWARFUnit.h:274
static DWARFFormValue createFromUValue(dwarf::Form F, uint64_t V)
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn&#39;t already there.
Definition: SmallSet.h:180
Optional< LocationList > parseOneLocationList(DWARFDataExtractor Data, uint32_t *Offset)
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:981
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1206
static void dumpArrayType(raw_ostream &OS, const DWARFDie &D)
Definition: DWARFDie.cpp:148
const T * data() const
Definition: ArrayRef.h:145
unsigned getTag(StringRef TagString)
Definition: Dwarf.cpp:32
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:385
const char * getName(DINameKind Kind) const
Return the DIE name resolving DW_AT_sepcification or DW_AT_abstract_origin references if necessary...
Definition: DWARFDie.cpp:526
Color
A "color", which is either even or odd.
DWARFDie getPreviousSibling() const
Get the previous sibling of this DIE object.
Definition: DWARFDie.cpp:642
uint32_t Offset
The debug info/types offset for this attribute.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:58
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
iterator_range< attribute_iterator > attributes() const
Get an iterator range to all attributes in the current DIE only.
Definition: DWARFDie.cpp:660
Optional< const char * > toString(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
StringRef getLocSectionData() const
Definition: DWARFUnit.h:277
A range adaptor for a pair of iterators.
This file contains constants used for implementing Dwarf debug support.
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
LLVM_DUMP_METHOD void dump() const
Convenience zero-argument overload for debugging.
Definition: DWARFDie.cpp:628
dwarf::Tag getTag() const
Definition: DWARFDie.h:71
#define I(x, y, z)
Definition: MD5.cpp:58
virtual ArrayRef< SectionName > getSectionNames() const
Definition: DWARFObject.h:32
static bool mayHaveLocationDescription(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
Definition: DWARFDie.cpp:706
Expected< DWARFAddressRangesVector > getAddressRanges() const
Get the address ranges for this DIE.
Definition: DWARFDie.cpp:474
unsigned ChildRecurseDepth
Definition: DIContext.h:159
bool isLittleEndian() const
Definition: DWARFContext.h:334
const DWARFObject & getDWARFObj() const
Definition: DWARFContext.h:116
Optional< uint64_t > getHighPC(uint64_t LowPC) const
Get the DW_AT_high_pc attribute value as an address.
Definition: DWARFDie.cpp:445
bool isValidOffset(uint32_t offset) const
Test the validity of offset.
static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent, DIDumpOptions DumpOpts, unsigned Depth=0)
Helper to dump a DIE with all of its parents, but no siblings.
Definition: DWARFDie.cpp:555
dwarf::Attribute getAttrByIndex(uint32_t idx) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition: DWARFDie.cpp:366
std::vector< DWARFAddressRange > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
LLVM Value Representation.
Definition: Value.h:72
DWARFDie getFirstChild() const
Get the first child of this DIE object.
Definition: DWARFDie.cpp:648
static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, DWARFUnit *U, unsigned Indent, DIDumpOptions DumpOpts)
Definition: DWARFDie.cpp:77
static const Function * getParent(const Value *V)
static void dumpTypeName(raw_ostream &OS, const DWARFDie &D)
Recursively dump the DIE type name when applicable.
Definition: DWARFDie.cpp:195
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Optional< uint64_t > getAsSectionOffset() const
Optional< uint32_t > getRnglistOffset(uint32_t Index)
Return a rangelist&#39;s offset based on an index.
Definition: DWARFUnit.h:418
virtual const DWARFSection & getLoclistsSection() const
Definition: DWARFObject.h:41
const char * getSubroutineName(DINameKind Kind) const
If a DIE represents a subprogram (or inlined subroutine), returns its mangled name (or short name...
Definition: DWARFDie.cpp:520
Optional< uint64_t > toUnsigned(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
static void dumpTypeTagName(raw_ostream &OS, dwarf::Tag T)
Dump the name encoded in the type tag.
Definition: DWARFDie.cpp:141
DWARFDie getParent() const
Get the parent of this DIE object.
Definition: DWARFDie.cpp:630