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/FormatVariadic.h"
25 #include "llvm/Support/MathExtras.h"
26 #include "llvm/Support/WithColor.h"
27 #include "llvm/Support/raw_ostream.h"
36 using namespace dwarf
;
37 using namespace object
;
39 static void dumpApplePropertyAttribute(raw_ostream
&OS
, uint64_t Val
) {
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())
49 OS
<< format("DW_APPLE_PROPERTY_0x%" PRIx64
, Bit
);
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
)
64 ArrayRef
<SectionName
> SectionNames
;
66 SectionNames
= Obj
.getSectionNames();
68 for (const DWARFAddressRange
&R
: Ranges
) {
71 R
.dump(OS
, AddressSize
);
73 DWARFFormValue::dumpAddressSection(Obj
, OS
, DumpOpts
, R
.SectionIndex
);
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
) ||
84 FormValue
.isFormClass(DWARFFormValue::FC_Exprloc
)) {
85 ArrayRef
<uint8_t> Expr
= *FormValue
.getAsBlock();
86 DataExtractor
Data(StringRef((const char *)Expr
.data(), Expr
.size()),
87 Ctx
.isLittleEndian(), 0);
88 DWARFExpression(Data
, U
->getVersion(), U
->getAddressByteSize())
93 FormValue
.dump(OS
, DumpOpts
);
94 if (FormValue
.isFormClass(DWARFFormValue::FC_SectionOffset
)) {
95 uint64_t Offset
= *FormValue
.getAsSectionOffset();
96 if (!U
->isDWOUnit() && !U
->getLocSection()->Data
.empty()) {
97 DWARFDebugLoc DebugLoc
;
98 DWARFDataExtractor
Data(Obj
, *U
->getLocSection(), Ctx
.isLittleEndian(),
99 Obj
.getAddressSize());
100 auto LL
= DebugLoc
.parseOneLocationList(Data
, &Offset
);
102 uint64_t BaseAddr
= 0;
103 if (Optional
<object::SectionedAddress
> BA
= U
->getBaseAddress())
104 BaseAddr
= BA
->Address
;
105 LL
->dump(OS
, Ctx
.isLittleEndian(), Obj
.getAddressSize(), MRI
, U
,
108 OS
<< "error extracting location list.";
112 bool UseLocLists
= !U
->isDWOUnit();
113 StringRef LoclistsSectionData
=
114 UseLocLists
? Obj
.getLoclistsSection().Data
: U
->getLocSectionData();
116 if (!LoclistsSectionData
.empty()) {
117 DataExtractor
Data(LoclistsSectionData
, Ctx
.isLittleEndian(),
118 Obj
.getAddressSize());
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.
124 auto LL
= DWARFDebugLoclists::parseOneLocationList(
125 Data
, &Offset
, UseLocLists
? U
->getVersion() : 4);
127 uint64_t BaseAddr
= 0;
128 if (Optional
<object::SectionedAddress
> BA
= U
->getBaseAddress())
129 BaseAddr
= BA
->Address
;
132 LL
->dump(OS
, BaseAddr
, Ctx
.isLittleEndian(), Obj
.getAddressSize(), MRI
,
135 OS
<< "error extracting location list.";
140 /// Dump the name encoded in the type tag.
141 static void dumpTypeTagName(raw_ostream
&OS
, dwarf::Tag T
) {
142 StringRef TagStr
= TagString(T
);
143 if (!TagStr
.startswith("DW_TAG_") || !TagStr
.endswith("_type"))
145 OS
<< TagStr
.substr(7, TagStr
.size() - 12) << " ";
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
) {
152 Optional
<uint64_t> LB
;
153 Optional
<uint64_t> Count
;
154 Optional
<uint64_t> UB
;
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())
166 LanguageLowerBound(static_cast<dwarf::SourceLanguage
>(*LC
))))
167 if (LB
&& *LB
== *DefaultLB
)
169 if (!LB
&& !Count
&& !UB
)
171 else if (!LB
&& (Count
|| UB
) && DefaultLB
)
172 OS
<< '[' << (Count
? *Count
: *UB
- *DefaultLB
+ 1) << ']';
184 OS
<< "? + " << *Count
;
194 /// Recursively dump the DIE type name when applicable.
195 static void dumpTypeName(raw_ostream
&OS
, const DWARFDie
&D
) {
199 if (const char *Name
= D
.getName(DINameKind::LinkageName
)) {
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();
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
:
216 dumpTypeTagName(OS
, T
);
219 // Follow the DW_AT_type if possible.
220 DWARFDie TypeDie
= D
.getAttributeValueAsReferencedDie(DW_AT_type
);
221 dumpTypeName(OS
, TypeDie
);
224 case DW_TAG_subroutine_type
: {
229 for (const DWARFDie
&C
: D
.children()) {
230 if (C
.getTag() == DW_TAG_formal_parameter
) {
234 dumpTypeName(OS
, C
.getAttributeValueAsReferencedDie(DW_AT_type
));
240 case DW_TAG_array_type
: {
241 dumpArrayType(OS
, D
);
244 case DW_TAG_pointer_type
:
247 case DW_TAG_ptr_to_member_type
:
249 D
.getAttributeValueAsReferencedDie(DW_AT_containing_type
)) {
250 dumpTypeName(OS
<< ' ', Cont
);
255 case DW_TAG_reference_type
:
258 case DW_TAG_rvalue_reference_type
:
266 static void dumpAttribute(raw_ostream
&OS
, const DWARFDie
&Die
,
267 uint64_t *OffsetPtr
, dwarf::Attribute Attr
,
268 dwarf::Form Form
, unsigned Indent
,
269 DIDumpOptions DumpOpts
) {
272 const char BaseIndent
[] = " ";
274 OS
.indent(Indent
+ 2);
275 WithColor(OS
, HighlightColor::Attribute
) << formatv("{0}", Attr
);
277 if (DumpOpts
.Verbose
|| DumpOpts
.ShowForm
)
278 OS
<< formatv(" [{0}]", Form
);
280 DWARFUnit
*U
= Die
.getDwarfUnit();
281 DWARFFormValue FormValue
= DWARFFormValue::createFromUnit(Form
, U
, OffsetPtr
);
287 auto Color
= HighlightColor::Enumerator
;
288 if (Attr
== DW_AT_decl_file
|| Attr
== DW_AT_call_file
) {
289 Color
= HighlightColor::String
;
290 if (const auto *LT
= U
->getContext().getLineTableForUnit(U
))
291 if (LT
->getFileNameByIndex(
292 FormValue
.getAsUnsignedConstant().getValue(),
293 U
->getCompilationDir(),
294 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
, File
)) {
295 File
= '"' + File
+ '"';
298 } else if (Optional
<uint64_t> Val
= FormValue
.getAsUnsignedConstant())
299 Name
= AttributeValueString(Attr
, *Val
);
302 WithColor(OS
, Color
) << Name
;
303 else if (Attr
== DW_AT_decl_line
|| Attr
== DW_AT_call_line
)
304 OS
<< *FormValue
.getAsUnsignedConstant();
305 else if (Attr
== DW_AT_high_pc
&& !DumpOpts
.ShowForm
&& !DumpOpts
.Verbose
&&
306 FormValue
.getAsUnsignedConstant()) {
307 if (DumpOpts
.ShowAddresses
) {
308 // Print the actual address rather than the offset.
309 uint64_t LowPC
, HighPC
, Index
;
310 if (Die
.getLowAndHighPC(LowPC
, HighPC
, Index
))
311 OS
<< format("0x%016" PRIx64
, HighPC
);
313 FormValue
.dump(OS
, DumpOpts
);
315 } else if (DWARFAttribute::mayHaveLocationDescription(Attr
))
316 dumpLocation(OS
, FormValue
, U
, sizeof(BaseIndent
) + Indent
+ 4, DumpOpts
);
318 FormValue
.dump(OS
, DumpOpts
);
320 std::string Space
= DumpOpts
.ShowAddresses
? " " : "";
322 // We have dumped the attribute raw value. For some attributes
323 // having both the raw value and the pretty-printed value is
324 // interesting. These attributes are handled below.
325 if (Attr
== DW_AT_specification
|| Attr
== DW_AT_abstract_origin
) {
326 if (const char *Name
=
327 Die
.getAttributeValueAsReferencedDie(FormValue
).getName(
328 DINameKind::LinkageName
))
329 OS
<< Space
<< "\"" << Name
<< '\"';
330 } else if (Attr
== DW_AT_type
) {
332 dumpTypeName(OS
, Die
.getAttributeValueAsReferencedDie(FormValue
));
334 } else if (Attr
== DW_AT_APPLE_property_attribute
) {
335 if (Optional
<uint64_t> OptVal
= FormValue
.getAsUnsignedConstant())
336 dumpApplePropertyAttribute(OS
, *OptVal
);
337 } else if (Attr
== DW_AT_ranges
) {
338 const DWARFObject
&Obj
= Die
.getDwarfUnit()->getContext().getDWARFObj();
339 // For DW_FORM_rnglistx we need to dump the offset separately, since
340 // we have only dumped the index so far.
341 if (FormValue
.getForm() == DW_FORM_rnglistx
)
342 if (auto RangeListOffset
=
343 U
->getRnglistOffset(*FormValue
.getAsSectionOffset())) {
344 DWARFFormValue FV
= DWARFFormValue::createFromUValue(
345 dwarf::DW_FORM_sec_offset
, *RangeListOffset
);
346 FV
.dump(OS
, DumpOpts
);
348 if (auto RangesOrError
= Die
.getAddressRanges())
349 dumpRanges(Obj
, OS
, RangesOrError
.get(), U
->getAddressByteSize(),
350 sizeof(BaseIndent
) + Indent
+ 4, DumpOpts
);
352 WithColor::error() << "decoding address ranges: "
353 << toString(RangesOrError
.takeError()) << '\n';
359 bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram
; }
361 bool DWARFDie::isSubroutineDIE() const {
363 return Tag
== DW_TAG_subprogram
|| Tag
== DW_TAG_inlined_subroutine
;
366 Optional
<DWARFFormValue
> DWARFDie::find(dwarf::Attribute Attr
) const {
369 auto AbbrevDecl
= getAbbreviationDeclarationPtr();
371 return AbbrevDecl
->getAttributeValue(getOffset(), Attr
, *U
);
375 Optional
<DWARFFormValue
>
376 DWARFDie::find(ArrayRef
<dwarf::Attribute
> Attrs
) const {
379 auto AbbrevDecl
= getAbbreviationDeclarationPtr();
381 for (auto Attr
: Attrs
) {
382 if (auto Value
= AbbrevDecl
->getAttributeValue(getOffset(), Attr
, *U
))
389 Optional
<DWARFFormValue
>
390 DWARFDie::findRecursively(ArrayRef
<dwarf::Attribute
> Attrs
) const {
391 std::vector
<DWARFDie
> Worklist
;
392 Worklist
.push_back(*this);
394 // Keep track if DIEs already seen to prevent infinite recursion.
395 // Empirically we rarely see a depth of more than 3 when dealing with valid
396 // DWARF. This corresponds to following the DW_AT_abstract_origin and
397 // DW_AT_specification just once.
398 SmallSet
<DWARFDie
, 3> Seen
;
401 while (!Worklist
.empty()) {
402 DWARFDie Die
= Worklist
.back();
408 if (auto Value
= Die
.find(Attrs
))
411 if (auto D
= Die
.getAttributeValueAsReferencedDie(DW_AT_abstract_origin
))
412 if (Seen
.insert(D
).second
)
413 Worklist
.push_back(D
);
415 if (auto D
= Die
.getAttributeValueAsReferencedDie(DW_AT_specification
))
416 if (Seen
.insert(D
).second
)
417 Worklist
.push_back(D
);
424 DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr
) const {
425 if (Optional
<DWARFFormValue
> F
= find(Attr
))
426 return getAttributeValueAsReferencedDie(*F
);
431 DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue
&V
) const {
432 if (auto SpecRef
= V
.getAsRelativeReference()) {
434 return SpecRef
->Unit
->getDIEForOffset(SpecRef
->Unit
->getOffset() + SpecRef
->Offset
);
435 if (auto SpecUnit
= U
->getUnitVector().getUnitForOffset(SpecRef
->Offset
))
436 return SpecUnit
->getDIEForOffset(SpecRef
->Offset
);
441 Optional
<uint64_t> DWARFDie::getRangesBaseAttribute() const {
442 return toSectionOffset(find({DW_AT_rnglists_base
, DW_AT_GNU_ranges_base
}));
445 Optional
<uint64_t> DWARFDie::getHighPC(uint64_t LowPC
) const {
446 if (auto FormValue
= find(DW_AT_high_pc
)) {
447 if (auto Address
= FormValue
->getAsAddress()) {
448 // High PC is an address.
451 if (auto Offset
= FormValue
->getAsUnsignedConstant()) {
452 // High PC is an offset from LowPC.
453 return LowPC
+ *Offset
;
459 bool DWARFDie::getLowAndHighPC(uint64_t &LowPC
, uint64_t &HighPC
,
460 uint64_t &SectionIndex
) const {
461 auto F
= find(DW_AT_low_pc
);
462 auto LowPcAddr
= toSectionedAddress(F
);
465 if (auto HighPcAddr
= getHighPC(LowPcAddr
->Address
)) {
466 LowPC
= LowPcAddr
->Address
;
467 HighPC
= *HighPcAddr
;
468 SectionIndex
= LowPcAddr
->SectionIndex
;
474 Expected
<DWARFAddressRangesVector
> DWARFDie::getAddressRanges() const {
476 return DWARFAddressRangesVector();
477 // Single range specified by low/high PC.
478 uint64_t LowPC
, HighPC
, Index
;
479 if (getLowAndHighPC(LowPC
, HighPC
, Index
))
480 return DWARFAddressRangesVector
{{LowPC
, HighPC
, Index
}};
482 Optional
<DWARFFormValue
> Value
= find(DW_AT_ranges
);
484 if (Value
->getForm() == DW_FORM_rnglistx
)
485 return U
->findRnglistFromIndex(*Value
->getAsSectionOffset());
486 return U
->findRnglistFromOffset(*Value
->getAsSectionOffset());
488 return DWARFAddressRangesVector();
491 void DWARFDie::collectChildrenAddressRanges(
492 DWARFAddressRangesVector
&Ranges
) const {
495 if (isSubprogramDIE()) {
496 if (auto DIERangesOrError
= getAddressRanges())
497 Ranges
.insert(Ranges
.end(), DIERangesOrError
.get().begin(),
498 DIERangesOrError
.get().end());
500 llvm::consumeError(DIERangesOrError
.takeError());
503 for (auto Child
: children())
504 Child
.collectChildrenAddressRanges(Ranges
);
507 bool DWARFDie::addressRangeContainsAddress(const uint64_t Address
) const {
508 auto RangesOrError
= getAddressRanges();
509 if (!RangesOrError
) {
510 llvm::consumeError(RangesOrError
.takeError());
514 for (const auto &R
: RangesOrError
.get())
515 if (R
.LowPC
<= Address
&& Address
< R
.HighPC
)
520 const char *DWARFDie::getSubroutineName(DINameKind Kind
) const {
521 if (!isSubroutineDIE())
523 return getName(Kind
);
526 const char *DWARFDie::getName(DINameKind Kind
) const {
527 if (!isValid() || Kind
== DINameKind::None
)
529 // Try to get mangled name only if it was asked for.
530 if (Kind
== DINameKind::LinkageName
) {
531 if (auto Name
= dwarf::toString(
532 findRecursively({DW_AT_MIPS_linkage_name
, DW_AT_linkage_name
}),
536 if (auto Name
= dwarf::toString(findRecursively(DW_AT_name
), nullptr))
541 uint64_t DWARFDie::getDeclLine() const {
542 return toUnsigned(findRecursively(DW_AT_decl_line
), 0);
545 void DWARFDie::getCallerFrame(uint32_t &CallFile
, uint32_t &CallLine
,
546 uint32_t &CallColumn
,
547 uint32_t &CallDiscriminator
) const {
548 CallFile
= toUnsigned(find(DW_AT_call_file
), 0);
549 CallLine
= toUnsigned(find(DW_AT_call_line
), 0);
550 CallColumn
= toUnsigned(find(DW_AT_call_column
), 0);
551 CallDiscriminator
= toUnsigned(find(DW_AT_GNU_discriminator
), 0);
554 /// Helper to dump a DIE with all of its parents, but no siblings.
555 static unsigned dumpParentChain(DWARFDie Die
, raw_ostream
&OS
, unsigned Indent
,
556 DIDumpOptions DumpOpts
, unsigned Depth
= 0) {
559 if (DumpOpts
.ParentRecurseDepth
> 0 && Depth
>= DumpOpts
.ParentRecurseDepth
)
561 Indent
= dumpParentChain(Die
.getParent(), OS
, Indent
, DumpOpts
, Depth
+ 1);
562 Die
.dump(OS
, Indent
, DumpOpts
);
566 void DWARFDie::dump(raw_ostream
&OS
, unsigned Indent
,
567 DIDumpOptions DumpOpts
) const {
570 DWARFDataExtractor debug_info_data
= U
->getDebugInfoExtractor();
571 const uint64_t Offset
= getOffset();
572 uint64_t offset
= Offset
;
573 if (DumpOpts
.ShowParents
) {
574 DIDumpOptions ParentDumpOpts
= DumpOpts
;
575 ParentDumpOpts
.ShowParents
= false;
576 ParentDumpOpts
.ShowChildren
= false;
577 Indent
= dumpParentChain(getParent(), OS
, Indent
, ParentDumpOpts
);
580 if (debug_info_data
.isValidOffset(offset
)) {
581 uint32_t abbrCode
= debug_info_data
.getULEB128(&offset
);
582 if (DumpOpts
.ShowAddresses
)
583 WithColor(OS
, HighlightColor::Address
).get()
584 << format("\n0x%8.8" PRIx64
": ", Offset
);
587 auto AbbrevDecl
= getAbbreviationDeclarationPtr();
589 WithColor(OS
, HighlightColor::Tag
).get().indent(Indent
)
590 << formatv("{0}", getTag());
591 if (DumpOpts
.Verbose
)
592 OS
<< format(" [%u] %c", abbrCode
,
593 AbbrevDecl
->hasChildren() ? '*' : ' ');
596 // Dump all data in the DIE for the attributes.
597 for (const auto &AttrSpec
: AbbrevDecl
->attributes()) {
598 if (AttrSpec
.Form
== DW_FORM_implicit_const
) {
599 // We are dumping .debug_info section ,
600 // implicit_const attribute values are not really stored here,
601 // but in .debug_abbrev section. So we just skip such attrs.
604 dumpAttribute(OS
, *this, &offset
, AttrSpec
.Attr
, AttrSpec
.Form
,
608 DWARFDie child
= getFirstChild();
609 if (DumpOpts
.ShowChildren
&& DumpOpts
.ChildRecurseDepth
> 0 && child
) {
610 DumpOpts
.ChildRecurseDepth
--;
611 DIDumpOptions ChildDumpOpts
= DumpOpts
;
612 ChildDumpOpts
.ShowParents
= false;
614 child
.dump(OS
, Indent
+ 2, ChildDumpOpts
);
615 child
= child
.getSibling();
619 OS
<< "Abbreviation code not found in 'debug_abbrev' class for code: "
623 OS
.indent(Indent
) << "NULL\n";
628 LLVM_DUMP_METHOD
void DWARFDie::dump() const { dump(llvm::errs(), 0); }
630 DWARFDie
DWARFDie::getParent() const {
632 return U
->getParent(Die
);
636 DWARFDie
DWARFDie::getSibling() const {
638 return U
->getSibling(Die
);
642 DWARFDie
DWARFDie::getPreviousSibling() const {
644 return U
->getPreviousSibling(Die
);
648 DWARFDie
DWARFDie::getFirstChild() const {
650 return U
->getFirstChild(Die
);
654 DWARFDie
DWARFDie::getLastChild() const {
656 return U
->getLastChild(Die
);
660 iterator_range
<DWARFDie::attribute_iterator
> DWARFDie::attributes() const {
661 return make_range(attribute_iterator(*this, false),
662 attribute_iterator(*this, true));
665 DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D
, bool End
)
667 auto AbbrDecl
= Die
.getAbbreviationDeclarationPtr();
668 assert(AbbrDecl
&& "Must have abbreviation declaration");
670 // This is the end iterator so we set the index to the attribute count.
671 Index
= AbbrDecl
->getNumAttributes();
673 // This is the begin iterator so we extract the value for this->Index.
674 AttrValue
.Offset
= D
.getOffset() + AbbrDecl
->getCodeByteSize();
675 updateForIndex(*AbbrDecl
, 0);
679 void DWARFDie::attribute_iterator::updateForIndex(
680 const DWARFAbbreviationDeclaration
&AbbrDecl
, uint32_t I
) {
682 // AbbrDecl must be valid before calling this function.
683 auto NumAttrs
= AbbrDecl
.getNumAttributes();
684 if (Index
< NumAttrs
) {
685 AttrValue
.Attr
= AbbrDecl
.getAttrByIndex(Index
);
686 // Add the previous byte size of any previous attribute value.
687 AttrValue
.Offset
+= AttrValue
.ByteSize
;
688 uint64_t ParseOffset
= AttrValue
.Offset
;
689 auto U
= Die
.getDwarfUnit();
690 assert(U
&& "Die must have valid DWARF unit");
691 AttrValue
.Value
= DWARFFormValue::createFromUnit(
692 AbbrDecl
.getFormByIndex(Index
), U
, &ParseOffset
);
693 AttrValue
.ByteSize
= ParseOffset
- AttrValue
.Offset
;
695 assert(Index
== NumAttrs
&& "Indexes should be [0, NumAttrs) only");
700 DWARFDie::attribute_iterator
&DWARFDie::attribute_iterator::operator++() {
701 if (auto AbbrDecl
= Die
.getAbbreviationDeclarationPtr())
702 updateForIndex(*AbbrDecl
, Index
+ 1);
706 bool DWARFAttribute::mayHaveLocationDescription(dwarf::Attribute Attr
) {
708 // From the DWARF v5 specification.
710 case DW_AT_byte_size
:
712 case DW_AT_string_length
:
713 case DW_AT_lower_bound
:
714 case DW_AT_return_addr
:
715 case DW_AT_bit_stride
:
716 case DW_AT_upper_bound
:
718 case DW_AT_data_member_location
:
719 case DW_AT_frame_base
:
721 case DW_AT_static_link
:
722 case DW_AT_use_location
:
723 case DW_AT_vtable_elem_location
:
724 case DW_AT_allocated
:
725 case DW_AT_associated
:
726 case DW_AT_byte_stride
:
728 case DW_AT_call_value
:
729 case DW_AT_call_origin
:
730 case DW_AT_call_target
:
731 case DW_AT_call_target_clobbered
:
732 case DW_AT_call_data_location
:
733 case DW_AT_call_data_value
:
735 case DW_AT_GNU_call_site_value
:
736 case DW_AT_GNU_call_site_target
: