LLVM  14.0.0git
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"
27 #include "llvm/Support/WithColor.h"
29 #include <algorithm>
30 #include <cassert>
31 #include <cinttypes>
32 #include <cstdint>
33 #include <string>
34 #include <utility>
35 
36 using namespace llvm;
37 using namespace dwarf;
38 using namespace object;
39 
41  OS << " (";
42  do {
44  assert(Shift < 64 && "undefined behavior");
45  uint64_t Bit = 1ULL << Shift;
46  auto PropName = ApplePropertyString(Bit);
47  if (!PropName.empty())
48  OS << PropName;
49  else
50  OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit);
51  if (!(Val ^= Bit))
52  break;
53  OS << ", ";
54  } while (true);
55  OS << ")";
56 }
57 
58 static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS,
59  const DWARFAddressRangesVector &Ranges,
60  unsigned AddressSize, unsigned Indent,
61  const DIDumpOptions &DumpOpts) {
62  if (!DumpOpts.ShowAddresses)
63  return;
64 
65  for (const DWARFAddressRange &R : Ranges) {
66  OS << '\n';
67  OS.indent(Indent);
68  R.dump(OS, AddressSize, DumpOpts, &Obj);
69  }
70 }
71 
72 static void dumpLocationList(raw_ostream &OS, const DWARFFormValue &FormValue,
73  DWARFUnit *U, unsigned Indent,
74  DIDumpOptions DumpOpts) {
76  "bad FORM for location list");
77  DWARFContext &Ctx = U->getContext();
78  const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
79  uint64_t Offset = *FormValue.getAsSectionOffset();
80 
81  if (FormValue.getForm() == DW_FORM_loclistx) {
82  FormValue.dump(OS, DumpOpts);
83 
84  if (auto LoclistOffset = U->getLoclistOffset(Offset))
85  Offset = *LoclistOffset;
86  else
87  return;
88  }
90  Ctx.getDWARFObj(), U, DumpOpts,
91  Indent);
92  return;
93 }
94 
95 static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
96  DWARFUnit *U, unsigned Indent,
97  DIDumpOptions DumpOpts) {
100  "bad FORM for location expression");
101  DWARFContext &Ctx = U->getContext();
102  const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
103  ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
104  DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
105  Ctx.isLittleEndian(), 0);
107  .print(OS, DumpOpts, MRI, U);
108  return;
109 }
110 
111 namespace {
112 
113 // FIXME: We should have pretty printers per language. Currently we print
114 // everything as if it was C++ and fall back to the TAG type name.
115 struct DWARFTypePrinter {
116  raw_ostream &OS;
117  bool Word = true;
118  bool EndedWithTemplate = false;
119 
120  DWARFTypePrinter(raw_ostream &OS) : OS(OS) {}
121 
122  /// Dump the name encoded in the type tag.
123  void appendTypeTagName(dwarf::Tag T) {
124  StringRef TagStr = TagString(T);
125  static constexpr StringRef Prefix = "DW_TAG_";
126  static constexpr StringRef Suffix = "_type";
127  if (!TagStr.startswith(Prefix) || !TagStr.endswith(Suffix))
128  return;
129  OS << TagStr.substr(Prefix.size(),
130  TagStr.size() - (Prefix.size() + Suffix.size()))
131  << " ";
132  }
133 
134  void appendArrayType(const DWARFDie &D) {
135  for (const DWARFDie &C : D.children()) {
136  if (C.getTag() != DW_TAG_subrange_type)
137  continue;
139  Optional<uint64_t> Count;
141  Optional<unsigned> DefaultLB;
142  if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
143  LB = L->getAsUnsignedConstant();
144  if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
145  Count = CountV->getAsUnsignedConstant();
146  if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
147  UB = UpperV->getAsUnsignedConstant();
148  if (Optional<DWARFFormValue> LV =
149  D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
150  if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
151  if ((DefaultLB =
152  LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
153  if (LB && *LB == *DefaultLB)
154  LB = None;
155  if (!LB && !Count && !UB)
156  OS << "[]";
157  else if (!LB && (Count || UB) && DefaultLB)
158  OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
159  else {
160  OS << "[[";
161  if (LB)
162  OS << *LB;
163  else
164  OS << '?';
165  OS << ", ";
166  if (Count)
167  if (LB)
168  OS << *LB + *Count;
169  else
170  OS << "? + " << *Count;
171  else if (UB)
172  OS << *UB + 1;
173  else
174  OS << '?';
175  OS << ")]";
176  }
177  }
178  }
179 
180  DWARFDie skipQualifiers(DWARFDie D) {
181  while (D && (D.getTag() == DW_TAG_const_type ||
182  D.getTag() == DW_TAG_volatile_type))
183  D = D.getAttributeValueAsReferencedDie(DW_AT_type);
184  return D;
185  }
186 
187  bool needsParens(DWARFDie D) {
188  D = skipQualifiers(D);
189  return D && (D.getTag() == DW_TAG_subroutine_type || D.getTag() == DW_TAG_array_type);
190  }
191 
192  void appendPointerLikeTypeBefore(DWARFDie D, DWARFDie Inner, StringRef Ptr) {
193  appendQualifiedNameBefore(Inner);
194  if (Word)
195  OS << ' ';
196  if (needsParens(Inner))
197  OS << '(';
198  OS << Ptr;
199  Word = false;
200  }
201 
202  DWARFDie appendUnqualifiedNameBefore(DWARFDie D) {
203  Word = true;
204  if (!D) {
205  OS << "void";
206  return DWARFDie();
207  }
208  DWARFDie Inner = D.getAttributeValueAsReferencedDie(DW_AT_type);
209  const dwarf::Tag T = D.getTag();
210  switch (T) {
211  case DW_TAG_pointer_type: {
212  appendPointerLikeTypeBefore(D, Inner, "*");
213  break;
214  }
215  case DW_TAG_subroutine_type: {
216  appendQualifiedNameBefore(Inner);
217  if (Word) {
218  OS << ' ';
219  }
220  Word = false;
221  break;
222  }
223  case DW_TAG_array_type: {
224  appendQualifiedNameBefore(Inner);
225  if (Word)
226  OS << ' ';
227  Word = false;
228  break;
229  }
230  case DW_TAG_reference_type:
231  appendPointerLikeTypeBefore(D, Inner, "&");
232  break;
233  case DW_TAG_rvalue_reference_type:
234  appendPointerLikeTypeBefore(D, Inner, "&&");
235  break;
236  case DW_TAG_ptr_to_member_type: {
237  appendQualifiedNameBefore(Inner);
238  if (needsParens(Inner))
239  OS << '(';
240  else if (Word)
241  OS << ' ';
242  if (DWARFDie Cont =
243  D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
244  appendQualifiedName(Cont);
245  OS << "::";
246  }
247  OS << "*";
248  Word = false;
249  break;
250  }
251  case DW_TAG_const_type:
252  case DW_TAG_volatile_type:
253  appendConstVolatileQualifierBefore(D);
254  break;
255  case DW_TAG_namespace: {
256  if (const char *Name = dwarf::toString(D.find(DW_AT_name), nullptr))
257  OS << Name;
258  else
259  OS << "(anonymous namespace)";
260  break;
261  }
262  case DW_TAG_unspecified_type: {
263  StringRef TypeName = D.getShortName();
264  if (TypeName == "decltype(nullptr)")
265  TypeName = "std::nullptr_t";
266  Word = true;
267  OS << TypeName;
268  EndedWithTemplate = false;
269  break;
270  }
271  default:
272  const char *NamePtr = dwarf::toString(D.find(DW_AT_name), nullptr);
273  if (!NamePtr) {
274  appendTypeTagName(D.getTag());
275  break;
276  }
277  OS << NamePtr;
278  break;
279  }
280  return Inner;
281  }
282 
283  void appendUnqualifiedNameAfter(DWARFDie D, DWARFDie Inner,
284  bool SkipFirstParamIfArtificial = false) {
285  if (!D)
286  return;
287  switch (D.getTag()) {
288  case DW_TAG_subroutine_type: {
289  appendSubroutineNameAfter(D, Inner, SkipFirstParamIfArtificial, false,
290  false);
291  break;
292  }
293  case DW_TAG_array_type: {
294  appendArrayType(D);
295  break;
296  }
297  case DW_TAG_const_type:
298  case DW_TAG_volatile_type:
299  appendConstVolatileQualifierAfter(D);
300  break;
301  case DW_TAG_ptr_to_member_type:
302  case DW_TAG_reference_type:
303  case DW_TAG_rvalue_reference_type:
304  case DW_TAG_pointer_type: {
305  if (needsParens(Inner))
306  OS << ')';
307  appendUnqualifiedNameAfter(
308  Inner, Inner.getAttributeValueAsReferencedDie(DW_AT_type),
309  /*SkipFirstParamIfArtificial=*/D.getTag() ==
310  DW_TAG_ptr_to_member_type);
311  break;
312  }
313  default:
314  break;
315  }
316  }
317 
318  void appendQualifiedName(DWARFDie D) {
319  if (D)
320  appendScopes(D.getParent());
321  appendUnqualifiedName(D);
322  }
323  DWARFDie appendQualifiedNameBefore(DWARFDie D) {
324  if (D)
325  appendScopes(D.getParent());
326  return appendUnqualifiedNameBefore(D);
327  }
328  void decomposeConstVolatile(DWARFDie &N, DWARFDie &T, DWARFDie &C,
329  DWARFDie &V) {
330  (N.getTag() == DW_TAG_const_type ? C : V) = N;
331  T = N.getAttributeValueAsReferencedDie(DW_AT_type);
332  if (T) {
333  auto Tag = T.getTag();
334  if (Tag == DW_TAG_const_type) {
335  C = T;
336  T = T.getAttributeValueAsReferencedDie(DW_AT_type);
337  } else if (Tag == DW_TAG_volatile_type) {
338  V = T;
339  T = T.getAttributeValueAsReferencedDie(DW_AT_type);
340  }
341  }
342  }
343  void appendConstVolatileQualifierAfter(DWARFDie N) {
344  DWARFDie C;
345  DWARFDie V;
346  DWARFDie T;
347  decomposeConstVolatile(N, T, C, V);
348  if (T && T.getTag() == DW_TAG_subroutine_type)
349  appendSubroutineNameAfter(T,
350  T.getAttributeValueAsReferencedDie(DW_AT_type),
351  false, C.isValid(), V.isValid());
352  else
353  appendUnqualifiedNameAfter(
354  T, T.getAttributeValueAsReferencedDie(DW_AT_type));
355  }
356  void appendConstVolatileQualifierBefore(DWARFDie N) {
357  DWARFDie C;
358  DWARFDie V;
359  DWARFDie T;
360  decomposeConstVolatile(N, T, C, V);
361  bool Subroutine = T && T.getTag() == DW_TAG_subroutine_type;
362  DWARFDie A = T;
363  while (A && A.getTag() == DW_TAG_array_type)
364  A = A.getAttributeValueAsReferencedDie(DW_AT_type);
365  bool Leading =
366  (!A || (A.getTag() != DW_TAG_pointer_type &&
367  A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
368  !Subroutine;
369  if (Leading) {
370  if (C)
371  OS << "const ";
372  if (V)
373  OS << "volatile ";
374  }
375  appendQualifiedNameBefore(T);
376  if (!Leading && !Subroutine) {
377  Word = true;
378  if (C)
379  OS << "const";
380  if (V) {
381  if (C)
382  OS << ' ';
383  OS << "volatile";
384  }
385  }
386  }
387 
388  /// Recursively append the DIE type name when applicable.
389  void appendUnqualifiedName(const DWARFDie &D) {
390  // FIXME: We should have pretty printers per language. Currently we print
391  // everything as if it was C++ and fall back to the TAG type name.
392  DWARFDie Inner = appendUnqualifiedNameBefore(D);
393  appendUnqualifiedNameAfter(D, Inner);
394  }
395 
396  void appendSubroutineNameAfter(DWARFDie D, DWARFDie Inner,
397  bool SkipFirstParamIfArtificial, bool Const,
398  bool Volatile) {
399  DWARFDie FirstParamIfArtificial;
400  OS << '(';
401  EndedWithTemplate = false;
402  bool First = true;
403  bool RealFirst = true;
404  for (DWARFDie P : D) {
405  if (P.getTag() != DW_TAG_formal_parameter)
406  return;
407  DWARFDie T = P.getAttributeValueAsReferencedDie(DW_AT_type);
408  if (SkipFirstParamIfArtificial && RealFirst && P.find(DW_AT_artificial)) {
409  FirstParamIfArtificial = T;
410  RealFirst = false;
411  continue;
412  }
413  if (!First) {
414  OS << ", ";
415  }
416  First = false;
417  appendQualifiedName(T);
418  }
419  EndedWithTemplate = false;
420  OS << ')';
421  if (FirstParamIfArtificial) {
422  if (DWARFDie P = FirstParamIfArtificial) {
423  if (P.getTag() == DW_TAG_pointer_type) {
424  DWARFDie C;
425  DWARFDie V;
426  auto CVStep = [&](DWARFDie CV) {
427  if (DWARFDie U = CV.getAttributeValueAsReferencedDie(DW_AT_type)) {
428  if (U.getTag() == DW_TAG_const_type)
429  return C = U;
430  if (U.getTag() == DW_TAG_volatile_type)
431  return V = U;
432  }
433  return DWARFDie();
434  };
435  if (DWARFDie CV = CVStep(P)) {
436  CVStep(CV);
437  }
438  if (C)
439  OS << " const";
440  if (V)
441  OS << " volatile";
442  }
443  }
444  } else {
445  if (Const)
446  OS << " const";
447  if (Volatile)
448  OS << " volatile";
449  }
450  if (D.find(DW_AT_reference))
451  OS << " &";
452  if (D.find(DW_AT_rvalue_reference))
453  OS << " &&";
454  appendUnqualifiedNameAfter(
455  Inner, Inner.getAttributeValueAsReferencedDie(DW_AT_type));
456  }
457  void appendScopes(DWARFDie D) {
458  if (D.getTag() == DW_TAG_compile_unit)
459  return;
460  if (D.getTag() == DW_TAG_type_unit)
461  return;
462  if (D.getTag() == llvm::dwarf::DW_TAG_skeleton_unit)
463  return;
464  if (D.getTag() == DW_TAG_subprogram)
465  return;
466  if (DWARFDie P = D.getParent())
467  appendScopes(P);
468  appendUnqualifiedName(D);
469  OS << "::";
470  }
471 };
472 } // anonymous namespace
473 
474 static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
475  const DWARFAttribute &AttrValue, unsigned Indent,
476  DIDumpOptions DumpOpts) {
477  if (!Die.isValid())
478  return;
479  const char BaseIndent[] = " ";
480  OS << BaseIndent;
481  OS.indent(Indent + 2);
482  dwarf::Attribute Attr = AttrValue.Attr;
483  WithColor(OS, HighlightColor::Attribute) << formatv("{0}", Attr);
484 
485  dwarf::Form Form = AttrValue.Value.getForm();
486  if (DumpOpts.Verbose || DumpOpts.ShowForm)
487  OS << formatv(" [{0}]", Form);
488 
489  DWARFUnit *U = Die.getDwarfUnit();
490  const DWARFFormValue &FormValue = AttrValue.Value;
491 
492  OS << "\t(";
493 
494  StringRef Name;
495  std::string File;
496  auto Color = HighlightColor::Enumerator;
497  if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
498  Color = HighlightColor::String;
499  if (const auto *LT = U->getContext().getLineTableForUnit(U))
500  if (LT->getFileNameByIndex(
501  FormValue.getAsUnsignedConstant().getValue(),
502  U->getCompilationDir(),
504  File = '"' + File + '"';
505  Name = File;
506  }
507  } else if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant())
508  Name = AttributeValueString(Attr, *Val);
509 
510  if (!Name.empty())
511  WithColor(OS, Color) << Name;
512  else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
513  OS << *FormValue.getAsUnsignedConstant();
514  else if (Attr == DW_AT_low_pc &&
515  (FormValue.getAsAddress() ==
517  if (DumpOpts.Verbose) {
518  FormValue.dump(OS, DumpOpts);
519  OS << " (";
520  }
521  OS << "dead code";
522  if (DumpOpts.Verbose)
523  OS << ')';
524  } else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
525  FormValue.getAsUnsignedConstant()) {
526  if (DumpOpts.ShowAddresses) {
527  // Print the actual address rather than the offset.
528  uint64_t LowPC, HighPC, Index;
529  if (Die.getLowAndHighPC(LowPC, HighPC, Index))
531  else
532  FormValue.dump(OS, DumpOpts);
533  }
534  } else if (DWARFAttribute::mayHaveLocationList(Attr) &&
536  dumpLocationList(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4,
537  DumpOpts);
538  else if (FormValue.isFormClass(DWARFFormValue::FC_Exprloc) ||
541  dumpLocationExpr(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4,
542  DumpOpts);
543  else
544  FormValue.dump(OS, DumpOpts);
545 
546  std::string Space = DumpOpts.ShowAddresses ? " " : "";
547 
548  // We have dumped the attribute raw value. For some attributes
549  // having both the raw value and the pretty-printed value is
550  // interesting. These attributes are handled below.
551  if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
552  if (const char *Name =
555  OS << Space << "\"" << Name << '\"';
556  } else if (Attr == DW_AT_type) {
558  if (D && !D.isNULL()) {
559  OS << Space << "\"";
560  DWARFTypePrinter(OS).appendQualifiedName(D);
561  OS << '"';
562  }
563  } else if (Attr == DW_AT_APPLE_property_attribute) {
564  if (Optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant())
565  dumpApplePropertyAttribute(OS, *OptVal);
566  } else if (Attr == DW_AT_ranges) {
567  const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj();
568  // For DW_FORM_rnglistx we need to dump the offset separately, since
569  // we have only dumped the index so far.
570  if (FormValue.getForm() == DW_FORM_rnglistx)
571  if (auto RangeListOffset =
572  U->getRnglistOffset(*FormValue.getAsSectionOffset())) {
574  dwarf::DW_FORM_sec_offset, *RangeListOffset);
575  FV.dump(OS, DumpOpts);
576  }
577  if (auto RangesOrError = Die.getAddressRanges())
578  dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(),
579  sizeof(BaseIndent) + Indent + 4, DumpOpts);
580  else
582  errc::invalid_argument, "decoding address ranges: %s",
583  toString(RangesOrError.takeError()).c_str()));
584  }
585 
586  OS << ")\n";
587 }
588 
589 bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram; }
590 
592  auto Tag = getTag();
593  return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine;
594 }
595 
597  if (!isValid())
598  return None;
599  auto AbbrevDecl = getAbbreviationDeclarationPtr();
600  if (AbbrevDecl)
601  return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U);
602  return None;
603 }
604 
607  if (!isValid())
608  return None;
609  auto AbbrevDecl = getAbbreviationDeclarationPtr();
610  if (AbbrevDecl) {
611  for (auto Attr : Attrs) {
612  if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U))
613  return Value;
614  }
615  }
616  return None;
617 }
618 
621  SmallVector<DWARFDie, 3> Worklist;
622  Worklist.push_back(*this);
623 
624  // Keep track if DIEs already seen to prevent infinite recursion.
625  // Empirically we rarely see a depth of more than 3 when dealing with valid
626  // DWARF. This corresponds to following the DW_AT_abstract_origin and
627  // DW_AT_specification just once.
629  Seen.insert(*this);
630 
631  while (!Worklist.empty()) {
632  DWARFDie Die = Worklist.pop_back_val();
633 
634  if (!Die.isValid())
635  continue;
636 
637  if (auto Value = Die.find(Attrs))
638  return Value;
639 
640  if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
641  if (Seen.insert(D).second)
642  Worklist.push_back(D);
643 
644  if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
645  if (Seen.insert(D).second)
646  Worklist.push_back(D);
647  }
648 
649  return None;
650 }
651 
652 DWARFDie
654  if (Optional<DWARFFormValue> F = find(Attr))
655  return getAttributeValueAsReferencedDie(*F);
656  return DWARFDie();
657 }
658 
659 DWARFDie
661  if (auto SpecRef = V.getAsRelativeReference()) {
662  if (SpecRef->Unit)
663  return SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() + SpecRef->Offset);
664  if (auto SpecUnit = U->getUnitVector().getUnitForOffset(SpecRef->Offset))
665  return SpecUnit->getDIEForOffset(SpecRef->Offset);
666  }
667  return DWARFDie();
668 }
669 
671  return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
672 }
673 
675  return toSectionOffset(find(DW_AT_loclists_base));
676 }
677 
679  uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize());
680  if (LowPC == Tombstone)
681  return None;
682  if (auto FormValue = find(DW_AT_high_pc)) {
683  if (auto Address = FormValue->getAsAddress()) {
684  // High PC is an address.
685  return Address;
686  }
687  if (auto Offset = FormValue->getAsUnsignedConstant()) {
688  // High PC is an offset from LowPC.
689  return LowPC + *Offset;
690  }
691  }
692  return None;
693 }
694 
696  uint64_t &SectionIndex) const {
697  auto F = find(DW_AT_low_pc);
698  auto LowPcAddr = toSectionedAddress(F);
699  if (!LowPcAddr)
700  return false;
701  if (auto HighPcAddr = getHighPC(LowPcAddr->Address)) {
702  LowPC = LowPcAddr->Address;
703  HighPC = *HighPcAddr;
704  SectionIndex = LowPcAddr->SectionIndex;
705  return true;
706  }
707  return false;
708 }
709 
711  if (isNULL())
712  return DWARFAddressRangesVector();
713  // Single range specified by low/high PC.
714  uint64_t LowPC, HighPC, Index;
715  if (getLowAndHighPC(LowPC, HighPC, Index))
716  return DWARFAddressRangesVector{{LowPC, HighPC, Index}};
717 
718  Optional<DWARFFormValue> Value = find(DW_AT_ranges);
719  if (Value) {
720  if (Value->getForm() == DW_FORM_rnglistx)
721  return U->findRnglistFromIndex(*Value->getAsSectionOffset());
722  return U->findRnglistFromOffset(*Value->getAsSectionOffset());
723  }
724  return DWARFAddressRangesVector();
725 }
726 
728  auto RangesOrError = getAddressRanges();
729  if (!RangesOrError) {
730  llvm::consumeError(RangesOrError.takeError());
731  return false;
732  }
733 
734  for (const auto &R : RangesOrError.get())
735  if (R.LowPC <= Address && Address < R.HighPC)
736  return true;
737  return false;
738 }
739 
742  Optional<DWARFFormValue> Location = find(Attr);
743  if (!Location)
744  return createStringError(inconvertibleErrorCode(), "No %s",
745  dwarf::AttributeString(Attr).data());
746 
747  if (Optional<uint64_t> Off = Location->getAsSectionOffset()) {
748  uint64_t Offset = *Off;
749 
750  if (Location->getForm() == DW_FORM_loclistx) {
751  if (auto LoclistOffset = U->getLoclistOffset(Offset))
752  Offset = *LoclistOffset;
753  else
755  "Loclist table not found");
756  }
757  return U->findLoclistFromOffset(Offset);
758  }
759 
760  if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
762  DWARFLocationExpression{None, to_vector<4>(*Expr)}};
763  }
764 
765  return createStringError(
766  inconvertibleErrorCode(), "Unsupported %s encoding: %s",
767  dwarf::AttributeString(Attr).data(),
768  dwarf::FormEncodingString(Location->getForm()).data());
769 }
770 
772  if (!isSubroutineDIE())
773  return nullptr;
774  return getName(Kind);
775 }
776 
777 const char *DWARFDie::getName(DINameKind Kind) const {
778  if (!isValid() || Kind == DINameKind::None)
779  return nullptr;
780  // Try to get mangled name only if it was asked for.
781  if (Kind == DINameKind::LinkageName) {
782  if (auto Name = getLinkageName())
783  return Name;
784  }
785  return getShortName();
786 }
787 
788 const char *DWARFDie::getShortName() const {
789  if (!isValid())
790  return nullptr;
791 
792  return dwarf::toString(findRecursively(dwarf::DW_AT_name), nullptr);
793 }
794 
795 const char *DWARFDie::getLinkageName() const {
796  if (!isValid())
797  return nullptr;
798 
799  return dwarf::toString(findRecursively({dwarf::DW_AT_MIPS_linkage_name,
800  dwarf::DW_AT_linkage_name}),
801  nullptr);
802 }
803 
805  return toUnsigned(findRecursively(DW_AT_decl_line), 0);
806 }
807 
808 std::string
810  if (auto FormValue = findRecursively(DW_AT_decl_file))
811  if (auto OptString = FormValue->getAsFile(Kind))
812  return *OptString;
813  return {};
814 }
815 
816 void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
817  uint32_t &CallColumn,
818  uint32_t &CallDiscriminator) const {
819  CallFile = toUnsigned(find(DW_AT_call_file), 0);
820  CallLine = toUnsigned(find(DW_AT_call_line), 0);
821  CallColumn = toUnsigned(find(DW_AT_call_column), 0);
822  CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0);
823 }
824 
825 /// Helper to dump a DIE with all of its parents, but no siblings.
826 static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent,
827  DIDumpOptions DumpOpts, unsigned Depth = 0) {
828  if (!Die)
829  return Indent;
830  if (DumpOpts.ParentRecurseDepth > 0 && Depth >= DumpOpts.ParentRecurseDepth)
831  return Indent;
832  Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts, Depth + 1);
833  Die.dump(OS, Indent, DumpOpts);
834  return Indent + 2;
835 }
836 
837 void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
838  DIDumpOptions DumpOpts) const {
839  if (!isValid())
840  return;
841  DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
842  const uint64_t Offset = getOffset();
843  uint64_t offset = Offset;
844  if (DumpOpts.ShowParents) {
845  DIDumpOptions ParentDumpOpts = DumpOpts;
846  ParentDumpOpts.ShowParents = false;
847  ParentDumpOpts.ShowChildren = false;
848  Indent = dumpParentChain(getParent(), OS, Indent, ParentDumpOpts);
849  }
850 
851  if (debug_info_data.isValidOffset(offset)) {
852  uint32_t abbrCode = debug_info_data.getULEB128(&offset);
853  if (DumpOpts.ShowAddresses)
855  << format("\n0x%8.8" PRIx64 ": ", Offset);
856 
857  if (abbrCode) {
858  auto AbbrevDecl = getAbbreviationDeclarationPtr();
859  if (AbbrevDecl) {
860  WithColor(OS, HighlightColor::Tag).get().indent(Indent)
861  << formatv("{0}", getTag());
862  if (DumpOpts.Verbose)
863  OS << format(" [%u] %c", abbrCode,
864  AbbrevDecl->hasChildren() ? '*' : ' ');
865  OS << '\n';
866 
867  // Dump all data in the DIE for the attributes.
868  for (const DWARFAttribute &AttrValue : attributes())
869  dumpAttribute(OS, *this, AttrValue, Indent, DumpOpts);
870 
871  if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0) {
872  DWARFDie Child = getFirstChild();
873  DumpOpts.ChildRecurseDepth--;
874  DIDumpOptions ChildDumpOpts = DumpOpts;
875  ChildDumpOpts.ShowParents = false;
876  while (Child) {
877  Child.dump(OS, Indent + 2, ChildDumpOpts);
878  Child = Child.getSibling();
879  }
880  }
881  } else {
882  OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
883  << abbrCode << '\n';
884  }
885  } else {
886  OS.indent(Indent) << "NULL\n";
887  }
888  }
889 }
890 
892 
894  if (isValid())
895  return U->getParent(Die);
896  return DWARFDie();
897 }
898 
900  if (isValid())
901  return U->getSibling(Die);
902  return DWARFDie();
903 }
904 
906  if (isValid())
907  return U->getPreviousSibling(Die);
908  return DWARFDie();
909 }
910 
912  if (isValid())
913  return U->getFirstChild(Die);
914  return DWARFDie();
915 }
916 
918  if (isValid())
919  return U->getLastChild(Die);
920  return DWARFDie();
921 }
922 
924  return make_range(attribute_iterator(*this, false),
925  attribute_iterator(*this, true));
926 }
927 
929  : Die(D), Index(0) {
930  auto AbbrDecl = Die.getAbbreviationDeclarationPtr();
931  assert(AbbrDecl && "Must have abbreviation declaration");
932  if (End) {
933  // This is the end iterator so we set the index to the attribute count.
934  Index = AbbrDecl->getNumAttributes();
935  } else {
936  // This is the begin iterator so we extract the value for this->Index.
937  AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize();
938  updateForIndex(*AbbrDecl, 0);
939  }
940 }
941 
942 void DWARFDie::attribute_iterator::updateForIndex(
943  const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) {
944  Index = I;
945  // AbbrDecl must be valid before calling this function.
946  auto NumAttrs = AbbrDecl.getNumAttributes();
947  if (Index < NumAttrs) {
948  AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
949  // Add the previous byte size of any previous attribute value.
950  AttrValue.Offset += AttrValue.ByteSize;
951  uint64_t ParseOffset = AttrValue.Offset;
952  if (AbbrDecl.getAttrIsImplicitConstByIndex(Index))
953  AttrValue.Value = DWARFFormValue::createFromSValue(
954  AbbrDecl.getFormByIndex(Index),
956  else {
957  auto U = Die.getDwarfUnit();
958  assert(U && "Die must have valid DWARF unit");
959  AttrValue.Value = DWARFFormValue::createFromUnit(
960  AbbrDecl.getFormByIndex(Index), U, &ParseOffset);
961  }
962  AttrValue.ByteSize = ParseOffset - AttrValue.Offset;
963  } else {
964  assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only");
965  AttrValue = {};
966  }
967 }
968 
970  if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr())
971  updateForIndex(*AbbrDecl, Index + 1);
972  return *this;
973 }
974 
976  switch(Attr) {
977  case DW_AT_location:
978  case DW_AT_string_length:
979  case DW_AT_return_addr:
980  case DW_AT_data_member_location:
981  case DW_AT_frame_base:
982  case DW_AT_static_link:
983  case DW_AT_segment:
984  case DW_AT_use_location:
985  case DW_AT_vtable_elem_location:
986  return true;
987  default:
988  return false;
989  }
990 }
991 
993  switch (Attr) {
994  // From the DWARF v5 specification.
995  case DW_AT_location:
996  case DW_AT_byte_size:
997  case DW_AT_bit_offset:
998  case DW_AT_bit_size:
999  case DW_AT_string_length:
1000  case DW_AT_lower_bound:
1001  case DW_AT_return_addr:
1002  case DW_AT_bit_stride:
1003  case DW_AT_upper_bound:
1004  case DW_AT_count:
1005  case DW_AT_data_member_location:
1006  case DW_AT_frame_base:
1007  case DW_AT_segment:
1008  case DW_AT_static_link:
1009  case DW_AT_use_location:
1010  case DW_AT_vtable_elem_location:
1011  case DW_AT_allocated:
1012  case DW_AT_associated:
1013  case DW_AT_data_location:
1014  case DW_AT_byte_stride:
1015  case DW_AT_rank:
1016  case DW_AT_call_value:
1017  case DW_AT_call_origin:
1018  case DW_AT_call_target:
1019  case DW_AT_call_target_clobbered:
1020  case DW_AT_call_data_location:
1021  case DW_AT_call_data_value:
1022  // Extensions.
1023  case DW_AT_GNU_call_site_value:
1024  case DW_AT_GNU_call_site_target:
1025  return true;
1026  default:
1027  return false;
1028  }
1029 }
llvm::DWARFLocationExpressionsVector
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
Definition: DWARFLocationExpression.h:45
DWARFFormValue.h
llvm::errc::invalid_argument
@ invalid_argument
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:286
llvm::DWARFContext::getLineTableForUnit
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *U)
Get a pointer to a parsed line table corresponding to a compile unit.
Definition: DWARFContext.cpp:929
Attrs
Function Attrs
Definition: README_ALTIVEC.txt:215
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm::DIDumpOptions::ShowForm
bool ShowForm
Definition: DIContext.h:189
llvm::DWARFDie::isValid
bool isValid() const
Definition: DWARFDie.h:51
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:491
MathExtras.h
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::DWARFDie::getPreviousSibling
DWARFDie getPreviousSibling() const
Get the previous sibling of this DIE object.
Definition: DWARFDie.cpp:905
llvm::DWARFDie::getRangesBaseAttribute
Optional< uint64_t > getRangesBaseAttribute() const
Extract the range base attribute from this DIE as absolute section offset.
Definition: DWARFDie.cpp:670
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
Optional.h
dumpAttribute
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, const DWARFAttribute &AttrValue, unsigned Indent, DIDumpOptions DumpOpts)
Definition: DWARFDie.cpp:474
llvm::DWARFAttribute::Value
DWARFFormValue Value
The form and value for this attribute.
Definition: DWARFAttribute.h:32
llvm::DWARFDie::getLinkageName
const char * getLinkageName() const
Return the DIE linkage name resolving DW_AT_specification or DW_AT_abstract_origin references if nece...
Definition: DWARFDie.cpp:795
llvm::DWARFUnit::getRnglistOffset
Optional< uint64_t > getRnglistOffset(uint32_t Index)
Return a rangelist's offset based on an index.
Definition: DWARFUnit.cpp:960
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:164
llvm::DWARFDie::dump
LLVM_DUMP_METHOD void dump() const
Convenience zero-argument overload for debugging.
Definition: DWARFDie.cpp:891
llvm::StringRef::endswith
LLVM_NODISCARD bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:297
T
llvm::DWARFAttribute::Attr
dwarf::Attribute Attr
The attribute enumeration of this attribute.
Definition: DWARFAttribute.h:30
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::DWARFAbbreviationDeclaration::getFormByIndex
dwarf::Form getFormByIndex(uint32_t idx) const
Definition: DWARFAbbreviationDeclaration.h:100
llvm::DWARFDie::getShortName
const char * getShortName() const
Return the DIE short name resolving DW_AT_specification or DW_AT_abstract_origin references if necess...
Definition: DWARFDie.cpp:788
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::dwarf::Form
Form
Definition: Dwarf.h:131
llvm::DWARFFormValue::getAsAddress
Optional< uint64_t > getAsAddress() const
Definition: DWARFFormValue.cpp:662
DWARFContext.h
llvm::dwarf::toSectionedAddress
Optional< object::SectionedAddress > toSectionedAddress(const Optional< DWARFFormValue > &V)
Definition: DWARFFormValue.h:282
llvm::DWARFDie::getAbbreviationDeclarationPtr
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Get the abbreviation declaration for this DIE.
Definition: DWARFDie.h:59
llvm::DWARFFormValue::createFromUValue
static DWARFFormValue createFromUValue(dwarf::Form F, uint64_t V)
Definition: DWARFFormValue.cpp:84
llvm::DWARFAbbreviationDeclaration::getAttrByIndex
dwarf::Attribute getAttrByIndex(uint32_t idx) const
Definition: DWARFAbbreviationDeclaration.h:109
llvm::DWARFFormValue::getAsUnsignedConstant
Optional< uint64_t > getAsUnsignedConstant() const
Definition: DWARFFormValue.cpp:721
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
dumpLocationList
static void dumpLocationList(raw_ostream &OS, const DWARFFormValue &FormValue, DWARFUnit *U, unsigned Indent, DIDumpOptions DumpOpts)
Definition: DWARFDie.cpp:72
Shift
bool Shift
Definition: README.txt:468
llvm::WithColor::get
raw_ostream & get()
Definition: WithColor.h:80
llvm::DWARFContext
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:53
llvm::DWARFFormValue::FC_Exprloc
@ FC_Exprloc
Definition: DWARFFormValue.h:38
llvm::DWARFLocationExpression
Represents a single DWARF expression, whose value is location-dependent.
Definition: DWARFLocationExpression.h:22
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
llvm::WithColor
An RAII object that temporarily switches an output stream to a specific color.
Definition: WithColor.h:53
llvm::Optional< uint64_t >
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::DWARFDie::addressRangeContainsAddress
bool addressRangeContainsAddress(const uint64_t Address) const
Definition: DWARFDie.cpp:727
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
llvm::DWARFExpression::print
void print(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *RegInfo, DWARFUnit *U, bool IsEH=false) const
Definition: DWARFExpression.cpp:324
attributes
Deduce and propagate attributes
Definition: Attributor.cpp:3074
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition: SparseBitVector.h:876
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::DWARFDebugInfoEntry::getAbbreviationDeclarationPtr
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Definition: DWARFDebugInfoEntry.h:58
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
llvm::DWARFUnit::getFormParams
const dwarf::FormParams & getFormParams() const
Definition: DWARFUnit.h:282
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition: DWARFDataExtractor.h:21
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:104
llvm::DINameKind::LinkageName
@ LinkageName
Format.h
llvm::dwarf::FormParams::Format
DwarfFormat Format
Definition: Dwarf.h:651
dumpLocationExpr
static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue, DWARFUnit *U, unsigned Indent, DIDumpOptions DumpOpts)
Definition: DWARFDie.cpp:95
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1035
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::getOffset
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
Definition: RuntimeDyld.cpp:170
llvm::dwarf::Attribute
Attribute
Attributes.
Definition: Dwarf.h:124
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:162
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::DWARFUnit::getLoclistOffset
Optional< uint64_t > getLoclistOffset(uint32_t Index)
Definition: DWARFUnit.cpp:971
llvm::AArch64CC::LT
@ LT
Definition: AArch64BaseInfo.h:266
llvm::StringRef::substr
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:611
llvm::DWARFAttribute::Offset
uint64_t Offset
The debug info/types offset for this attribute.
Definition: DWARFAttribute.h:26
llvm::DWARFDie::getLastChild
DWARFDie getLastChild() const
Get the last child of this DIE object.
Definition: DWARFDie.cpp:917
llvm::DataExtractor::getULEB128
uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
Definition: DataExtractor.cpp:221
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:250
llvm::DIDumpOptions::ShowAddresses
bool ShowAddresses
Definition: DIContext.h:186
llvm::DWARFAttribute
Encapsulates a DWARF attribute value and all of the data required to describe the attribute value.
Definition: DWARFAttribute.h:24
llvm::DWARFFormValue::createFromSValue
static DWARFFormValue createFromSValue(dwarf::Form F, int64_t V)
Definition: DWARFFormValue.cpp:80
llvm::HighlightColor::Tag
@ Tag
dumpRanges
static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS, const DWARFAddressRangesVector &Ranges, unsigned AddressSize, unsigned Indent, const DIDumpOptions &DumpOpts)
Definition: DWARFDie.cpp:58
DWARFDebugRangeList.h
llvm::DIDumpOptions::Verbose
bool Verbose
Definition: DIContext.h:191
llvm::DINameKind
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
Definition: DIContext.h:131
dumpApplePropertyAttribute
static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val)
Definition: DWARFDie.cpp:40
llvm::dwarf::computeTombstoneAddress
uint64_t computeTombstoneAddress(uint8_t AddressByteSize)
Definition: Dwarf.h:772
llvm::dwarf::AttributeValueString
StringRef AttributeValueString(uint16_t Attr, unsigned Val)
Returns the symbolic string representing Val when used as a value for attribute Attr.
Definition: Dwarf.cpp:639
llvm::DWARFDie::isSubroutineDIE
bool isSubroutineDIE() const
Returns true if DIE represents a subprogram or an inlined subroutine.
Definition: DWARFDie.cpp:591
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::HighlightColor::Enumerator
@ Enumerator
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
llvm::dwarf::getTag
unsigned getTag(StringRef TagString)
Definition: Dwarf.cpp:32
llvm::DWARFFormValue::FC_SectionOffset
@ FC_SectionOffset
Definition: DWARFFormValue.h:37
llvm::DWARFFormValue::dump
void dump(raw_ostream &OS, DIDumpOptions DumpOpts=DIDumpOptions()) const
Definition: DWARFFormValue.cpp:405
llvm::dwarf::LanguageLowerBound
Optional< unsigned > LanguageLowerBound(SourceLanguage L)
Definition: Dwarf.cpp:368
llvm::DWARFLocationTable::dumpLocationList
bool dumpLocationList(uint64_t *Offset, raw_ostream &OS, Optional< object::SectionedAddress > BaseAddr, const MCRegisterInfo *MRI, const DWARFObject &Obj, DWARFUnit *U, DIDumpOptions DumpOpts, unsigned Indent) const
Dump the location list at the given Offset.
Definition: DWARFDebugLoc.cpp:121
llvm::DIDumpOptions::ShowChildren
bool ShowChildren
Definition: DIContext.h:187
llvm::DWARFFormValue::getAsSectionOffset
Optional< uint64_t > getAsSectionOffset() const
Definition: DWARFFormValue.cpp:715
DWARFDie.h
llvm::dwarf::Index
Index
Definition: Dwarf.h:467
llvm::DWARFDie::getCallerFrame
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:816
First
into llvm powi allowing the code generator to produce balanced multiplication trees First
Definition: README.txt:54
llvm::DIDumpOptions::ChildRecurseDepth
unsigned ChildRecurseDepth
Definition: DIContext.h:182
llvm::DWARFDie::getDeclFile
std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const
Definition: DWARFDie.cpp:809
llvm::dwarf::toSectionOffset
Optional< uint64_t > toSectionOffset(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
Definition: DWARFFormValue.h:303
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::DWARFObject
Definition: DWARFObject.h:25
llvm::DWARFFormValue
Definition: DWARFFormValue.h:26
llvm::DWARFDie::attribute_iterator
Definition: DWARFDie.h:290
FormatVariadic.h
llvm::None
const NoneType None
Definition: None.h:23
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::dwarf::FormEncodingString
StringRef FormEncodingString(unsigned Encoding)
Definition: Dwarf.cpp:105
llvm::DWARFDie::dump
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:837
llvm::DWARFFormValue::getAsRelativeReference
Optional< UnitOffset > getAsRelativeReference() const
Definition: DWARFFormValue.cpp:694
llvm::DIDumpOptions::ShowParents
bool ShowParents
Definition: DIContext.h:188
getLinkageName
static std::string getLinkageName(GlobalValue::LinkageTypes LT)
Definition: AsmWriter.cpp:3155
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
uint64_t
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::DWARFDie::getDeclLine
uint64_t getDeclLine() const
Returns the declaration line (start line) for a DIE, assuming it specifies a subprogram.
Definition: DWARFDie.cpp:804
llvm::find
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1571
llvm::DWARFDie::getAddressRanges
Expected< DWARFAddressRangesVector > getAddressRanges() const
Get the address ranges for this DIE.
Definition: DWARFDie.cpp:710
I
#define I(x, y, z)
Definition: MD5.cpp:59
DWARFUnit.h
llvm::DWARFDie::find
Optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition: DWARFDie.cpp:596
llvm::DILineInfoSpecifier::FileLineInfoKind
FileLineInfoKind
Definition: DIContext.h:136
llvm::DWARFExpression
Definition: DWARFExpression.h:25
llvm::HighlightColor::Address
@ Address
llvm::DataExtractor::isValidOffset
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
Definition: DataExtractor.h:665
DWARFAbbreviationDeclaration.h
llvm::DWARFFormValue::FC_Block
@ FC_Block
Definition: DWARFFormValue.h:31
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ObjectFile.h
llvm::DWARFDie::findRecursively
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:620
llvm::DWARFDie::getLowAndHighPC
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:695
llvm::irsymtab::storage::Word
support::ulittle32_t Word
Definition: IRSymtab.h:52
llvm::dwarf::toString
Optional< const char * > toString(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Definition: DWARFFormValue.h:175
llvm::dwarf::SourceLanguage
SourceLanguage
Definition: Dwarf.h:200
llvm::DWARFDie::getLocations
Expected< DWARFLocationExpressionsVector > getLocations(dwarf::Attribute Attr) const
Definition: DWARFDie.cpp:741
llvm::DWARFUnit::getCompilationDir
const char * getCompilationDir()
Definition: DWARFUnit.cpp:373
llvm::ArrayRef< uint8_t >
llvm::DWARFAbbreviationDeclaration::getNumAttributes
size_t getNumAttributes() const
Definition: DWARFAbbreviationDeclaration.h:105
llvm::DWARFContext::isLittleEndian
bool isLittleEndian() const
Definition: DWARFContext.h:366
None.h
llvm::DWARFFormValue::dumpAddress
void dumpAddress(raw_ostream &OS, uint64_t Address) const
llvm::HighlightColor::String
@ String
llvm::countTrailingZeros
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: MathExtras.h:156
llvm::DWARFAbbreviationDeclaration::getAttrIsImplicitConstByIndex
bool getAttrIsImplicitConstByIndex(uint32_t idx) const
Definition: DWARFAbbreviationDeclaration.h:114
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
Dwarf.h
llvm::DWARFUnit::getContext
DWARFContext & getContext() const
Definition: DWARFUnit.h:279
llvm::DWARFDie::getDwarfUnit
DWARFUnit * getDwarfUnit() const
Definition: DWARFDie.h:54
getParent
static const Function * getParent(const Value *V)
Definition: BasicAliasAnalysis.cpp:776
uint32_t
llvm::DWARFDie::getName
const char * getName(DINameKind Kind) const
Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin references if necessary.
Definition: DWARFDie.cpp:777
llvm::DWARFDie::getLocBaseAttribute
Optional< uint64_t > getLocBaseAttribute() const
Definition: DWARFDie.cpp:674
llvm::dwarf::ApplePropertyString
StringRef ApplePropertyString(unsigned)
Definition: Dwarf.cpp:565
llvm::DWARFDie::getSibling
DWARFDie getSibling() const
Get the sibling of this DIE object.
Definition: DWARFDie.cpp:899
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::SmallSet::insert
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:180
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
@ AbsoluteFilePath
llvm::DWARFAttribute::mayHaveLocationExpr
static bool mayHaveLocationExpr(dwarf::Attribute Attr)
Identifies DWARF attributes that may contain a reference to a DWARF expression.
Definition: DWARFDie.cpp:992
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::DWARFDie::attribute_iterator::operator++
attribute_iterator & operator++()
Definition: DWARFDie.cpp:969
llvm::HighlightColor::Attribute
@ Attribute
WithColor.h
llvm::DWARFDie::getParent
DWARFDie getParent() const
Get the parent of this DIE object.
Definition: DWARFDie.cpp:893
llvm::DWARFUnit::getAddressByteSize
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:286
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1231
llvm::DWARFAddressRangesVector
std::vector< DWARFAddressRange > DWARFAddressRangesVector
DWARFAddressRangesVector - represents a set of absolute address ranges.
Definition: DWARFAddressRange.h:83
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
llvm::DWARFContext::getRegisterInfo
const MCRegisterInfo * getRegisterInfo() const
Definition: DWARFContext.h:382
llvm::AMDGPU::HSAMD::Kernel::Arg::Key::TypeName
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
Definition: AMDGPUMetadata.h:170
llvm::DWARFAbbreviationDeclaration
Definition: DWARFAbbreviationDeclaration.h:27
llvm::DWARFUnit
Definition: DWARFUnit.h:203
llvm::DWARFFormValue::getAsBlock
Optional< ArrayRef< uint8_t > > getAsBlock() const
Definition: DWARFFormValue.cpp:747
DataExtractor.h
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
DWARFExpression.h
llvm::DWARFAbbreviationDeclaration::getAttrImplicitConstValueByIndex
int64_t getAttrImplicitConstValueByIndex(uint32_t idx) const
Definition: DWARFAbbreviationDeclaration.h:119
llvm::dwarf::toUnsigned
Optional< uint64_t > toUnsigned(const Optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
Definition: DWARFFormValue.h:210
llvm::DWARFDie::getAttributeValueAsReferencedDie
DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE as the referenced DIE.
Definition: DWARFDie.cpp:653
FormatAdapters.h
isValid
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
Definition: RustDemangle.cpp:216
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::DWARFUnit::getBaseAddress
llvm::Optional< object::SectionedAddress > getBaseAddress()
Definition: DWARFUnit.cpp:821
llvm::DWARFDie::attributes
iterator_range< attribute_iterator > attributes() const
Get an iterator range to all attributes in the current DIE only.
Definition: DWARFDie.cpp:923
llvm::DINameKind::None
@ None
llvm::raw_ostream::indent
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Definition: raw_ostream.cpp:497
llvm::DWARFFormValue::isFormClass
bool isFormClass(FormClass FC) const
Definition: DWARFFormValue.cpp:212
N
#define N
llvm::DWARFContext::getDWARFObj
const DWARFObject & getDWARFObj() const
Definition: DWARFContext.h:130
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
llvm::DWARFFormValue::getForm
dwarf::Form getForm() const
Definition: DWARFFormValue.h:77
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::tgtok::Bit
@ Bit
Definition: TGLexer.h:50
llvm::DWARFDie::attribute_iterator::attribute_iterator
attribute_iterator()=delete
llvm::StringRef::data
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:149
llvm::DWARFDie::getHighPC
Optional< uint64_t > getHighPC(uint64_t LowPC) const
Get the DW_AT_high_pc attribute value as an address.
Definition: DWARFDie.cpp:678
llvm::DWARFAttribute::mayHaveLocationList
static bool mayHaveLocationList(dwarf::Attribute Attr)
Identify DWARF attributes that may contain a pointer to a location list.
Definition: DWARFDie.cpp:975
llvm::DWARFFormValue::createFromUnit
static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit, uint64_t *OffsetPtr)
Definition: DWARFFormValue.cpp:100
llvm::DWARFDie
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition: DWARFDie.h:43
llvm::DWARFAddressRange
Definition: DWARFAddressRange.h:22
llvm::DWARFDie::isSubprogramDIE
bool isSubprogramDIE() const
Returns true if DIE represents a subprogram (not inlined).
Definition: DWARFDie.cpp:589
llvm::dwarf::TagString
StringRef TagString(unsigned Tag)
Definition: Dwarf.cpp:21
raw_ostream.h
llvm::DWARFUnit::getLocationTable
const DWARFLocationTable & getLocationTable()
Definition: DWARFUnit.h:342
dumpParentChain
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:826
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
File
Instrumentation for Order File
Definition: InstrOrderFile.cpp:205
llvm::dwarf::AttributeString
StringRef AttributeString(unsigned Attribute)
Definition: Dwarf.cpp:72
llvm::DWARFDie::getFirstChild
DWARFDie getFirstChild() const
Get the first child of this DIE object.
Definition: DWARFDie.cpp:911
llvm::DIDumpOptions::ParentRecurseDepth
unsigned ParentRecurseDepth
Definition: DIContext.h:183
llvm::Optional::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:282
llvm::DWARFDie::getSubroutineName
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:771
SmallSet.h
llvm::DIDumpOptions
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:180
llvm::DIDumpOptions::RecoverableErrorHandler
std::function< void(Error)> RecoverableErrorHandler
Definition: DIContext.h:212