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);
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, BaseAddr,
106  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  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(Form);
282 
283  if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
284  U->getFormParams(), U))
285  return;
286 
287  OS << "\t(";
288 
289  StringRef Name;
290  std::string File;
292  if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
294  if (const auto *LT = U->getContext().getLineTableForUnit(U))
295  if (LT->getFileNameByIndex(
296  formValue.getAsUnsignedConstant().getValue(),
297  U->getCompilationDir(),
299  File = '"' + File + '"';
300  Name = File;
301  }
302  } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
303  Name = AttributeValueString(Attr, *Val);
304 
305  if (!Name.empty())
306  WithColor(OS, Color) << Name;
307  else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
308  OS << *formValue.getAsUnsignedConstant();
309  else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
310  formValue.getAsUnsignedConstant()) {
311  if (DumpOpts.ShowAddresses) {
312  // Print the actual address rather than the offset.
313  uint64_t LowPC, HighPC, Index;
314  if (Die.getLowAndHighPC(LowPC, HighPC, Index))
315  OS << format("0x%016" PRIx64, HighPC);
316  else
317  formValue.dump(OS, DumpOpts);
318  }
319  } else if (Attr == DW_AT_location || Attr == DW_AT_frame_base ||
320  Attr == DW_AT_data_member_location ||
321  Attr == DW_AT_GNU_call_site_value)
322  dumpLocation(OS, formValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
323  else
324  formValue.dump(OS, DumpOpts);
325 
326  std::string Space = DumpOpts.ShowAddresses ? " " : "";
327 
328  // We have dumped the attribute raw value. For some attributes
329  // having both the raw value and the pretty-printed value is
330  // interesting. These attributes are handled below.
331  if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
332  if (const char *Name =
335  OS << Space << "\"" << Name << '\"';
336  } else if (Attr == DW_AT_type) {
337  OS << Space << "\"";
339  OS << '"';
340  } else if (Attr == DW_AT_APPLE_property_attribute) {
341  if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
342  dumpApplePropertyAttribute(OS, *OptVal);
343  } else if (Attr == DW_AT_ranges) {
344  const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj();
345  // For DW_FORM_rnglistx we need to dump the offset separately, since
346  // we have only dumped the index so far.
347  if (formValue.getForm() == DW_FORM_rnglistx)
348  if (auto RangeListOffset =
349  U->getRnglistOffset(*formValue.getAsSectionOffset())) {
350  DWARFFormValue FV(dwarf::DW_FORM_sec_offset);
351  FV.setUValue(*RangeListOffset);
352  FV.dump(OS, DumpOpts);
353  }
354  if (auto RangesOrError = Die.getAddressRanges())
355  dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(),
356  sizeof(BaseIndent) + Indent + 4, DumpOpts);
357  else
358  WithColor::error() << "decoding address ranges: "
359  << toString(RangesOrError.takeError()) << '\n';
360  }
361 
362  OS << ")\n";
363 }
364 
365 bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram; }
366 
368  auto Tag = getTag();
369  return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine;
370 }
371 
373  if (!isValid())
374  return None;
375  auto AbbrevDecl = getAbbreviationDeclarationPtr();
376  if (AbbrevDecl)
377  return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U);
378  return None;
379 }
380 
383  if (!isValid())
384  return None;
385  auto AbbrevDecl = getAbbreviationDeclarationPtr();
386  if (AbbrevDecl) {
387  for (auto Attr : Attrs) {
388  if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U))
389  return Value;
390  }
391  }
392  return None;
393 }
394 
397  std::vector<DWARFDie> Worklist;
398  Worklist.push_back(*this);
399 
400  // Keep track if DIEs already seen to prevent infinite recursion.
401  // Empirically we rarely see a depth of more than 3 when dealing with valid
402  // DWARF. This corresponds to following the DW_AT_abstract_origin and
403  // DW_AT_specification just once.
405 
406  while (!Worklist.empty()) {
407  DWARFDie Die = Worklist.back();
408  Worklist.pop_back();
409 
410  if (!Die.isValid())
411  continue;
412 
413  if (Seen.count(Die))
414  continue;
415 
416  Seen.insert(Die);
417 
418  if (auto Value = Die.find(Attrs))
419  return Value;
420 
421  if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
422  Worklist.push_back(D);
423 
424  if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
425  Worklist.push_back(D);
426  }
427 
428  return None;
429 }
430 
431 DWARFDie
433  if (Optional<DWARFFormValue> F = find(Attr))
434  return getAttributeValueAsReferencedDie(*F);
435  return DWARFDie();
436 }
437 
438 DWARFDie
440  if (auto SpecRef = toReference(V)) {
441  if (auto SpecUnit = U->getUnitVector().getUnitForOffset(*SpecRef))
442  return SpecUnit->getDIEForOffset(*SpecRef);
443  }
444  return DWARFDie();
445 }
446 
448  return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
449 }
450 
452  if (auto FormValue = find(DW_AT_high_pc)) {
453  if (auto Address = FormValue->getAsAddress()) {
454  // High PC is an address.
455  return Address;
456  }
457  if (auto Offset = FormValue->getAsUnsignedConstant()) {
458  // High PC is an offset from LowPC.
459  return LowPC + *Offset;
460  }
461  }
462  return None;
463 }
464 
465 bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
466  uint64_t &SectionIndex) const {
467  auto F = find(DW_AT_low_pc);
468  auto LowPcAddr = toSectionedAddress(F);
469  if (!LowPcAddr)
470  return false;
471  if (auto HighPcAddr = getHighPC(LowPcAddr->Address)) {
472  LowPC = LowPcAddr->Address;
473  HighPC = *HighPcAddr;
474  SectionIndex = LowPcAddr->SectionIndex;
475  return true;
476  }
477  return false;
478 }
479 
481  if (isNULL())
482  return DWARFAddressRangesVector();
483  // Single range specified by low/high PC.
484  uint64_t LowPC, HighPC, Index;
485  if (getLowAndHighPC(LowPC, HighPC, Index))
486  return DWARFAddressRangesVector{{LowPC, HighPC, Index}};
487 
488  Optional<DWARFFormValue> Value = find(DW_AT_ranges);
489  if (Value) {
490  if (Value->getForm() == DW_FORM_rnglistx)
491  return U->findRnglistFromIndex(*Value->getAsSectionOffset());
492  return U->findRnglistFromOffset(*Value->getAsSectionOffset());
493  }
494  return DWARFAddressRangesVector();
495 }
496 
498  DWARFAddressRangesVector &Ranges) const {
499  if (isNULL())
500  return;
501  if (isSubprogramDIE()) {
502  if (auto DIERangesOrError = getAddressRanges())
503  Ranges.insert(Ranges.end(), DIERangesOrError.get().begin(),
504  DIERangesOrError.get().end());
505  else
506  llvm::consumeError(DIERangesOrError.takeError());
507  }
508 
509  for (auto Child : children())
510  Child.collectChildrenAddressRanges(Ranges);
511 }
512 
513 bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
514  auto RangesOrError = getAddressRanges();
515  if (!RangesOrError) {
516  llvm::consumeError(RangesOrError.takeError());
517  return false;
518  }
519 
520  for (const auto &R : RangesOrError.get())
521  if (R.LowPC <= Address && Address < R.HighPC)
522  return true;
523  return false;
524 }
525 
527  if (!isSubroutineDIE())
528  return nullptr;
529  return getName(Kind);
530 }
531 
532 const char *DWARFDie::getName(DINameKind Kind) const {
533  if (!isValid() || Kind == DINameKind::None)
534  return nullptr;
535  // Try to get mangled name only if it was asked for.
536  if (Kind == DINameKind::LinkageName) {
537  if (auto Name = dwarf::toString(
538  findRecursively({DW_AT_MIPS_linkage_name, DW_AT_linkage_name}),
539  nullptr))
540  return Name;
541  }
542  if (auto Name = dwarf::toString(findRecursively(DW_AT_name), nullptr))
543  return Name;
544  return nullptr;
545 }
546 
547 uint64_t DWARFDie::getDeclLine() const {
548  return toUnsigned(findRecursively(DW_AT_decl_line), 0);
549 }
550 
551 void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
552  uint32_t &CallColumn,
553  uint32_t &CallDiscriminator) const {
554  CallFile = toUnsigned(find(DW_AT_call_file), 0);
555  CallLine = toUnsigned(find(DW_AT_call_line), 0);
556  CallColumn = toUnsigned(find(DW_AT_call_column), 0);
557  CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0);
558 }
559 
560 /// Helper to dump a DIE with all of its parents, but no siblings.
561 static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent,
562  DIDumpOptions DumpOpts) {
563  if (!Die)
564  return Indent;
565  Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts);
566  Die.dump(OS, Indent, DumpOpts);
567  return Indent + 2;
568 }
569 
570 void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
571  DIDumpOptions DumpOpts) const {
572  if (!isValid())
573  return;
574  DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
575  const uint32_t Offset = getOffset();
576  uint32_t offset = Offset;
577  if (DumpOpts.ShowParents) {
578  DIDumpOptions ParentDumpOpts = DumpOpts;
579  ParentDumpOpts.ShowParents = false;
580  ParentDumpOpts.ShowChildren = false;
581  Indent = dumpParentChain(getParent(), OS, Indent, ParentDumpOpts);
582  }
583 
584  if (debug_info_data.isValidOffset(offset)) {
585  uint32_t abbrCode = debug_info_data.getULEB128(&offset);
586  if (DumpOpts.ShowAddresses)
588  << format("\n0x%8.8x: ", Offset);
589 
590  if (abbrCode) {
591  auto AbbrevDecl = getAbbreviationDeclarationPtr();
592  if (AbbrevDecl) {
593  WithColor(OS, HighlightColor::Tag).get().indent(Indent)
594  << formatv("{0}", getTag());
595  if (DumpOpts.Verbose)
596  OS << format(" [%u] %c", abbrCode,
597  AbbrevDecl->hasChildren() ? '*' : ' ');
598  OS << '\n';
599 
600  // Dump all data in the DIE for the attributes.
601  for (const auto &AttrSpec : AbbrevDecl->attributes()) {
602  if (AttrSpec.Form == DW_FORM_implicit_const) {
603  // We are dumping .debug_info section ,
604  // implicit_const attribute values are not really stored here,
605  // but in .debug_abbrev section. So we just skip such attrs.
606  continue;
607  }
608  dumpAttribute(OS, *this, &offset, AttrSpec.Attr, AttrSpec.Form,
609  Indent, DumpOpts);
610  }
611 
612  DWARFDie child = getFirstChild();
613  if (DumpOpts.ShowChildren && DumpOpts.RecurseDepth > 0 && child) {
614  DumpOpts.RecurseDepth--;
615  DIDumpOptions ChildDumpOpts = DumpOpts;
616  ChildDumpOpts.ShowParents = false;
617  while (child) {
618  child.dump(OS, Indent + 2, ChildDumpOpts);
619  child = child.getSibling();
620  }
621  }
622  } else {
623  OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
624  << abbrCode << '\n';
625  }
626  } else {
627  OS.indent(Indent) << "NULL\n";
628  }
629  }
630 }
631 
633 
635  if (isValid())
636  return U->getParent(Die);
637  return DWARFDie();
638 }
639 
641  if (isValid())
642  return U->getSibling(Die);
643  return DWARFDie();
644 }
645 
647  if (isValid())
648  return U->getPreviousSibling(Die);
649  return DWARFDie();
650 }
651 
653  if (isValid())
654  return U->getFirstChild(Die);
655  return DWARFDie();
656 }
657 
659  if (isValid())
660  return U->getLastChild(Die);
661  return DWARFDie();
662 }
663 
665  return make_range(attribute_iterator(*this, false),
666  attribute_iterator(*this, true));
667 }
668 
670  : Die(D), AttrValue(0), Index(0) {
671  auto AbbrDecl = Die.getAbbreviationDeclarationPtr();
672  assert(AbbrDecl && "Must have abbreviation declaration");
673  if (End) {
674  // This is the end iterator so we set the index to the attribute count.
675  Index = AbbrDecl->getNumAttributes();
676  } else {
677  // This is the begin iterator so we extract the value for this->Index.
678  AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize();
679  updateForIndex(*AbbrDecl, 0);
680  }
681 }
682 
683 void DWARFDie::attribute_iterator::updateForIndex(
684  const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) {
685  Index = I;
686  // AbbrDecl must be valid before calling this function.
687  auto NumAttrs = AbbrDecl.getNumAttributes();
688  if (Index < NumAttrs) {
689  AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
690  // Add the previous byte size of any previous attribute value.
691  AttrValue.Offset += AttrValue.ByteSize;
692  AttrValue.Value.setForm(AbbrDecl.getFormByIndex(Index));
693  uint32_t ParseOffset = AttrValue.Offset;
694  auto U = Die.getDwarfUnit();
695  assert(U && "Die must have valid DWARF unit");
696  bool b = AttrValue.Value.extractValue(U->getDebugInfoExtractor(),
697  &ParseOffset, U->getFormParams(), U);
698  (void)b;
699  assert(b && "extractValue cannot fail on fully parsed DWARF");
700  AttrValue.ByteSize = ParseOffset - AttrValue.Offset;
701  } else {
702  assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only");
703  AttrValue.clear();
704  }
705 }
706 
708  if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr())
709  updateForIndex(*AbbrDecl, Index + 1);
710  return *this;
711 }
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:498
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
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:464
bool isSubprogramDIE() const
Returns true if DIE represents a subprogram (not inlined).
Definition: DWARFDie.cpp:365
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:513
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:707
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:497
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:272
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.
static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent, DIDumpOptions DumpOpts)
Helper to dump a DIE with all of its parents, but no siblings.
Definition: DWARFDie.cpp:561
void setUValue(uint64_t V)
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:432
A debug info location.
Definition: DebugLoc.h:33
F(f)
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
Definition: DIContext.h:118
Optional< unsigned > LanguageLowerBound(SourceLanguage L)
Definition: Dwarf.cpp:340
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:570
const dwarf::FormParams & getFormParams() const
Definition: DWARFUnit.h:275
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:341
Optional< uint64_t > getRangesBaseAttribute() const
Extract the range base attribute from this DIE as absolute section offset.
Definition: DWARFDie.cpp:447
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:551
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:336
void setForm(dwarf::Form F)
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:279
bool isDWOUnit() const
Definition: DWARFUnit.h:269
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:162
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
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:465
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
uint16_t getVersion() const
Definition: DWARFUnit.h:278
DWARFDie getSibling() const
Get the sibling of this DIE object.
Definition: DWARFDie.cpp:640
StringRef AttributeValueString(uint16_t Attr, unsigned Val)
Returns the symbolic string representing Val when used as a value for attribute Attr.
Definition: Dwarf.cpp:572
uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
Definition: DWARFDie.cpp:547
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:158
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
Optional< uint64_t > toReference(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an reference.
DWARFDie getLastChild() const
Get the last child of this DIE object.
Definition: DWARFDie.cpp:658
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
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:367
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:396
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:270
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:380
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:532
Color
A "color", which is either even or odd.
DWARFDie getPreviousSibling() const
Get the previous sibling of this DIE object.
Definition: DWARFDie.cpp:646
Definition: JSON.cpp:600
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:664
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:273
A range adaptor for a pair of iterators.
This file contains constants used for implementing Dwarf debug support.
DWARFDataExtractor getDebugInfoExtractor() const
Definition: DWARFUnit.cpp:195
unsigned RecurseDepth
Definition: DIContext.h:160
bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, dwarf::FormParams FormParams, const DWARFContext *Context=nullptr, const DWARFUnit *Unit=nullptr)
Extracts a value in Data at offset *OffsetPtr.
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
LLVM_DUMP_METHOD void dump() const
Convenience zero-argument overload for debugging.
Definition: DWARFDie.cpp:632
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
Expected< DWARFAddressRangesVector > getAddressRanges() const
Get the address ranges for this DIE.
Definition: DWARFDie.cpp:480
bool isLittleEndian() const
Definition: DWARFContext.h:329
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:451
bool isValidOffset(uint32_t offset) const
Test the validity of offset.
llvm::Optional< SectionedAddress > getBaseAddress()
Definition: DWARFUnit.cpp:747
const unsigned Kind
dwarf::Attribute getAttrByIndex(uint32_t idx) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Definition: JSON.cpp:597
Optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition: DWARFDie.cpp:372
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:652
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:406
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:526
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:634
Optional< SectionedAddress > toSectionedAddress(const Optional< DWARFFormValue > &V)
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition: SmallSet.h:164