1 //===- DWARFDie.cpp -------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
10 #include "llvm/ADT/None.h"
11 #include "llvm/ADT/Optional.h"
12 #include "llvm/ADT/SmallSet.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/BinaryFormat/Dwarf.h"
15 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
16 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
17 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
18 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
19 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
20 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
21 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/Support/DataExtractor.h"
23 #include "llvm/Support/Format.h"
24 #include "llvm/Support/FormatAdapters.h"
25 #include "llvm/Support/FormatVariadic.h"
26 #include "llvm/Support/MathExtras.h"
27 #include "llvm/Support/WithColor.h"
28 #include "llvm/Support/raw_ostream.h"
37 using namespace dwarf
;
38 using namespace object
;
40 static void dumpApplePropertyAttribute(raw_ostream
&OS
, uint64_t Val
) {
43 uint64_t Shift
= countTrailingZeros(Val
);
44 assert(Shift
< 64 && "undefined behavior");
45 uint64_t Bit
= 1ULL << Shift
;
46 auto PropName
= ApplePropertyString(Bit
);
47 if (!PropName
.empty())
50 OS
<< format("DW_APPLE_PROPERTY_0x%" PRIx64
, Bit
);
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
)
65 ArrayRef
<SectionName
> SectionNames
;
67 SectionNames
= Obj
.getSectionNames();
69 for (const DWARFAddressRange
&R
: Ranges
) {
72 R
.dump(OS
, AddressSize
);
74 DWARFFormValue::dumpAddressSection(Obj
, OS
, DumpOpts
, R
.SectionIndex
);
78 static void dumpLocation(raw_ostream
&OS
, DWARFFormValue
&FormValue
,
79 DWARFUnit
*U
, unsigned Indent
,
80 DIDumpOptions DumpOpts
) {
81 DWARFContext
&Ctx
= U
->getContext();
82 const DWARFObject
&Obj
= Ctx
.getDWARFObj();
83 const MCRegisterInfo
*MRI
= Ctx
.getRegisterInfo();
84 if (FormValue
.isFormClass(DWARFFormValue::FC_Block
) ||
85 FormValue
.isFormClass(DWARFFormValue::FC_Exprloc
)) {
86 ArrayRef
<uint8_t> Expr
= *FormValue
.getAsBlock();
87 DataExtractor
Data(StringRef((const char *)Expr
.data(), Expr
.size()),
88 Ctx
.isLittleEndian(), 0);
89 DWARFExpression(Data
, U
->getVersion(), U
->getAddressByteSize())
94 FormValue
.dump(OS
, DumpOpts
);
95 const auto &DumpLL
= [&](auto ExpectedLL
) {
97 uint64_t BaseAddr
= 0;
98 if (Optional
<object::SectionedAddress
> BA
= U
->getBaseAddress())
99 BaseAddr
= BA
->Address
;
100 auto LLDumpOpts
= DumpOpts
;
101 LLDumpOpts
.Verbose
= false;
102 ExpectedLL
->dump(OS
, BaseAddr
, Ctx
.isLittleEndian(), Obj
.getAddressSize(),
103 MRI
, U
, LLDumpOpts
, Indent
);
107 OS
<< formatv("error extracting location list: {0}",
108 fmt_consume(ExpectedLL
.takeError()));
111 if (FormValue
.isFormClass(DWARFFormValue::FC_SectionOffset
)) {
112 uint64_t Offset
= *FormValue
.getAsSectionOffset();
113 if (!U
->isDWOUnit() && !U
->getLocSection()->Data
.empty()) {
114 DWARFDebugLoc DebugLoc
;
115 DWARFDataExtractor
Data(Obj
, *U
->getLocSection(), Ctx
.isLittleEndian(),
116 Obj
.getAddressSize());
117 DumpLL(DebugLoc
.parseOneLocationList(Data
, &Offset
));
121 bool UseLocLists
= !U
->isDWOUnit();
122 StringRef LoclistsSectionData
=
123 UseLocLists
? Obj
.getLoclistsSection().Data
: U
->getLocSectionData();
125 if (!LoclistsSectionData
.empty()) {
126 DataExtractor
Data(LoclistsSectionData
, Ctx
.isLittleEndian(),
127 Obj
.getAddressSize());
129 // Old-style location list were used in DWARF v4 (.debug_loc.dwo section).
130 // Modern locations list (.debug_loclists) are used starting from v5.
131 // Ideally we should take the version from the .debug_loclists section
132 // header, but using CU's version for simplicity.
133 DumpLL(DWARFDebugLoclists::parseOneLocationList(
134 Data
, &Offset
, UseLocLists
? U
->getVersion() : 4));
139 /// Dump the name encoded in the type tag.
140 static void dumpTypeTagName(raw_ostream
&OS
, dwarf::Tag T
) {
141 StringRef TagStr
= TagString(T
);
142 if (!TagStr
.startswith("DW_TAG_") || !TagStr
.endswith("_type"))
144 OS
<< TagStr
.substr(7, TagStr
.size() - 12) << " ";
147 static void dumpArrayType(raw_ostream
&OS
, const DWARFDie
&D
) {
148 Optional
<uint64_t> Bound
;
149 for (const DWARFDie
&C
: D
.children())
150 if (C
.getTag() == DW_TAG_subrange_type
) {
151 Optional
<uint64_t> LB
;
152 Optional
<uint64_t> Count
;
153 Optional
<uint64_t> UB
;
154 Optional
<unsigned> DefaultLB
;
155 if (Optional
<DWARFFormValue
> L
= C
.find(DW_AT_lower_bound
))
156 LB
= L
->getAsUnsignedConstant();
157 if (Optional
<DWARFFormValue
> CountV
= C
.find(DW_AT_count
))
158 Count
= CountV
->getAsUnsignedConstant();
159 if (Optional
<DWARFFormValue
> UpperV
= C
.find(DW_AT_upper_bound
))
160 UB
= UpperV
->getAsUnsignedConstant();
161 if (Optional
<DWARFFormValue
> LV
=
162 D
.getDwarfUnit()->getUnitDIE().find(DW_AT_language
))
163 if (Optional
<uint64_t> LC
= LV
->getAsUnsignedConstant())
165 LanguageLowerBound(static_cast<dwarf::SourceLanguage
>(*LC
))))
166 if (LB
&& *LB
== *DefaultLB
)
168 if (!LB
&& !Count
&& !UB
)
170 else if (!LB
&& (Count
|| UB
) && DefaultLB
)
171 OS
<< '[' << (Count
? *Count
: *UB
- *DefaultLB
+ 1) << ']';
183 OS
<< "? + " << *Count
;
193 /// Recursively dump the DIE type name when applicable.
194 static void dumpTypeName(raw_ostream
&OS
, const DWARFDie
&D
) {
198 if (const char *Name
= D
.getName(DINameKind::LinkageName
)) {
203 // FIXME: We should have pretty printers per language. Currently we print
204 // everything as if it was C++ and fall back to the TAG type name.
205 const dwarf::Tag T
= D
.getTag();
207 case DW_TAG_array_type
:
208 case DW_TAG_pointer_type
:
209 case DW_TAG_ptr_to_member_type
:
210 case DW_TAG_reference_type
:
211 case DW_TAG_rvalue_reference_type
:
212 case DW_TAG_subroutine_type
:
215 dumpTypeTagName(OS
, T
);
218 // Follow the DW_AT_type if possible.
219 DWARFDie TypeDie
= D
.getAttributeValueAsReferencedDie(DW_AT_type
);
220 dumpTypeName(OS
, TypeDie
);
223 case DW_TAG_subroutine_type
: {
228 for (const DWARFDie
&C
: D
.children()) {
229 if (C
.getTag() == DW_TAG_formal_parameter
) {
233 dumpTypeName(OS
, C
.getAttributeValueAsReferencedDie(DW_AT_type
));
239 case DW_TAG_array_type
: {
240 dumpArrayType(OS
, D
);
243 case DW_TAG_pointer_type
:
246 case DW_TAG_ptr_to_member_type
:
248 D
.getAttributeValueAsReferencedDie(DW_AT_containing_type
)) {
249 dumpTypeName(OS
<< ' ', Cont
);
254 case DW_TAG_reference_type
:
257 case DW_TAG_rvalue_reference_type
:
265 static void dumpAttribute(raw_ostream
&OS
, const DWARFDie
&Die
,
266 uint64_t *OffsetPtr
, dwarf::Attribute Attr
,
267 dwarf::Form Form
, unsigned Indent
,
268 DIDumpOptions DumpOpts
) {
271 const char BaseIndent
[] = " ";
273 OS
.indent(Indent
+ 2);
274 WithColor(OS
, HighlightColor::Attribute
) << formatv("{0}", Attr
);
276 if (DumpOpts
.Verbose
|| DumpOpts
.ShowForm
)
277 OS
<< formatv(" [{0}]", Form
);
279 DWARFUnit
*U
= Die
.getDwarfUnit();
280 DWARFFormValue FormValue
= DWARFFormValue::createFromUnit(Form
, U
, OffsetPtr
);
286 auto Color
= HighlightColor::Enumerator
;
287 if (Attr
== DW_AT_decl_file
|| Attr
== DW_AT_call_file
) {
288 Color
= HighlightColor::String
;
289 if (const auto *LT
= U
->getContext().getLineTableForUnit(U
))
290 if (LT
->getFileNameByIndex(
291 FormValue
.getAsUnsignedConstant().getValue(),
292 U
->getCompilationDir(),
293 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
, File
)) {
294 File
= '"' + File
+ '"';
297 } else if (Optional
<uint64_t> Val
= FormValue
.getAsUnsignedConstant())
298 Name
= AttributeValueString(Attr
, *Val
);
301 WithColor(OS
, Color
) << Name
;
302 else if (Attr
== DW_AT_decl_line
|| Attr
== DW_AT_call_line
)
303 OS
<< *FormValue
.getAsUnsignedConstant();
304 else if (Attr
== DW_AT_high_pc
&& !DumpOpts
.ShowForm
&& !DumpOpts
.Verbose
&&
305 FormValue
.getAsUnsignedConstant()) {
306 if (DumpOpts
.ShowAddresses
) {
307 // Print the actual address rather than the offset.
308 uint64_t LowPC
, HighPC
, Index
;
309 if (Die
.getLowAndHighPC(LowPC
, HighPC
, Index
))
310 OS
<< format("0x%016" PRIx64
, HighPC
);
312 FormValue
.dump(OS
, DumpOpts
);
314 } else if (DWARFAttribute::mayHaveLocationDescription(Attr
))
315 dumpLocation(OS
, FormValue
, U
, sizeof(BaseIndent
) + Indent
+ 4, DumpOpts
);
317 FormValue
.dump(OS
, DumpOpts
);
319 std::string Space
= DumpOpts
.ShowAddresses
? " " : "";
321 // We have dumped the attribute raw value. For some attributes
322 // having both the raw value and the pretty-printed value is
323 // interesting. These attributes are handled below.
324 if (Attr
== DW_AT_specification
|| Attr
== DW_AT_abstract_origin
) {
325 if (const char *Name
=
326 Die
.getAttributeValueAsReferencedDie(FormValue
).getName(
327 DINameKind::LinkageName
))
328 OS
<< Space
<< "\"" << Name
<< '\"';
329 } else if (Attr
== DW_AT_type
) {
331 dumpTypeName(OS
, Die
.getAttributeValueAsReferencedDie(FormValue
));
333 } else if (Attr
== DW_AT_APPLE_property_attribute
) {
334 if (Optional
<uint64_t> OptVal
= FormValue
.getAsUnsignedConstant())
335 dumpApplePropertyAttribute(OS
, *OptVal
);
336 } else if (Attr
== DW_AT_ranges
) {
337 const DWARFObject
&Obj
= Die
.getDwarfUnit()->getContext().getDWARFObj();
338 // For DW_FORM_rnglistx we need to dump the offset separately, since
339 // we have only dumped the index so far.
340 if (FormValue
.getForm() == DW_FORM_rnglistx
)
341 if (auto RangeListOffset
=
342 U
->getRnglistOffset(*FormValue
.getAsSectionOffset())) {
343 DWARFFormValue FV
= DWARFFormValue::createFromUValue(
344 dwarf::DW_FORM_sec_offset
, *RangeListOffset
);
345 FV
.dump(OS
, DumpOpts
);
347 if (auto RangesOrError
= Die
.getAddressRanges())
348 dumpRanges(Obj
, OS
, RangesOrError
.get(), U
->getAddressByteSize(),
349 sizeof(BaseIndent
) + Indent
+ 4, DumpOpts
);
351 WithColor::error() << "decoding address ranges: "
352 << toString(RangesOrError
.takeError()) << '\n';
358 bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram
; }
360 bool DWARFDie::isSubroutineDIE() const {
362 return Tag
== DW_TAG_subprogram
|| Tag
== DW_TAG_inlined_subroutine
;
365 Optional
<DWARFFormValue
> DWARFDie::find(dwarf::Attribute Attr
) const {
368 auto AbbrevDecl
= getAbbreviationDeclarationPtr();
370 return AbbrevDecl
->getAttributeValue(getOffset(), Attr
, *U
);
374 Optional
<DWARFFormValue
>
375 DWARFDie::find(ArrayRef
<dwarf::Attribute
> Attrs
) const {
378 auto AbbrevDecl
= getAbbreviationDeclarationPtr();
380 for (auto Attr
: Attrs
) {
381 if (auto Value
= AbbrevDecl
->getAttributeValue(getOffset(), Attr
, *U
))
388 Optional
<DWARFFormValue
>
389 DWARFDie::findRecursively(ArrayRef
<dwarf::Attribute
> Attrs
) const {
390 std::vector
<DWARFDie
> Worklist
;
391 Worklist
.push_back(*this);
393 // Keep track if DIEs already seen to prevent infinite recursion.
394 // Empirically we rarely see a depth of more than 3 when dealing with valid
395 // DWARF. This corresponds to following the DW_AT_abstract_origin and
396 // DW_AT_specification just once.
397 SmallSet
<DWARFDie
, 3> Seen
;
400 while (!Worklist
.empty()) {
401 DWARFDie Die
= Worklist
.back();
407 if (auto Value
= Die
.find(Attrs
))
410 if (auto D
= Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
411 if (Seen
.insert(D
).second
)
412 Worklist
.push_back(D
);
414 if (auto D
= Die
.getAttributeValueAsReferencedDie(DW_AT_specification
))
415 if (Seen
.insert(D
).second
)
416 Worklist
.push_back(D
);
423 DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr
) const {
424 if (Optional
<DWARFFormValue
> F
= find(Attr
))
425 return getAttributeValueAsReferencedDie(*F
);
430 DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue
&V
) const {
431 if (auto SpecRef
= V
.getAsRelativeReference()) {
433 return SpecRef
->Unit
->getDIEForOffset(SpecRef
->Unit
->getOffset() + SpecRef
->Offset
);
434 if (auto SpecUnit
= U
->getUnitVector().getUnitForOffset(SpecRef
->Offset
))
435 return SpecUnit
->getDIEForOffset(SpecRef
->Offset
);
440 Optional
<uint64_t> DWARFDie::getRangesBaseAttribute() const {
441 return toSectionOffset(find({DW_AT_rnglists_base
, DW_AT_GNU_ranges_base
}));
444 Optional
<uint64_t> DWARFDie::getHighPC(uint64_t LowPC
) const {
445 if (auto FormValue
= find(DW_AT_high_pc
)) {
446 if (auto Address
= FormValue
->getAsAddress()) {
447 // High PC is an address.
450 if (auto Offset
= FormValue
->getAsUnsignedConstant()) {
451 // High PC is an offset from LowPC.
452 return LowPC
+ *Offset
;
458 bool DWARFDie::getLowAndHighPC(uint64_t &LowPC
, uint64_t &HighPC
,
459 uint64_t &SectionIndex
) const {
460 auto F
= find(DW_AT_low_pc
);
461 auto LowPcAddr
= toSectionedAddress(F
);
464 if (auto HighPcAddr
= getHighPC(LowPcAddr
->Address
)) {
465 LowPC
= LowPcAddr
->Address
;
466 HighPC
= *HighPcAddr
;
467 SectionIndex
= LowPcAddr
->SectionIndex
;
473 Expected
<DWARFAddressRangesVector
> DWARFDie::getAddressRanges() const {
475 return DWARFAddressRangesVector();
476 // Single range specified by low/high PC.
477 uint64_t LowPC
, HighPC
, Index
;
478 if (getLowAndHighPC(LowPC
, HighPC
, Index
))
479 return DWARFAddressRangesVector
{{LowPC
, HighPC
, Index
}};
481 Optional
<DWARFFormValue
> Value
= find(DW_AT_ranges
);
483 if (Value
->getForm() == DW_FORM_rnglistx
)
484 return U
->findRnglistFromIndex(*Value
->getAsSectionOffset());
485 return U
->findRnglistFromOffset(*Value
->getAsSectionOffset());
487 return DWARFAddressRangesVector();
490 void DWARFDie::collectChildrenAddressRanges(
491 DWARFAddressRangesVector
&Ranges
) const {
494 if (isSubprogramDIE()) {
495 if (auto DIERangesOrError
= getAddressRanges())
496 Ranges
.insert(Ranges
.end(), DIERangesOrError
.get().begin(),
497 DIERangesOrError
.get().end());
499 llvm::consumeError(DIERangesOrError
.takeError());
502 for (auto Child
: children())
503 Child
.collectChildrenAddressRanges(Ranges
);
506 bool DWARFDie::addressRangeContainsAddress(const uint64_t Address
) const {
507 auto RangesOrError
= getAddressRanges();
508 if (!RangesOrError
) {
509 llvm::consumeError(RangesOrError
.takeError());
513 for (const auto &R
: RangesOrError
.get())
514 if (R
.LowPC
<= Address
&& Address
< R
.HighPC
)
519 const char *DWARFDie::getSubroutineName(DINameKind Kind
) const {
520 if (!isSubroutineDIE())
522 return getName(Kind
);
525 const char *DWARFDie::getName(DINameKind Kind
) const {
526 if (!isValid() || Kind
== DINameKind::None
)
528 // Try to get mangled name only if it was asked for.
529 if (Kind
== DINameKind::LinkageName
) {
530 if (auto Name
= dwarf::toString(
531 findRecursively({DW_AT_MIPS_linkage_name
, DW_AT_linkage_name
}),
535 if (auto Name
= dwarf::toString(findRecursively(DW_AT_name
), nullptr))
540 uint64_t DWARFDie::getDeclLine() const {
541 return toUnsigned(findRecursively(DW_AT_decl_line
), 0);
544 void DWARFDie::getCallerFrame(uint32_t &CallFile
, uint32_t &CallLine
,
545 uint32_t &CallColumn
,
546 uint32_t &CallDiscriminator
) const {
547 CallFile
= toUnsigned(find(DW_AT_call_file
), 0);
548 CallLine
= toUnsigned(find(DW_AT_call_line
), 0);
549 CallColumn
= toUnsigned(find(DW_AT_call_column
), 0);
550 CallDiscriminator
= toUnsigned(find(DW_AT_GNU_discriminator
), 0);
553 /// Helper to dump a DIE with all of its parents, but no siblings.
554 static unsigned dumpParentChain(DWARFDie Die
, raw_ostream
&OS
, unsigned Indent
,
555 DIDumpOptions DumpOpts
, unsigned Depth
= 0) {
558 if (DumpOpts
.ParentRecurseDepth
> 0 && Depth
>= DumpOpts
.ParentRecurseDepth
)
560 Indent
= dumpParentChain(Die
.getParent(), OS
, Indent
, DumpOpts
, Depth
+ 1);
561 Die
.dump(OS
, Indent
, DumpOpts
);
565 void DWARFDie::dump(raw_ostream
&OS
, unsigned Indent
,
566 DIDumpOptions DumpOpts
) const {
569 DWARFDataExtractor debug_info_data
= U
->getDebugInfoExtractor();
570 const uint64_t Offset
= getOffset();
571 uint64_t offset
= Offset
;
572 if (DumpOpts
.ShowParents
) {
573 DIDumpOptions ParentDumpOpts
= DumpOpts
;
574 ParentDumpOpts
.ShowParents
= false;
575 ParentDumpOpts
.ShowChildren
= false;
576 Indent
= dumpParentChain(getParent(), OS
, Indent
, ParentDumpOpts
);
579 if (debug_info_data
.isValidOffset(offset
)) {
580 uint32_t abbrCode
= debug_info_data
.getULEB128(&offset
);
581 if (DumpOpts
.ShowAddresses
)
582 WithColor(OS
, HighlightColor::Address
).get()
583 << format("\n0x%8.8" PRIx64
": ", Offset
);
586 auto AbbrevDecl
= getAbbreviationDeclarationPtr();
588 WithColor(OS
, HighlightColor::Tag
).get().indent(Indent
)
589 << formatv("{0}", getTag());
590 if (DumpOpts
.Verbose
)
591 OS
<< format(" [%u] %c", abbrCode
,
592 AbbrevDecl
->hasChildren() ? '*' : ' ');
595 // Dump all data in the DIE for the attributes.
596 for (const auto &AttrSpec
: AbbrevDecl
->attributes()) {
597 if (AttrSpec
.Form
== DW_FORM_implicit_const
) {
598 // We are dumping .debug_info section ,
599 // implicit_const attribute values are not really stored here,
600 // but in .debug_abbrev section. So we just skip such attrs.
603 dumpAttribute(OS
, *this, &offset
, AttrSpec
.Attr
, AttrSpec
.Form
,
607 DWARFDie child
= getFirstChild();
608 if (DumpOpts
.ShowChildren
&& DumpOpts
.ChildRecurseDepth
> 0 && child
) {
609 DumpOpts
.ChildRecurseDepth
--;
610 DIDumpOptions ChildDumpOpts
= DumpOpts
;
611 ChildDumpOpts
.ShowParents
= false;
613 child
.dump(OS
, Indent
+ 2, ChildDumpOpts
);
614 child
= child
.getSibling();
618 OS
<< "Abbreviation code not found in 'debug_abbrev' class for code: "
622 OS
.indent(Indent
) << "NULL\n";
627 LLVM_DUMP_METHOD
void DWARFDie::dump() const { dump(llvm::errs(), 0); }
629 DWARFDie
DWARFDie::getParent() const {
631 return U
->getParent(Die
);
635 DWARFDie
DWARFDie::getSibling() const {
637 return U
->getSibling(Die
);
641 DWARFDie
DWARFDie::getPreviousSibling() const {
643 return U
->getPreviousSibling(Die
);
647 DWARFDie
DWARFDie::getFirstChild() const {
649 return U
->getFirstChild(Die
);
653 DWARFDie
DWARFDie::getLastChild() const {
655 return U
->getLastChild(Die
);
659 iterator_range
<DWARFDie::attribute_iterator
> DWARFDie::attributes() const {
660 return make_range(attribute_iterator(*this, false),
661 attribute_iterator(*this, true));
664 DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D
, bool End
)
666 auto AbbrDecl
= Die
.getAbbreviationDeclarationPtr();
667 assert(AbbrDecl
&& "Must have abbreviation declaration");
669 // This is the end iterator so we set the index to the attribute count.
670 Index
= AbbrDecl
->getNumAttributes();
672 // This is the begin iterator so we extract the value for this->Index.
673 AttrValue
.Offset
= D
.getOffset() + AbbrDecl
->getCodeByteSize();
674 updateForIndex(*AbbrDecl
, 0);
678 void DWARFDie::attribute_iterator::updateForIndex(
679 const DWARFAbbreviationDeclaration
&AbbrDecl
, uint32_t I
) {
681 // AbbrDecl must be valid before calling this function.
682 auto NumAttrs
= AbbrDecl
.getNumAttributes();
683 if (Index
< NumAttrs
) {
684 AttrValue
.Attr
= AbbrDecl
.getAttrByIndex(Index
);
685 // Add the previous byte size of any previous attribute value.
686 AttrValue
.Offset
+= AttrValue
.ByteSize
;
687 uint64_t ParseOffset
= AttrValue
.Offset
;
688 auto U
= Die
.getDwarfUnit();
689 assert(U
&& "Die must have valid DWARF unit");
690 AttrValue
.Value
= DWARFFormValue::createFromUnit(
691 AbbrDecl
.getFormByIndex(Index
), U
, &ParseOffset
);
692 AttrValue
.ByteSize
= ParseOffset
- AttrValue
.Offset
;
694 assert(Index
== NumAttrs
&& "Indexes should be [0, NumAttrs) only");
699 DWARFDie::attribute_iterator
&DWARFDie::attribute_iterator::operator++() {
700 if (auto AbbrDecl
= Die
.getAbbreviationDeclarationPtr())
701 updateForIndex(*AbbrDecl
, Index
+ 1);
705 bool DWARFAttribute::mayHaveLocationDescription(dwarf::Attribute Attr
) {
707 // From the DWARF v5 specification.
709 case DW_AT_byte_size
:
711 case DW_AT_string_length
:
712 case DW_AT_lower_bound
:
713 case DW_AT_return_addr
:
714 case DW_AT_bit_stride
:
715 case DW_AT_upper_bound
:
717 case DW_AT_data_member_location
:
718 case DW_AT_frame_base
:
720 case DW_AT_static_link
:
721 case DW_AT_use_location
:
722 case DW_AT_vtable_elem_location
:
723 case DW_AT_allocated
:
724 case DW_AT_associated
:
725 case DW_AT_byte_stride
:
727 case DW_AT_call_value
:
728 case DW_AT_call_origin
:
729 case DW_AT_call_target
:
730 case DW_AT_call_target_clobbered
:
731 case DW_AT_call_data_location
:
732 case DW_AT_call_data_value
:
734 case DW_AT_GNU_call_site_value
:
735 case DW_AT_GNU_call_site_target
: