blob: bdeff7bd3af32e7c033298b5af9fd4088d5466f6 [file] [log] [blame]
Greg Claytonc8c10322016-12-13 18:25:19 +00001//===-- DWARFDie.cpp ------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/DebugInfo/DWARF/DWARFDie.h"
11#include "SyntaxHighlighting.h"
12#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
13#include "llvm/DebugInfo/DWARF/DWARFContext.h"
14#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
15#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
16#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
17#include "llvm/Support/DataTypes.h"
18#include "llvm/Support/Debug.h"
19#include "llvm/Support/Dwarf.h"
20#include "llvm/Support/Format.h"
21#include "llvm/Support/raw_ostream.h"
22
23using namespace llvm;
24using namespace dwarf;
25using namespace syntax;
26
27namespace {
28 static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
29 OS << " (";
30 do {
31 uint64_t Shift = countTrailingZeros(Val);
32 assert(Shift < 64 && "undefined behavior");
33 uint64_t Bit = 1ULL << Shift;
34 auto PropName = ApplePropertyString(Bit);
35 if (!PropName.empty())
36 OS << PropName;
37 else
38 OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit);
39 if (!(Val ^= Bit))
40 break;
41 OS << ", ";
42 } while (true);
43 OS << ")";
44}
45
46static void dumpRanges(raw_ostream &OS, const DWARFAddressRangesVector& Ranges,
47 unsigned AddressSize, unsigned Indent) {
48 if (Ranges.empty())
49 return;
50
51 for (const auto &Range: Ranges) {
52 OS << '\n';
53 OS.indent(Indent);
54 OS << format("[0x%0*" PRIx64 " - 0x%0*" PRIx64 ")",
55 AddressSize*2, Range.first,
56 AddressSize*2, Range.second);
57 }
58}
59
60static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
61 uint32_t *OffsetPtr, dwarf::Attribute Attr,
62 dwarf::Form Form, unsigned Indent) {
63 if (!Die.isValid())
64 return;
65 const char BaseIndent[] = " ";
66 OS << BaseIndent;
67 OS.indent(Indent+2);
68 auto attrString = AttributeString(Attr);
69 if (!attrString.empty())
70 WithColor(OS, syntax::Attribute) << attrString;
71 else
72 WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", Attr);
73
74 auto formString = FormEncodingString(Form);
75 if (!formString.empty())
76 OS << " [" << formString << ']';
77 else
78 OS << format(" [DW_FORM_Unknown_%x]", Form);
79
80 DWARFUnit *U = Die.getDwarfUnit();
81 DWARFFormValue formValue(Form);
82
83 if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, U))
84 return;
85
86 OS << "\t(";
87
88 StringRef Name;
89 std::string File;
90 auto Color = syntax::Enumerator;
91 if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
92 Color = syntax::String;
93 if (const auto *LT = U->getContext().getLineTableForUnit(U))
94 if (LT->getFileNameByIndex(formValue.getAsUnsignedConstant().getValue(), U->getCompilationDir(), DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
95 File = '"' + File + '"';
96 Name = File;
97 }
98 } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
99 Name = AttributeValueString(Attr, *Val);
100
101 if (!Name.empty())
102 WithColor(OS, Color) << Name;
103 else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
104 OS << *formValue.getAsUnsignedConstant();
105 else
106 formValue.dump(OS);
107
108 // We have dumped the attribute raw value. For some attributes
109 // having both the raw value and the pretty-printed value is
110 // interesting. These attributes are handled below.
111 if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
112 if (const char *Name = Die.getAttributeValueAsReferencedDie(Attr).getName(DINameKind::LinkageName))
113 OS << " \"" << Name << '\"';
114 } else if (Attr == DW_AT_APPLE_property_attribute) {
115 if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
116 dumpApplePropertyAttribute(OS, *OptVal);
117 } else if (Attr == DW_AT_ranges) {
118 dumpRanges(OS, Die.getAddressRanges(), U->getAddressByteSize(),
119 sizeof(BaseIndent)+Indent+4);
120 }
121
122 OS << ")\n";
123}
124
125} // end anonymous namespace
126
127bool DWARFDie::isSubprogramDIE() const {
128 return getTag() == DW_TAG_subprogram;
129}
130
131bool DWARFDie::isSubroutineDIE() const {
132 auto Tag = getTag();
133 return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine;
134}
135
Greg Clayton1cbf3fa2016-12-13 23:20:56 +0000136Optional<DWARFFormValue>
Greg Clayton97d22182017-01-13 21:08:18 +0000137DWARFDie::find(dwarf::Attribute Attr) const {
Greg Clayton1cbf3fa2016-12-13 23:20:56 +0000138 if (!isValid())
139 return None;
Greg Claytonc8c10322016-12-13 18:25:19 +0000140 auto AbbrevDecl = getAbbreviationDeclarationPtr();
141 if (AbbrevDecl)
Greg Clayton1cbf3fa2016-12-13 23:20:56 +0000142 return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U);
143 return None;
Greg Claytonc8c10322016-12-13 18:25:19 +0000144}
145
Greg Clayton97d22182017-01-13 21:08:18 +0000146Optional<DWARFFormValue>
147DWARFDie::findRecursively(dwarf::Attribute Attr) const {
148 if (!isValid())
149 return None;
150 if (auto Value = find(Attr))
151 return Value;
152 if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
153 if (auto Value = Die.find(Attr))
154 return Value;
155 if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification))
156 if (auto Value = Die.find(Attr))
157 return Value;
Greg Clayton52fe1f62016-12-14 22:38:08 +0000158 return None;
Greg Claytonc8c10322016-12-13 18:25:19 +0000159}
160
Greg Claytonc109bbe2017-01-13 22:32:12 +0000161Optional<DWARFFormValue>
162DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const {
163 if (!isValid())
164 return None;
165 auto AbbrevDecl = getAbbreviationDeclarationPtr();
166 if (AbbrevDecl) {
167 for (auto Attr : Attrs) {
168 if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U))
169 return Value;
170 }
171 }
172 return None;
173}
174
175Optional<DWARFFormValue>
176DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
177 if (!isValid())
178 return None;
179 if (auto Value = find(Attrs))
180 return Value;
181 if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
182 if (auto Value = Die.find(Attrs))
183 return Value;
184 if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification))
185 if (auto Value = Die.find(Attrs))
186 return Value;
187 return None;
188}
189
Greg Claytonc8c10322016-12-13 18:25:19 +0000190DWARFDie
191DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
Greg Clayton97d22182017-01-13 21:08:18 +0000192 auto SpecRef = toReference(find(Attr));
Greg Clayton52fe1f62016-12-14 22:38:08 +0000193 if (SpecRef) {
194 auto SpecUnit = U->getUnitSection().getUnitForOffset(*SpecRef);
Greg Claytonc8c10322016-12-13 18:25:19 +0000195 if (SpecUnit)
Greg Clayton52fe1f62016-12-14 22:38:08 +0000196 return SpecUnit->getDIEForOffset(*SpecRef);
Greg Claytonc8c10322016-12-13 18:25:19 +0000197 }
198 return DWARFDie();
199}
200
Greg Clayton52fe1f62016-12-14 22:38:08 +0000201Optional<uint64_t>
202DWARFDie::getRangesBaseAttribute() const {
Greg Claytonc109bbe2017-01-13 22:32:12 +0000203 return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
Greg Claytonc8c10322016-12-13 18:25:19 +0000204}
205
Greg Clayton2520c9e2016-12-19 20:36:41 +0000206Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
Greg Clayton97d22182017-01-13 21:08:18 +0000207 if (auto FormValue = find(DW_AT_high_pc)) {
Greg Clayton2520c9e2016-12-19 20:36:41 +0000208 if (auto Address = FormValue->getAsAddress()) {
209 // High PC is an address.
210 return Address;
211 }
212 if (auto Offset = FormValue->getAsUnsignedConstant()) {
213 // High PC is an offset from LowPC.
214 return LowPC + *Offset;
215 }
216 }
217 return None;
218}
Greg Clayton52fe1f62016-12-14 22:38:08 +0000219
Greg Clayton2520c9e2016-12-19 20:36:41 +0000220bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const {
Greg Clayton97d22182017-01-13 21:08:18 +0000221 auto LowPcAddr = toAddress(find(DW_AT_low_pc));
Greg Clayton2520c9e2016-12-19 20:36:41 +0000222 if (!LowPcAddr)
Greg Clayton52fe1f62016-12-14 22:38:08 +0000223 return false;
Greg Clayton2520c9e2016-12-19 20:36:41 +0000224 if (auto HighPcAddr = getHighPC(*LowPcAddr)) {
225 LowPC = *LowPcAddr;
226 HighPC = *HighPcAddr;
227 return true;
228 }
229 return false;
Greg Claytonc8c10322016-12-13 18:25:19 +0000230}
231
232DWARFAddressRangesVector
233DWARFDie::getAddressRanges() const {
234 if (isNULL())
235 return DWARFAddressRangesVector();
236 // Single range specified by low/high PC.
237 uint64_t LowPC, HighPC;
238 if (getLowAndHighPC(LowPC, HighPC)) {
239 return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC));
240 }
241 // Multiple ranges from .debug_ranges section.
Greg Clayton97d22182017-01-13 21:08:18 +0000242 auto RangesOffset = toSectionOffset(find(DW_AT_ranges));
Greg Clayton52fe1f62016-12-14 22:38:08 +0000243 if (RangesOffset) {
Greg Claytonc8c10322016-12-13 18:25:19 +0000244 DWARFDebugRangeList RangeList;
Greg Clayton52fe1f62016-12-14 22:38:08 +0000245 if (U->extractRangeList(*RangesOffset, RangeList))
Greg Claytonc8c10322016-12-13 18:25:19 +0000246 return RangeList.getAbsoluteRanges(U->getBaseAddress());
247 }
248 return DWARFAddressRangesVector();
249}
250
251void
252DWARFDie::collectChildrenAddressRanges(DWARFAddressRangesVector& Ranges) const {
253 if (isNULL())
254 return;
255 if (isSubprogramDIE()) {
256 const auto &DIERanges = getAddressRanges();
257 Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
258 }
259
Greg Clayton93e4fe82017-01-05 23:47:37 +0000260 for (auto Child: children())
Greg Claytonc8c10322016-12-13 18:25:19 +0000261 Child.collectChildrenAddressRanges(Ranges);
Greg Claytonc8c10322016-12-13 18:25:19 +0000262}
263
264bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
265 for (const auto& R : getAddressRanges()) {
266 if (R.first <= Address && Address < R.second)
267 return true;
268 }
269 return false;
270}
271
272const char *
273DWARFDie::getSubroutineName(DINameKind Kind) const {
274 if (!isSubroutineDIE())
275 return nullptr;
276 return getName(Kind);
277}
278
279const char *
280DWARFDie::getName(DINameKind Kind) const {
281 if (!isValid() || Kind == DINameKind::None)
282 return nullptr;
Greg Claytonc8c10322016-12-13 18:25:19 +0000283 // Try to get mangled name only if it was asked for.
284 if (Kind == DINameKind::LinkageName) {
Greg Claytonc109bbe2017-01-13 22:32:12 +0000285 if (auto Name = dwarf::toString(findRecursively({DW_AT_MIPS_linkage_name,
286 DW_AT_linkage_name}), nullptr))
Greg Clayton97d22182017-01-13 21:08:18 +0000287 return Name;
Greg Claytonc8c10322016-12-13 18:25:19 +0000288 }
Greg Clayton97d22182017-01-13 21:08:18 +0000289 if (auto Name = dwarf::toString(findRecursively(DW_AT_name), nullptr))
290 return Name;
Greg Claytonc8c10322016-12-13 18:25:19 +0000291 return nullptr;
292}
293
David Blaikieefc4eba2017-02-06 20:19:02 +0000294uint64_t DWARFDie::getDeclLine() const {
295 return toUnsigned(findRecursively(DW_AT_decl_line), 0);
296}
297
Greg Claytonc8c10322016-12-13 18:25:19 +0000298void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
299 uint32_t &CallColumn) const {
Greg Clayton97d22182017-01-13 21:08:18 +0000300 CallFile = toUnsigned(find(DW_AT_call_file), 0);
301 CallLine = toUnsigned(find(DW_AT_call_line), 0);
302 CallColumn = toUnsigned(find(DW_AT_call_column), 0);
Greg Claytonc8c10322016-12-13 18:25:19 +0000303}
304
305void DWARFDie::dump(raw_ostream &OS, unsigned RecurseDepth,
306 unsigned Indent) const {
307 if (!isValid())
308 return;
309 DataExtractor debug_info_data = U->getDebugInfoExtractor();
310 const uint32_t Offset = getOffset();
311 uint32_t offset = Offset;
312
313 if (debug_info_data.isValidOffset(offset)) {
314 uint32_t abbrCode = debug_info_data.getULEB128(&offset);
315 WithColor(OS, syntax::Address).get() << format("\n0x%8.8x: ", Offset);
316
317 if (abbrCode) {
318 auto AbbrevDecl = getAbbreviationDeclarationPtr();
319 if (AbbrevDecl) {
320 auto tagString = TagString(getTag());
321 if (!tagString.empty())
322 WithColor(OS, syntax::Tag).get().indent(Indent) << tagString;
323 else
324 WithColor(OS, syntax::Tag).get().indent(Indent)
325 << format("DW_TAG_Unknown_%x", getTag());
326
327 OS << format(" [%u] %c\n", abbrCode,
328 AbbrevDecl->hasChildren() ? '*' : ' ');
329
330 // Dump all data in the DIE for the attributes.
331 for (const auto &AttrSpec : AbbrevDecl->attributes()) {
Victor Leschuk96d99812017-02-25 13:15:57 +0000332 if (AttrSpec.Form == DW_FORM_implicit_const) {
333 // We are dumping .debug_info section ,
334 // implicit_const attribute values are not really stored here,
335 // but in .debug_abbrev section. So we just skip such attrs.
336 continue;
337 }
Greg Claytonc8c10322016-12-13 18:25:19 +0000338 dumpAttribute(OS, *this, &offset, AttrSpec.Attr, AttrSpec.Form,
339 Indent);
340 }
341
342 DWARFDie child = getFirstChild();
343 if (RecurseDepth > 0 && child) {
344 while (child) {
345 child.dump(OS, RecurseDepth-1, Indent+2);
346 child = child.getSibling();
347 }
348 }
349 } else {
350 OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
351 << abbrCode << '\n';
352 }
353 } else {
354 OS.indent(Indent) << "NULL\n";
355 }
356 }
357}
358
359
360void DWARFDie::getInlinedChainForAddress(
361 const uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) const {
362 if (isNULL())
363 return;
364 DWARFDie DIE(*this);
365 while (DIE) {
366 // Append current DIE to inlined chain only if it has correct tag
367 // (e.g. it is not a lexical block).
368 if (DIE.isSubroutineDIE())
369 InlinedChain.push_back(DIE);
370
371 // Try to get child which also contains provided address.
372 DWARFDie Child = DIE.getFirstChild();
373 while (Child) {
374 if (Child.addressRangeContainsAddress(Address)) {
375 // Assume there is only one such child.
376 break;
377 }
378 Child = Child.getSibling();
379 }
380 DIE = Child;
381 }
382 // Reverse the obtained chain to make the root of inlined chain last.
383 std::reverse(InlinedChain.begin(), InlinedChain.end());
384}
385
Greg Clayton78a07bf2016-12-21 21:37:06 +0000386DWARFDie DWARFDie::getParent() const {
387 if (isValid())
388 return U->getParent(Die);
389 return DWARFDie();
390}
391
392DWARFDie DWARFDie::getSibling() const {
393 if (isValid())
394 return U->getSibling(Die);
395 return DWARFDie();
396}
Greg Clayton0e62ee72017-01-13 00:13:42 +0000397
398iterator_range<DWARFDie::attribute_iterator>
399DWARFDie::attributes() const {
400 return make_range(attribute_iterator(*this, false),
401 attribute_iterator(*this, true));
402}
403
404DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D, bool End) :
405 Die(D), AttrValue(0), Index(0) {
406 auto AbbrDecl = Die.getAbbreviationDeclarationPtr();
407 assert(AbbrDecl && "Must have abbreviation declaration");
408 if (End) {
409 // This is the end iterator so we set the index to the attribute count.
410 Index = AbbrDecl->getNumAttributes();
411 } else {
412 // This is the begin iterator so we extract the value for this->Index.
413 AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize();
414 updateForIndex(*AbbrDecl, 0);
415 }
416}
417
418void DWARFDie::attribute_iterator::updateForIndex(
419 const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) {
420 Index = I;
421 // AbbrDecl must be valid befor calling this function.
422 auto NumAttrs = AbbrDecl.getNumAttributes();
423 if (Index < NumAttrs) {
424 AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
425 // Add the previous byte size of any previous attribute value.
426 AttrValue.Offset += AttrValue.ByteSize;
427 AttrValue.Value.setForm(AbbrDecl.getFormByIndex(Index));
428 uint32_t ParseOffset = AttrValue.Offset;
429 auto U = Die.getDwarfUnit();
430 assert(U && "Die must have valid DWARF unit");
431 bool b = AttrValue.Value.extractValue(U->getDebugInfoExtractor(),
432 &ParseOffset, U);
433 (void)b;
434 assert(b && "extractValue cannot fail on fully parsed DWARF");
435 AttrValue.ByteSize = ParseOffset - AttrValue.Offset;
436 } else {
437 assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only");
438 AttrValue.clear();
439 }
440}
441
442DWARFDie::attribute_iterator &DWARFDie::attribute_iterator::operator++() {
443 if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr())
444 updateForIndex(*AbbrDecl, Index + 1);
445 return *this;
446}