xref: /openbsd-src/gnu/llvm/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp (revision 09467b48e8bc8b4905716062da846024139afbf2)
1*09467b48Spatrick //===- DWARFDie.cpp -------------------------------------------------------===//
2*09467b48Spatrick //
3*09467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*09467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*09467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*09467b48Spatrick //
7*09467b48Spatrick //===----------------------------------------------------------------------===//
8*09467b48Spatrick 
9*09467b48Spatrick #include "llvm/DebugInfo/DWARF/DWARFDie.h"
10*09467b48Spatrick #include "llvm/ADT/None.h"
11*09467b48Spatrick #include "llvm/ADT/Optional.h"
12*09467b48Spatrick #include "llvm/ADT/SmallSet.h"
13*09467b48Spatrick #include "llvm/ADT/StringRef.h"
14*09467b48Spatrick #include "llvm/BinaryFormat/Dwarf.h"
15*09467b48Spatrick #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
16*09467b48Spatrick #include "llvm/DebugInfo/DWARF/DWARFContext.h"
17*09467b48Spatrick #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
18*09467b48Spatrick #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
19*09467b48Spatrick #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
20*09467b48Spatrick #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
21*09467b48Spatrick #include "llvm/Object/ObjectFile.h"
22*09467b48Spatrick #include "llvm/Support/DataExtractor.h"
23*09467b48Spatrick #include "llvm/Support/Format.h"
24*09467b48Spatrick #include "llvm/Support/FormatAdapters.h"
25*09467b48Spatrick #include "llvm/Support/FormatVariadic.h"
26*09467b48Spatrick #include "llvm/Support/MathExtras.h"
27*09467b48Spatrick #include "llvm/Support/WithColor.h"
28*09467b48Spatrick #include "llvm/Support/raw_ostream.h"
29*09467b48Spatrick #include <algorithm>
30*09467b48Spatrick #include <cassert>
31*09467b48Spatrick #include <cinttypes>
32*09467b48Spatrick #include <cstdint>
33*09467b48Spatrick #include <string>
34*09467b48Spatrick #include <utility>
35*09467b48Spatrick 
36*09467b48Spatrick using namespace llvm;
37*09467b48Spatrick using namespace dwarf;
38*09467b48Spatrick using namespace object;
39*09467b48Spatrick 
40*09467b48Spatrick static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
41*09467b48Spatrick   OS << " (";
42*09467b48Spatrick   do {
43*09467b48Spatrick     uint64_t Shift = countTrailingZeros(Val);
44*09467b48Spatrick     assert(Shift < 64 && "undefined behavior");
45*09467b48Spatrick     uint64_t Bit = 1ULL << Shift;
46*09467b48Spatrick     auto PropName = ApplePropertyString(Bit);
47*09467b48Spatrick     if (!PropName.empty())
48*09467b48Spatrick       OS << PropName;
49*09467b48Spatrick     else
50*09467b48Spatrick       OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit);
51*09467b48Spatrick     if (!(Val ^= Bit))
52*09467b48Spatrick       break;
53*09467b48Spatrick     OS << ", ";
54*09467b48Spatrick   } while (true);
55*09467b48Spatrick   OS << ")";
56*09467b48Spatrick }
57*09467b48Spatrick 
58*09467b48Spatrick static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS,
59*09467b48Spatrick                        const DWARFAddressRangesVector &Ranges,
60*09467b48Spatrick                        unsigned AddressSize, unsigned Indent,
61*09467b48Spatrick                        const DIDumpOptions &DumpOpts) {
62*09467b48Spatrick   if (!DumpOpts.ShowAddresses)
63*09467b48Spatrick     return;
64*09467b48Spatrick 
65*09467b48Spatrick   for (const DWARFAddressRange &R : Ranges) {
66*09467b48Spatrick     OS << '\n';
67*09467b48Spatrick     OS.indent(Indent);
68*09467b48Spatrick     R.dump(OS, AddressSize, DumpOpts, &Obj);
69*09467b48Spatrick   }
70*09467b48Spatrick }
71*09467b48Spatrick 
72*09467b48Spatrick static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
73*09467b48Spatrick                          DWARFUnit *U, unsigned Indent,
74*09467b48Spatrick                          DIDumpOptions DumpOpts) {
75*09467b48Spatrick   DWARFContext &Ctx = U->getContext();
76*09467b48Spatrick   const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
77*09467b48Spatrick   if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
78*09467b48Spatrick       FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) {
79*09467b48Spatrick     ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
80*09467b48Spatrick     DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
81*09467b48Spatrick                        Ctx.isLittleEndian(), 0);
82*09467b48Spatrick     DWARFExpression(Data, U->getVersion(), U->getAddressByteSize())
83*09467b48Spatrick         .print(OS, MRI, U);
84*09467b48Spatrick     return;
85*09467b48Spatrick   }
86*09467b48Spatrick 
87*09467b48Spatrick   if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
88*09467b48Spatrick     uint64_t Offset = *FormValue.getAsSectionOffset();
89*09467b48Spatrick 
90*09467b48Spatrick     if (FormValue.getForm() == DW_FORM_loclistx) {
91*09467b48Spatrick       FormValue.dump(OS, DumpOpts);
92*09467b48Spatrick 
93*09467b48Spatrick       if (auto LoclistOffset = U->getLoclistOffset(Offset))
94*09467b48Spatrick         Offset = *LoclistOffset;
95*09467b48Spatrick       else
96*09467b48Spatrick         return;
97*09467b48Spatrick     }
98*09467b48Spatrick     U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(),
99*09467b48Spatrick                                            MRI, Ctx.getDWARFObj(), U, DumpOpts,
100*09467b48Spatrick                                            Indent);
101*09467b48Spatrick     return;
102*09467b48Spatrick   }
103*09467b48Spatrick 
104*09467b48Spatrick   FormValue.dump(OS, DumpOpts);
105*09467b48Spatrick }
106*09467b48Spatrick 
107*09467b48Spatrick /// Dump the name encoded in the type tag.
108*09467b48Spatrick static void dumpTypeTagName(raw_ostream &OS, dwarf::Tag T) {
109*09467b48Spatrick   StringRef TagStr = TagString(T);
110*09467b48Spatrick   if (!TagStr.startswith("DW_TAG_") || !TagStr.endswith("_type"))
111*09467b48Spatrick     return;
112*09467b48Spatrick   OS << TagStr.substr(7, TagStr.size() - 12) << " ";
113*09467b48Spatrick }
114*09467b48Spatrick 
115*09467b48Spatrick static void dumpArrayType(raw_ostream &OS, const DWARFDie &D) {
116*09467b48Spatrick   Optional<uint64_t> Bound;
117*09467b48Spatrick   for (const DWARFDie &C : D.children())
118*09467b48Spatrick     if (C.getTag() == DW_TAG_subrange_type) {
119*09467b48Spatrick       Optional<uint64_t> LB;
120*09467b48Spatrick       Optional<uint64_t> Count;
121*09467b48Spatrick       Optional<uint64_t> UB;
122*09467b48Spatrick       Optional<unsigned> DefaultLB;
123*09467b48Spatrick       if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
124*09467b48Spatrick         LB = L->getAsUnsignedConstant();
125*09467b48Spatrick       if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
126*09467b48Spatrick         Count = CountV->getAsUnsignedConstant();
127*09467b48Spatrick       if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
128*09467b48Spatrick         UB = UpperV->getAsUnsignedConstant();
129*09467b48Spatrick       if (Optional<DWARFFormValue> LV =
130*09467b48Spatrick               D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
131*09467b48Spatrick         if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
132*09467b48Spatrick           if ((DefaultLB =
133*09467b48Spatrick                    LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
134*09467b48Spatrick             if (LB && *LB == *DefaultLB)
135*09467b48Spatrick               LB = None;
136*09467b48Spatrick       if (!LB && !Count && !UB)
137*09467b48Spatrick         OS << "[]";
138*09467b48Spatrick       else if (!LB && (Count || UB) && DefaultLB)
139*09467b48Spatrick         OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
140*09467b48Spatrick       else {
141*09467b48Spatrick         OS << "[[";
142*09467b48Spatrick         if (LB)
143*09467b48Spatrick           OS << *LB;
144*09467b48Spatrick         else
145*09467b48Spatrick           OS << '?';
146*09467b48Spatrick         OS << ", ";
147*09467b48Spatrick         if (Count)
148*09467b48Spatrick           if (LB)
149*09467b48Spatrick             OS << *LB + *Count;
150*09467b48Spatrick           else
151*09467b48Spatrick             OS << "? + " << *Count;
152*09467b48Spatrick         else if (UB)
153*09467b48Spatrick           OS << *UB + 1;
154*09467b48Spatrick         else
155*09467b48Spatrick           OS << '?';
156*09467b48Spatrick         OS << ")]";
157*09467b48Spatrick       }
158*09467b48Spatrick     }
159*09467b48Spatrick }
160*09467b48Spatrick 
161*09467b48Spatrick /// Recursively dump the DIE type name when applicable.
162*09467b48Spatrick static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) {
163*09467b48Spatrick   if (!D.isValid())
164*09467b48Spatrick     return;
165*09467b48Spatrick 
166*09467b48Spatrick   if (const char *Name = D.getName(DINameKind::LinkageName)) {
167*09467b48Spatrick     OS << Name;
168*09467b48Spatrick     return;
169*09467b48Spatrick   }
170*09467b48Spatrick 
171*09467b48Spatrick   // FIXME: We should have pretty printers per language. Currently we print
172*09467b48Spatrick   // everything as if it was C++ and fall back to the TAG type name.
173*09467b48Spatrick   const dwarf::Tag T = D.getTag();
174*09467b48Spatrick   switch (T) {
175*09467b48Spatrick   case DW_TAG_array_type:
176*09467b48Spatrick   case DW_TAG_pointer_type:
177*09467b48Spatrick   case DW_TAG_ptr_to_member_type:
178*09467b48Spatrick   case DW_TAG_reference_type:
179*09467b48Spatrick   case DW_TAG_rvalue_reference_type:
180*09467b48Spatrick   case DW_TAG_subroutine_type:
181*09467b48Spatrick     break;
182*09467b48Spatrick   default:
183*09467b48Spatrick     dumpTypeTagName(OS, T);
184*09467b48Spatrick   }
185*09467b48Spatrick 
186*09467b48Spatrick   // Follow the DW_AT_type if possible.
187*09467b48Spatrick   DWARFDie TypeDie = D.getAttributeValueAsReferencedDie(DW_AT_type);
188*09467b48Spatrick   dumpTypeName(OS, TypeDie);
189*09467b48Spatrick 
190*09467b48Spatrick   switch (T) {
191*09467b48Spatrick   case DW_TAG_subroutine_type: {
192*09467b48Spatrick     if (!TypeDie)
193*09467b48Spatrick       OS << "void";
194*09467b48Spatrick     OS << '(';
195*09467b48Spatrick     bool First = true;
196*09467b48Spatrick     for (const DWARFDie &C : D.children()) {
197*09467b48Spatrick       if (C.getTag() == DW_TAG_formal_parameter) {
198*09467b48Spatrick         if (!First)
199*09467b48Spatrick           OS << ", ";
200*09467b48Spatrick         First = false;
201*09467b48Spatrick         dumpTypeName(OS, C.getAttributeValueAsReferencedDie(DW_AT_type));
202*09467b48Spatrick       }
203*09467b48Spatrick     }
204*09467b48Spatrick     OS << ')';
205*09467b48Spatrick     break;
206*09467b48Spatrick   }
207*09467b48Spatrick   case DW_TAG_array_type: {
208*09467b48Spatrick     dumpArrayType(OS, D);
209*09467b48Spatrick     break;
210*09467b48Spatrick   }
211*09467b48Spatrick   case DW_TAG_pointer_type:
212*09467b48Spatrick     OS << '*';
213*09467b48Spatrick     break;
214*09467b48Spatrick   case DW_TAG_ptr_to_member_type:
215*09467b48Spatrick     if (DWARFDie Cont =
216*09467b48Spatrick             D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
217*09467b48Spatrick       dumpTypeName(OS << ' ', Cont);
218*09467b48Spatrick       OS << "::";
219*09467b48Spatrick     }
220*09467b48Spatrick     OS << '*';
221*09467b48Spatrick     break;
222*09467b48Spatrick   case DW_TAG_reference_type:
223*09467b48Spatrick     OS << '&';
224*09467b48Spatrick     break;
225*09467b48Spatrick   case DW_TAG_rvalue_reference_type:
226*09467b48Spatrick     OS << "&&";
227*09467b48Spatrick     break;
228*09467b48Spatrick   default:
229*09467b48Spatrick     break;
230*09467b48Spatrick   }
231*09467b48Spatrick }
232*09467b48Spatrick 
233*09467b48Spatrick static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
234*09467b48Spatrick                           uint64_t *OffsetPtr, dwarf::Attribute Attr,
235*09467b48Spatrick                           dwarf::Form Form, unsigned Indent,
236*09467b48Spatrick                           DIDumpOptions DumpOpts) {
237*09467b48Spatrick   if (!Die.isValid())
238*09467b48Spatrick     return;
239*09467b48Spatrick   const char BaseIndent[] = "            ";
240*09467b48Spatrick   OS << BaseIndent;
241*09467b48Spatrick   OS.indent(Indent + 2);
242*09467b48Spatrick   WithColor(OS, HighlightColor::Attribute) << formatv("{0}", Attr);
243*09467b48Spatrick 
244*09467b48Spatrick   if (DumpOpts.Verbose || DumpOpts.ShowForm)
245*09467b48Spatrick     OS << formatv(" [{0}]", Form);
246*09467b48Spatrick 
247*09467b48Spatrick   DWARFUnit *U = Die.getDwarfUnit();
248*09467b48Spatrick   DWARFFormValue FormValue = DWARFFormValue::createFromUnit(Form, U, OffsetPtr);
249*09467b48Spatrick 
250*09467b48Spatrick   OS << "\t(";
251*09467b48Spatrick 
252*09467b48Spatrick   StringRef Name;
253*09467b48Spatrick   std::string File;
254*09467b48Spatrick   auto Color = HighlightColor::Enumerator;
255*09467b48Spatrick   if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
256*09467b48Spatrick     Color = HighlightColor::String;
257*09467b48Spatrick     if (const auto *LT = U->getContext().getLineTableForUnit(U))
258*09467b48Spatrick       if (LT->getFileNameByIndex(
259*09467b48Spatrick               FormValue.getAsUnsignedConstant().getValue(),
260*09467b48Spatrick               U->getCompilationDir(),
261*09467b48Spatrick               DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
262*09467b48Spatrick         File = '"' + File + '"';
263*09467b48Spatrick         Name = File;
264*09467b48Spatrick       }
265*09467b48Spatrick   } else if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant())
266*09467b48Spatrick     Name = AttributeValueString(Attr, *Val);
267*09467b48Spatrick 
268*09467b48Spatrick   if (!Name.empty())
269*09467b48Spatrick     WithColor(OS, Color) << Name;
270*09467b48Spatrick   else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
271*09467b48Spatrick     OS << *FormValue.getAsUnsignedConstant();
272*09467b48Spatrick   else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
273*09467b48Spatrick            FormValue.getAsUnsignedConstant()) {
274*09467b48Spatrick     if (DumpOpts.ShowAddresses) {
275*09467b48Spatrick       // Print the actual address rather than the offset.
276*09467b48Spatrick       uint64_t LowPC, HighPC, Index;
277*09467b48Spatrick       if (Die.getLowAndHighPC(LowPC, HighPC, Index))
278*09467b48Spatrick         OS << format("0x%016" PRIx64, HighPC);
279*09467b48Spatrick       else
280*09467b48Spatrick         FormValue.dump(OS, DumpOpts);
281*09467b48Spatrick     }
282*09467b48Spatrick   } else if (Form == dwarf::Form::DW_FORM_exprloc ||
283*09467b48Spatrick              DWARFAttribute::mayHaveLocationDescription(Attr))
284*09467b48Spatrick     dumpLocation(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
285*09467b48Spatrick   else
286*09467b48Spatrick     FormValue.dump(OS, DumpOpts);
287*09467b48Spatrick 
288*09467b48Spatrick   std::string Space = DumpOpts.ShowAddresses ? " " : "";
289*09467b48Spatrick 
290*09467b48Spatrick   // We have dumped the attribute raw value. For some attributes
291*09467b48Spatrick   // having both the raw value and the pretty-printed value is
292*09467b48Spatrick   // interesting. These attributes are handled below.
293*09467b48Spatrick   if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
294*09467b48Spatrick     if (const char *Name =
295*09467b48Spatrick             Die.getAttributeValueAsReferencedDie(FormValue).getName(
296*09467b48Spatrick                 DINameKind::LinkageName))
297*09467b48Spatrick       OS << Space << "\"" << Name << '\"';
298*09467b48Spatrick   } else if (Attr == DW_AT_type) {
299*09467b48Spatrick     OS << Space << "\"";
300*09467b48Spatrick     dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(FormValue));
301*09467b48Spatrick     OS << '"';
302*09467b48Spatrick   } else if (Attr == DW_AT_APPLE_property_attribute) {
303*09467b48Spatrick     if (Optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant())
304*09467b48Spatrick       dumpApplePropertyAttribute(OS, *OptVal);
305*09467b48Spatrick   } else if (Attr == DW_AT_ranges) {
306*09467b48Spatrick     const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj();
307*09467b48Spatrick     // For DW_FORM_rnglistx we need to dump the offset separately, since
308*09467b48Spatrick     // we have only dumped the index so far.
309*09467b48Spatrick     if (FormValue.getForm() == DW_FORM_rnglistx)
310*09467b48Spatrick       if (auto RangeListOffset =
311*09467b48Spatrick               U->getRnglistOffset(*FormValue.getAsSectionOffset())) {
312*09467b48Spatrick         DWARFFormValue FV = DWARFFormValue::createFromUValue(
313*09467b48Spatrick             dwarf::DW_FORM_sec_offset, *RangeListOffset);
314*09467b48Spatrick         FV.dump(OS, DumpOpts);
315*09467b48Spatrick       }
316*09467b48Spatrick     if (auto RangesOrError = Die.getAddressRanges())
317*09467b48Spatrick       dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(),
318*09467b48Spatrick                  sizeof(BaseIndent) + Indent + 4, DumpOpts);
319*09467b48Spatrick     else
320*09467b48Spatrick       WithColor::error() << "decoding address ranges: "
321*09467b48Spatrick                          << toString(RangesOrError.takeError()) << '\n';
322*09467b48Spatrick   }
323*09467b48Spatrick 
324*09467b48Spatrick   OS << ")\n";
325*09467b48Spatrick }
326*09467b48Spatrick 
327*09467b48Spatrick bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram; }
328*09467b48Spatrick 
329*09467b48Spatrick bool DWARFDie::isSubroutineDIE() const {
330*09467b48Spatrick   auto Tag = getTag();
331*09467b48Spatrick   return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine;
332*09467b48Spatrick }
333*09467b48Spatrick 
334*09467b48Spatrick Optional<DWARFFormValue> DWARFDie::find(dwarf::Attribute Attr) const {
335*09467b48Spatrick   if (!isValid())
336*09467b48Spatrick     return None;
337*09467b48Spatrick   auto AbbrevDecl = getAbbreviationDeclarationPtr();
338*09467b48Spatrick   if (AbbrevDecl)
339*09467b48Spatrick     return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U);
340*09467b48Spatrick   return None;
341*09467b48Spatrick }
342*09467b48Spatrick 
343*09467b48Spatrick Optional<DWARFFormValue>
344*09467b48Spatrick DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const {
345*09467b48Spatrick   if (!isValid())
346*09467b48Spatrick     return None;
347*09467b48Spatrick   auto AbbrevDecl = getAbbreviationDeclarationPtr();
348*09467b48Spatrick   if (AbbrevDecl) {
349*09467b48Spatrick     for (auto Attr : Attrs) {
350*09467b48Spatrick       if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U))
351*09467b48Spatrick         return Value;
352*09467b48Spatrick     }
353*09467b48Spatrick   }
354*09467b48Spatrick   return None;
355*09467b48Spatrick }
356*09467b48Spatrick 
357*09467b48Spatrick Optional<DWARFFormValue>
358*09467b48Spatrick DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
359*09467b48Spatrick   std::vector<DWARFDie> Worklist;
360*09467b48Spatrick   Worklist.push_back(*this);
361*09467b48Spatrick 
362*09467b48Spatrick   // Keep track if DIEs already seen to prevent infinite recursion.
363*09467b48Spatrick   // Empirically we rarely see a depth of more than 3 when dealing with valid
364*09467b48Spatrick   // DWARF. This corresponds to following the DW_AT_abstract_origin and
365*09467b48Spatrick   // DW_AT_specification just once.
366*09467b48Spatrick   SmallSet<DWARFDie, 3> Seen;
367*09467b48Spatrick   Seen.insert(*this);
368*09467b48Spatrick 
369*09467b48Spatrick   while (!Worklist.empty()) {
370*09467b48Spatrick     DWARFDie Die = Worklist.back();
371*09467b48Spatrick     Worklist.pop_back();
372*09467b48Spatrick 
373*09467b48Spatrick     if (!Die.isValid())
374*09467b48Spatrick       continue;
375*09467b48Spatrick 
376*09467b48Spatrick     if (auto Value = Die.find(Attrs))
377*09467b48Spatrick       return Value;
378*09467b48Spatrick 
379*09467b48Spatrick     if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
380*09467b48Spatrick       if (Seen.insert(D).second)
381*09467b48Spatrick         Worklist.push_back(D);
382*09467b48Spatrick 
383*09467b48Spatrick     if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
384*09467b48Spatrick       if (Seen.insert(D).second)
385*09467b48Spatrick         Worklist.push_back(D);
386*09467b48Spatrick   }
387*09467b48Spatrick 
388*09467b48Spatrick   return None;
389*09467b48Spatrick }
390*09467b48Spatrick 
391*09467b48Spatrick DWARFDie
392*09467b48Spatrick DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
393*09467b48Spatrick   if (Optional<DWARFFormValue> F = find(Attr))
394*09467b48Spatrick     return getAttributeValueAsReferencedDie(*F);
395*09467b48Spatrick   return DWARFDie();
396*09467b48Spatrick }
397*09467b48Spatrick 
398*09467b48Spatrick DWARFDie
399*09467b48Spatrick DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const {
400*09467b48Spatrick   if (auto SpecRef = V.getAsRelativeReference()) {
401*09467b48Spatrick     if (SpecRef->Unit)
402*09467b48Spatrick       return SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() + SpecRef->Offset);
403*09467b48Spatrick     if (auto SpecUnit = U->getUnitVector().getUnitForOffset(SpecRef->Offset))
404*09467b48Spatrick       return SpecUnit->getDIEForOffset(SpecRef->Offset);
405*09467b48Spatrick   }
406*09467b48Spatrick   return DWARFDie();
407*09467b48Spatrick }
408*09467b48Spatrick 
409*09467b48Spatrick Optional<uint64_t> DWARFDie::getRangesBaseAttribute() const {
410*09467b48Spatrick   return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
411*09467b48Spatrick }
412*09467b48Spatrick 
413*09467b48Spatrick Optional<uint64_t> DWARFDie::getLocBaseAttribute() const {
414*09467b48Spatrick   return toSectionOffset(find(DW_AT_loclists_base));
415*09467b48Spatrick }
416*09467b48Spatrick 
417*09467b48Spatrick Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
418*09467b48Spatrick   if (auto FormValue = find(DW_AT_high_pc)) {
419*09467b48Spatrick     if (auto Address = FormValue->getAsAddress()) {
420*09467b48Spatrick       // High PC is an address.
421*09467b48Spatrick       return Address;
422*09467b48Spatrick     }
423*09467b48Spatrick     if (auto Offset = FormValue->getAsUnsignedConstant()) {
424*09467b48Spatrick       // High PC is an offset from LowPC.
425*09467b48Spatrick       return LowPC + *Offset;
426*09467b48Spatrick     }
427*09467b48Spatrick   }
428*09467b48Spatrick   return None;
429*09467b48Spatrick }
430*09467b48Spatrick 
431*09467b48Spatrick bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
432*09467b48Spatrick                                uint64_t &SectionIndex) const {
433*09467b48Spatrick   auto F = find(DW_AT_low_pc);
434*09467b48Spatrick   auto LowPcAddr = toSectionedAddress(F);
435*09467b48Spatrick   if (!LowPcAddr)
436*09467b48Spatrick     return false;
437*09467b48Spatrick   if (auto HighPcAddr = getHighPC(LowPcAddr->Address)) {
438*09467b48Spatrick     LowPC = LowPcAddr->Address;
439*09467b48Spatrick     HighPC = *HighPcAddr;
440*09467b48Spatrick     SectionIndex = LowPcAddr->SectionIndex;
441*09467b48Spatrick     return true;
442*09467b48Spatrick   }
443*09467b48Spatrick   return false;
444*09467b48Spatrick }
445*09467b48Spatrick 
446*09467b48Spatrick Expected<DWARFAddressRangesVector> DWARFDie::getAddressRanges() const {
447*09467b48Spatrick   if (isNULL())
448*09467b48Spatrick     return DWARFAddressRangesVector();
449*09467b48Spatrick   // Single range specified by low/high PC.
450*09467b48Spatrick   uint64_t LowPC, HighPC, Index;
451*09467b48Spatrick   if (getLowAndHighPC(LowPC, HighPC, Index))
452*09467b48Spatrick     return DWARFAddressRangesVector{{LowPC, HighPC, Index}};
453*09467b48Spatrick 
454*09467b48Spatrick   Optional<DWARFFormValue> Value = find(DW_AT_ranges);
455*09467b48Spatrick   if (Value) {
456*09467b48Spatrick     if (Value->getForm() == DW_FORM_rnglistx)
457*09467b48Spatrick       return U->findRnglistFromIndex(*Value->getAsSectionOffset());
458*09467b48Spatrick     return U->findRnglistFromOffset(*Value->getAsSectionOffset());
459*09467b48Spatrick   }
460*09467b48Spatrick   return DWARFAddressRangesVector();
461*09467b48Spatrick }
462*09467b48Spatrick 
463*09467b48Spatrick void DWARFDie::collectChildrenAddressRanges(
464*09467b48Spatrick     DWARFAddressRangesVector &Ranges) const {
465*09467b48Spatrick   if (isNULL())
466*09467b48Spatrick     return;
467*09467b48Spatrick   if (isSubprogramDIE()) {
468*09467b48Spatrick     if (auto DIERangesOrError = getAddressRanges())
469*09467b48Spatrick       Ranges.insert(Ranges.end(), DIERangesOrError.get().begin(),
470*09467b48Spatrick                     DIERangesOrError.get().end());
471*09467b48Spatrick     else
472*09467b48Spatrick       llvm::consumeError(DIERangesOrError.takeError());
473*09467b48Spatrick   }
474*09467b48Spatrick 
475*09467b48Spatrick   for (auto Child : children())
476*09467b48Spatrick     Child.collectChildrenAddressRanges(Ranges);
477*09467b48Spatrick }
478*09467b48Spatrick 
479*09467b48Spatrick bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
480*09467b48Spatrick   auto RangesOrError = getAddressRanges();
481*09467b48Spatrick   if (!RangesOrError) {
482*09467b48Spatrick     llvm::consumeError(RangesOrError.takeError());
483*09467b48Spatrick     return false;
484*09467b48Spatrick   }
485*09467b48Spatrick 
486*09467b48Spatrick   for (const auto &R : RangesOrError.get())
487*09467b48Spatrick     if (R.LowPC <= Address && Address < R.HighPC)
488*09467b48Spatrick       return true;
489*09467b48Spatrick   return false;
490*09467b48Spatrick }
491*09467b48Spatrick 
492*09467b48Spatrick Expected<DWARFLocationExpressionsVector>
493*09467b48Spatrick DWARFDie::getLocations(dwarf::Attribute Attr) const {
494*09467b48Spatrick   Optional<DWARFFormValue> Location = find(Attr);
495*09467b48Spatrick   if (!Location)
496*09467b48Spatrick     return createStringError(inconvertibleErrorCode(), "No %s",
497*09467b48Spatrick                              dwarf::AttributeString(Attr).data());
498*09467b48Spatrick 
499*09467b48Spatrick   if (Optional<uint64_t> Off = Location->getAsSectionOffset()) {
500*09467b48Spatrick     uint64_t Offset = *Off;
501*09467b48Spatrick 
502*09467b48Spatrick     if (Location->getForm() == DW_FORM_loclistx) {
503*09467b48Spatrick       if (auto LoclistOffset = U->getLoclistOffset(Offset))
504*09467b48Spatrick         Offset = *LoclistOffset;
505*09467b48Spatrick       else
506*09467b48Spatrick         return createStringError(inconvertibleErrorCode(),
507*09467b48Spatrick                                  "Loclist table not found");
508*09467b48Spatrick     }
509*09467b48Spatrick     return U->findLoclistFromOffset(Offset);
510*09467b48Spatrick   }
511*09467b48Spatrick 
512*09467b48Spatrick   if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
513*09467b48Spatrick     return DWARFLocationExpressionsVector{
514*09467b48Spatrick         DWARFLocationExpression{None, to_vector<4>(*Expr)}};
515*09467b48Spatrick   }
516*09467b48Spatrick 
517*09467b48Spatrick   return createStringError(
518*09467b48Spatrick       inconvertibleErrorCode(), "Unsupported %s encoding: %s",
519*09467b48Spatrick       dwarf::AttributeString(Attr).data(),
520*09467b48Spatrick       dwarf::FormEncodingString(Location->getForm()).data());
521*09467b48Spatrick }
522*09467b48Spatrick 
523*09467b48Spatrick const char *DWARFDie::getSubroutineName(DINameKind Kind) const {
524*09467b48Spatrick   if (!isSubroutineDIE())
525*09467b48Spatrick     return nullptr;
526*09467b48Spatrick   return getName(Kind);
527*09467b48Spatrick }
528*09467b48Spatrick 
529*09467b48Spatrick const char *DWARFDie::getName(DINameKind Kind) const {
530*09467b48Spatrick   if (!isValid() || Kind == DINameKind::None)
531*09467b48Spatrick     return nullptr;
532*09467b48Spatrick   // Try to get mangled name only if it was asked for.
533*09467b48Spatrick   if (Kind == DINameKind::LinkageName) {
534*09467b48Spatrick     if (auto Name = dwarf::toString(
535*09467b48Spatrick             findRecursively({DW_AT_MIPS_linkage_name, DW_AT_linkage_name}),
536*09467b48Spatrick             nullptr))
537*09467b48Spatrick       return Name;
538*09467b48Spatrick   }
539*09467b48Spatrick   if (auto Name = dwarf::toString(findRecursively(DW_AT_name), nullptr))
540*09467b48Spatrick     return Name;
541*09467b48Spatrick   return nullptr;
542*09467b48Spatrick }
543*09467b48Spatrick 
544*09467b48Spatrick uint64_t DWARFDie::getDeclLine() const {
545*09467b48Spatrick   return toUnsigned(findRecursively(DW_AT_decl_line), 0);
546*09467b48Spatrick }
547*09467b48Spatrick 
548*09467b48Spatrick void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
549*09467b48Spatrick                               uint32_t &CallColumn,
550*09467b48Spatrick                               uint32_t &CallDiscriminator) const {
551*09467b48Spatrick   CallFile = toUnsigned(find(DW_AT_call_file), 0);
552*09467b48Spatrick   CallLine = toUnsigned(find(DW_AT_call_line), 0);
553*09467b48Spatrick   CallColumn = toUnsigned(find(DW_AT_call_column), 0);
554*09467b48Spatrick   CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0);
555*09467b48Spatrick }
556*09467b48Spatrick 
557*09467b48Spatrick /// Helper to dump a DIE with all of its parents, but no siblings.
558*09467b48Spatrick static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent,
559*09467b48Spatrick                                 DIDumpOptions DumpOpts, unsigned Depth = 0) {
560*09467b48Spatrick   if (!Die)
561*09467b48Spatrick     return Indent;
562*09467b48Spatrick   if (DumpOpts.ParentRecurseDepth > 0 && Depth >= DumpOpts.ParentRecurseDepth)
563*09467b48Spatrick     return Indent;
564*09467b48Spatrick   Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts, Depth + 1);
565*09467b48Spatrick   Die.dump(OS, Indent, DumpOpts);
566*09467b48Spatrick   return Indent + 2;
567*09467b48Spatrick }
568*09467b48Spatrick 
569*09467b48Spatrick void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
570*09467b48Spatrick                     DIDumpOptions DumpOpts) const {
571*09467b48Spatrick   if (!isValid())
572*09467b48Spatrick     return;
573*09467b48Spatrick   DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
574*09467b48Spatrick   const uint64_t Offset = getOffset();
575*09467b48Spatrick   uint64_t offset = Offset;
576*09467b48Spatrick   if (DumpOpts.ShowParents) {
577*09467b48Spatrick     DIDumpOptions ParentDumpOpts = DumpOpts;
578*09467b48Spatrick     ParentDumpOpts.ShowParents = false;
579*09467b48Spatrick     ParentDumpOpts.ShowChildren = false;
580*09467b48Spatrick     Indent = dumpParentChain(getParent(), OS, Indent, ParentDumpOpts);
581*09467b48Spatrick   }
582*09467b48Spatrick 
583*09467b48Spatrick   if (debug_info_data.isValidOffset(offset)) {
584*09467b48Spatrick     uint32_t abbrCode = debug_info_data.getULEB128(&offset);
585*09467b48Spatrick     if (DumpOpts.ShowAddresses)
586*09467b48Spatrick       WithColor(OS, HighlightColor::Address).get()
587*09467b48Spatrick           << format("\n0x%8.8" PRIx64 ": ", Offset);
588*09467b48Spatrick 
589*09467b48Spatrick     if (abbrCode) {
590*09467b48Spatrick       auto AbbrevDecl = getAbbreviationDeclarationPtr();
591*09467b48Spatrick       if (AbbrevDecl) {
592*09467b48Spatrick         WithColor(OS, HighlightColor::Tag).get().indent(Indent)
593*09467b48Spatrick             << formatv("{0}", getTag());
594*09467b48Spatrick         if (DumpOpts.Verbose)
595*09467b48Spatrick           OS << format(" [%u] %c", abbrCode,
596*09467b48Spatrick                        AbbrevDecl->hasChildren() ? '*' : ' ');
597*09467b48Spatrick         OS << '\n';
598*09467b48Spatrick 
599*09467b48Spatrick         // Dump all data in the DIE for the attributes.
600*09467b48Spatrick         for (const auto &AttrSpec : AbbrevDecl->attributes()) {
601*09467b48Spatrick           if (AttrSpec.Form == DW_FORM_implicit_const) {
602*09467b48Spatrick             // We are dumping .debug_info section ,
603*09467b48Spatrick             // implicit_const attribute values are not really stored here,
604*09467b48Spatrick             // but in .debug_abbrev section. So we just skip such attrs.
605*09467b48Spatrick             continue;
606*09467b48Spatrick           }
607*09467b48Spatrick           dumpAttribute(OS, *this, &offset, AttrSpec.Attr, AttrSpec.Form,
608*09467b48Spatrick                         Indent, DumpOpts);
609*09467b48Spatrick         }
610*09467b48Spatrick 
611*09467b48Spatrick         DWARFDie child = getFirstChild();
612*09467b48Spatrick         if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) {
613*09467b48Spatrick           DumpOpts.ChildRecurseDepth--;
614*09467b48Spatrick           DIDumpOptions ChildDumpOpts = DumpOpts;
615*09467b48Spatrick           ChildDumpOpts.ShowParents = false;
616*09467b48Spatrick           while (child) {
617*09467b48Spatrick             child.dump(OS, Indent + 2, ChildDumpOpts);
618*09467b48Spatrick             child = child.getSibling();
619*09467b48Spatrick           }
620*09467b48Spatrick         }
621*09467b48Spatrick       } else {
622*09467b48Spatrick         OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
623*09467b48Spatrick            << abbrCode << '\n';
624*09467b48Spatrick       }
625*09467b48Spatrick     } else {
626*09467b48Spatrick       OS.indent(Indent) << "NULL\n";
627*09467b48Spatrick     }
628*09467b48Spatrick   }
629*09467b48Spatrick }
630*09467b48Spatrick 
631*09467b48Spatrick LLVM_DUMP_METHOD void DWARFDie::dump() const { dump(llvm::errs(), 0); }
632*09467b48Spatrick 
633*09467b48Spatrick DWARFDie DWARFDie::getParent() const {
634*09467b48Spatrick   if (isValid())
635*09467b48Spatrick     return U->getParent(Die);
636*09467b48Spatrick   return DWARFDie();
637*09467b48Spatrick }
638*09467b48Spatrick 
639*09467b48Spatrick DWARFDie DWARFDie::getSibling() const {
640*09467b48Spatrick   if (isValid())
641*09467b48Spatrick     return U->getSibling(Die);
642*09467b48Spatrick   return DWARFDie();
643*09467b48Spatrick }
644*09467b48Spatrick 
645*09467b48Spatrick DWARFDie DWARFDie::getPreviousSibling() const {
646*09467b48Spatrick   if (isValid())
647*09467b48Spatrick     return U->getPreviousSibling(Die);
648*09467b48Spatrick   return DWARFDie();
649*09467b48Spatrick }
650*09467b48Spatrick 
651*09467b48Spatrick DWARFDie DWARFDie::getFirstChild() const {
652*09467b48Spatrick   if (isValid())
653*09467b48Spatrick     return U->getFirstChild(Die);
654*09467b48Spatrick   return DWARFDie();
655*09467b48Spatrick }
656*09467b48Spatrick 
657*09467b48Spatrick DWARFDie DWARFDie::getLastChild() const {
658*09467b48Spatrick   if (isValid())
659*09467b48Spatrick     return U->getLastChild(Die);
660*09467b48Spatrick   return DWARFDie();
661*09467b48Spatrick }
662*09467b48Spatrick 
663*09467b48Spatrick iterator_range<DWARFDie::attribute_iterator> DWARFDie::attributes() const {
664*09467b48Spatrick   return make_range(attribute_iterator(*this, false),
665*09467b48Spatrick                     attribute_iterator(*this, true));
666*09467b48Spatrick }
667*09467b48Spatrick 
668*09467b48Spatrick DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D, bool End)
669*09467b48Spatrick     : Die(D), Index(0) {
670*09467b48Spatrick   auto AbbrDecl = Die.getAbbreviationDeclarationPtr();
671*09467b48Spatrick   assert(AbbrDecl && "Must have abbreviation declaration");
672*09467b48Spatrick   if (End) {
673*09467b48Spatrick     // This is the end iterator so we set the index to the attribute count.
674*09467b48Spatrick     Index = AbbrDecl->getNumAttributes();
675*09467b48Spatrick   } else {
676*09467b48Spatrick     // This is the begin iterator so we extract the value for this->Index.
677*09467b48Spatrick     AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize();
678*09467b48Spatrick     updateForIndex(*AbbrDecl, 0);
679*09467b48Spatrick   }
680*09467b48Spatrick }
681*09467b48Spatrick 
682*09467b48Spatrick void DWARFDie::attribute_iterator::updateForIndex(
683*09467b48Spatrick     const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) {
684*09467b48Spatrick   Index = I;
685*09467b48Spatrick   // AbbrDecl must be valid before calling this function.
686*09467b48Spatrick   auto NumAttrs = AbbrDecl.getNumAttributes();
687*09467b48Spatrick   if (Index < NumAttrs) {
688*09467b48Spatrick     AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
689*09467b48Spatrick     // Add the previous byte size of any previous attribute value.
690*09467b48Spatrick     AttrValue.Offset += AttrValue.ByteSize;
691*09467b48Spatrick     uint64_t ParseOffset = AttrValue.Offset;
692*09467b48Spatrick     auto U = Die.getDwarfUnit();
693*09467b48Spatrick     assert(U && "Die must have valid DWARF unit");
694*09467b48Spatrick     AttrValue.Value = DWARFFormValue::createFromUnit(
695*09467b48Spatrick         AbbrDecl.getFormByIndex(Index), U, &ParseOffset);
696*09467b48Spatrick     AttrValue.ByteSize = ParseOffset - AttrValue.Offset;
697*09467b48Spatrick   } else {
698*09467b48Spatrick     assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only");
699*09467b48Spatrick     AttrValue = {};
700*09467b48Spatrick   }
701*09467b48Spatrick }
702*09467b48Spatrick 
703*09467b48Spatrick DWARFDie::attribute_iterator &DWARFDie::attribute_iterator::operator++() {
704*09467b48Spatrick   if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr())
705*09467b48Spatrick     updateForIndex(*AbbrDecl, Index + 1);
706*09467b48Spatrick   return *this;
707*09467b48Spatrick }
708*09467b48Spatrick 
709*09467b48Spatrick bool DWARFAttribute::mayHaveLocationDescription(dwarf::Attribute Attr) {
710*09467b48Spatrick   switch (Attr) {
711*09467b48Spatrick   // From the DWARF v5 specification.
712*09467b48Spatrick   case DW_AT_location:
713*09467b48Spatrick   case DW_AT_byte_size:
714*09467b48Spatrick   case DW_AT_bit_size:
715*09467b48Spatrick   case DW_AT_string_length:
716*09467b48Spatrick   case DW_AT_lower_bound:
717*09467b48Spatrick   case DW_AT_return_addr:
718*09467b48Spatrick   case DW_AT_bit_stride:
719*09467b48Spatrick   case DW_AT_upper_bound:
720*09467b48Spatrick   case DW_AT_count:
721*09467b48Spatrick   case DW_AT_data_member_location:
722*09467b48Spatrick   case DW_AT_frame_base:
723*09467b48Spatrick   case DW_AT_segment:
724*09467b48Spatrick   case DW_AT_static_link:
725*09467b48Spatrick   case DW_AT_use_location:
726*09467b48Spatrick   case DW_AT_vtable_elem_location:
727*09467b48Spatrick   case DW_AT_allocated:
728*09467b48Spatrick   case DW_AT_associated:
729*09467b48Spatrick   case DW_AT_byte_stride:
730*09467b48Spatrick   case DW_AT_rank:
731*09467b48Spatrick   case DW_AT_call_value:
732*09467b48Spatrick   case DW_AT_call_origin:
733*09467b48Spatrick   case DW_AT_call_target:
734*09467b48Spatrick   case DW_AT_call_target_clobbered:
735*09467b48Spatrick   case DW_AT_call_data_location:
736*09467b48Spatrick   case DW_AT_call_data_value:
737*09467b48Spatrick   // Extensions.
738*09467b48Spatrick   case DW_AT_GNU_call_site_value:
739*09467b48Spatrick   case DW_AT_GNU_call_site_target:
740*09467b48Spatrick     return true;
741*09467b48Spatrick   default:
742*09467b48Spatrick     return false;
743*09467b48Spatrick   }
744*09467b48Spatrick }
745