blob: b16a53cbb78671e52e2013d77440f856cf659680 [file] [log] [blame]
Eric Christopherc2ce0042012-08-23 00:52:51 +00001//===-- DWARFDebugInfoEntry.cpp -------------------------------------------===//
Benjamin Krameraa2f78f2011-09-13 19:42:23 +00002//
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 "DWARFDebugInfoEntry.h"
11#include "DWARFCompileUnit.h"
12#include "DWARFContext.h"
13#include "DWARFDebugAbbrev.h"
Alexey Samsonov045c6c52013-04-17 08:29:02 +000014#include "llvm/DebugInfo/DWARFFormValue.h"
Frederic Rissb3c99122014-10-10 15:51:10 +000015#include "llvm/Support/DataTypes.h"
Eric Christopher2cbd5762013-01-07 19:32:41 +000016#include "llvm/Support/Debug.h"
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000017#include "llvm/Support/Dwarf.h"
18#include "llvm/Support/Format.h"
19#include "llvm/Support/raw_ostream.h"
20using namespace llvm;
21using namespace dwarf;
22
Frederic Riss58ed53c2014-09-22 12:35:53 +000023// Small helper to extract a DIE pointed by a reference
24// attribute. It looks up the Unit containing the DIE and calls
25// DIE.extractFast with the right unit. Returns new unit on success,
26// nullptr otherwise.
27static const DWARFUnit *findUnitAndExtractFast(DWARFDebugInfoEntryMinimal &DIE,
28 const DWARFUnit *Unit,
29 uint32_t *Offset) {
30 Unit = Unit->getUnitSection().getUnitForOffset(*Offset);
31 return (Unit && DIE.extractFast(Unit, Offset)) ? Unit : nullptr;
32}
33
Frederic Riss955724e2014-09-22 12:36:04 +000034void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, DWARFUnit *u,
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000035 unsigned recurseDepth,
36 unsigned indent) const {
David Blaikie07e22442013-09-23 22:44:40 +000037 DataExtractor debug_info_data = u->getDebugInfoExtractor();
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000038 uint32_t offset = Offset;
39
40 if (debug_info_data.isValidOffset(offset)) {
Benjamin Kramerf7e0a312011-11-05 15:35:00 +000041 uint32_t abbrCode = debug_info_data.getULEB128(&offset);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000042
Benjamin Kramerf915acc2011-09-14 17:54:56 +000043 OS << format("\n0x%8.8x: ", Offset);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000044 if (abbrCode) {
45 if (AbbrevDecl) {
Benjamin Kramer9bca64f2011-09-15 05:43:00 +000046 const char *tagString = TagString(getTag());
47 if (tagString)
48 OS.indent(indent) << tagString;
49 else
50 OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag());
51 OS << format(" [%u] %c\n", abbrCode,
52 AbbrevDecl->hasChildren() ? '*' : ' ');
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000053
Eric Christopher7f5870c2013-01-07 03:27:58 +000054 // Dump all data in the DIE for the attributes.
Alexey Samsonov1eabf982014-03-13 07:52:54 +000055 for (const auto &AttrSpec : AbbrevDecl->attributes()) {
56 dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000057 }
58
59 const DWARFDebugInfoEntryMinimal *child = getFirstChild();
60 if (recurseDepth > 0 && child) {
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000061 while (child) {
David Blaikie07e22442013-09-23 22:44:40 +000062 child->dump(OS, u, recurseDepth-1, indent+2);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000063 child = child->getSibling();
64 }
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000065 }
66 } else {
67 OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
68 << abbrCode << '\n';
69 }
70 } else {
Benjamin Kramerf915acc2011-09-14 17:54:56 +000071 OS.indent(indent) << "NULL\n";
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000072 }
73 }
74}
75
Frederic Rissb3c99122014-10-10 15:51:10 +000076static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
77 OS << " (";
78 do {
Michael Ilsemanaddddc42014-12-15 18:48:43 +000079 uint64_t Shift = countTrailingZeros(Val);
80 assert(Shift < 64 && "undefined behavior");
81 uint64_t Bit = 1ULL << Shift;
Frederic Rissb3c99122014-10-10 15:51:10 +000082 if (const char *PropName = ApplePropertyString(Bit))
83 OS << PropName;
84 else
85 OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit);
86 if (!(Val ^= Bit))
87 break;
88 OS << ", ";
89 } while (true);
90 OS << ")";
91}
92
Frederic Risse939b432014-10-23 04:08:34 +000093static void dumpRanges(raw_ostream &OS, const DWARFAddressRangesVector& Ranges,
94 unsigned AddressSize, unsigned Indent) {
95 if (Ranges.empty())
96 return;
97
98 for (const auto &Range: Ranges) {
99 OS << '\n';
100 OS.indent(Indent);
101 OS << format("[0x%0*" PRIx64 " - 0x%0*" PRIx64 ")",
102 AddressSize*2, Range.first,
103 AddressSize*2, Range.second);
104 }
105}
106
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000107void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
Frederic Riss955724e2014-09-22 12:36:04 +0000108 DWARFUnit *u,
David Blaikie07e22442013-09-23 22:44:40 +0000109 uint32_t *offset_ptr,
110 uint16_t attr, uint16_t form,
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000111 unsigned indent) const {
Frederic Risse939b432014-10-23 04:08:34 +0000112 const char BaseIndent[] = " ";
113 OS << BaseIndent;
Benjamin Kramer9bca64f2011-09-15 05:43:00 +0000114 OS.indent(indent+2);
115 const char *attrString = AttributeString(attr);
116 if (attrString)
117 OS << attrString;
118 else
119 OS << format("DW_AT_Unknown_%x", attr);
120 const char *formString = FormEncodingString(form);
121 if (formString)
122 OS << " [" << formString << ']';
123 else
124 OS << format(" [DW_FORM_Unknown_%x]", form);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000125
126 DWARFFormValue formValue(form);
127
David Blaikie07e22442013-09-23 22:44:40 +0000128 if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u))
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000129 return;
130
131 OS << "\t(";
Frederic Riss878065b2014-09-04 19:39:20 +0000132
133 const char *Name = nullptr;
Frederic Riss955724e2014-09-22 12:36:04 +0000134 std::string File;
135 if (attr == DW_AT_decl_file || attr == DW_AT_call_file) {
136 if (const auto *LT = u->getContext().getLineTableForUnit(u))
137 if (LT->getFileNameByIndex(
138 formValue.getAsUnsignedConstant().getValue(),
139 u->getCompilationDir(),
140 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
141 File = '"' + File + '"';
142 Name = File.c_str();
143 }
144 } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
Frederic Riss878065b2014-09-04 19:39:20 +0000145 Name = AttributeValueString(attr, *Val);
146
147 if (Name) {
148 OS << Name;
Frederic Riss0982e692014-09-05 07:21:50 +0000149 } else if (attr == DW_AT_decl_line || attr == DW_AT_call_line) {
150 OS << *formValue.getAsUnsignedConstant();
Frederic Riss878065b2014-09-04 19:39:20 +0000151 } else {
152 formValue.dump(OS, u);
153 }
154
Frederic Rissd1cfc3c2014-10-06 03:36:31 +0000155 // We have dumped the attribute raw value. For some attributes
156 // having both the raw value and the pretty-printed value is
157 // interesting. These attributes are handled below.
158 if ((attr == DW_AT_specification || attr == DW_AT_abstract_origin) &&
159 // The signature references aren't handled.
160 formValue.getForm() != DW_FORM_ref_sig8) {
161 uint32_t Ref = formValue.getAsReference(u).getValue();
162 DWARFDebugInfoEntryMinimal DIE;
163 if (const DWARFUnit *RefU = findUnitAndExtractFast(DIE, u, &Ref))
Frederic Rissd4de1802014-10-10 15:51:02 +0000164 if (const char *Ref = DIE.getName(RefU, DINameKind::LinkageName))
Frederic Rissd1cfc3c2014-10-06 03:36:31 +0000165 OS << " \"" << Ref << '\"';
Frederic Rissb3c99122014-10-10 15:51:10 +0000166 } else if (attr == DW_AT_APPLE_property_attribute) {
167 if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
168 dumpApplePropertyAttribute(OS, *OptVal);
Frederic Risse939b432014-10-23 04:08:34 +0000169 } else if (attr == DW_AT_ranges) {
170 dumpRanges(OS, getAddressRanges(u), u->getAddressByteSize(),
171 sizeof(BaseIndent)+indent+4);
Frederic Rissd1cfc3c2014-10-06 03:36:31 +0000172 }
173
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000174 OS << ")\n";
175}
176
David Blaikie07e22442013-09-23 22:44:40 +0000177bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit *U,
Alexey Samsonovc03f2ee2013-04-08 14:37:16 +0000178 uint32_t *OffsetPtr) {
179 Offset = *OffsetPtr;
David Blaikie07e22442013-09-23 22:44:40 +0000180 DataExtractor DebugInfoData = U->getDebugInfoExtractor();
Alexey Samsonov330b8932013-10-28 23:58:58 +0000181 uint32_t UEndOffset = U->getNextUnitOffset();
182 if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset))
Alexey Samsonovc03f2ee2013-04-08 14:37:16 +0000183 return false;
184 uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
185 if (0 == AbbrCode) {
186 // NULL debug tag entry.
Craig Topper2617dcc2014-04-15 06:32:26 +0000187 AbbrevDecl = nullptr;
Alexey Samsonovc03f2ee2013-04-08 14:37:16 +0000188 return true;
189 }
David Blaikie07e22442013-09-23 22:44:40 +0000190 AbbrevDecl = U->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
Craig Topper2617dcc2014-04-15 06:32:26 +0000191 if (nullptr == AbbrevDecl) {
Alexey Samsonovc03f2ee2013-04-08 14:37:16 +0000192 // Restore the original offset.
193 *OffsetPtr = Offset;
194 return false;
195 }
Alexey Samsonov330b8932013-10-28 23:58:58 +0000196 ArrayRef<uint8_t> FixedFormSizes = DWARFFormValue::getFixedFormSizes(
197 U->getAddressByteSize(), U->getVersion());
198 assert(FixedFormSizes.size() > 0);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000199
Alexey Samsonovc03f2ee2013-04-08 14:37:16 +0000200 // Skip all data in the .debug_info for the attributes
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000201 for (const auto &AttrSpec : AbbrevDecl->attributes()) {
202 uint16_t Form = AttrSpec.Form;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000203
Alexey Samsonov330b8932013-10-28 23:58:58 +0000204 uint8_t FixedFormSize =
205 (Form < FixedFormSizes.size()) ? FixedFormSizes[Form] : 0;
206 if (FixedFormSize)
207 *OffsetPtr += FixedFormSize;
208 else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, U)) {
Alexey Samsonovc03f2ee2013-04-08 14:37:16 +0000209 // Restore the original offset.
210 *OffsetPtr = Offset;
211 return false;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000212 }
213 }
Alexey Samsonovc03f2ee2013-04-08 14:37:16 +0000214 return true;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000215}
216
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000217bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const {
218 return getTag() == DW_TAG_subprogram;
219}
220
221bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const {
222 uint32_t Tag = getTag();
223 return Tag == DW_TAG_subprogram ||
224 Tag == DW_TAG_inlined_subroutine;
225}
226
Alexey Samsonovcaabb0e2013-10-17 13:28:16 +0000227bool DWARFDebugInfoEntryMinimal::getAttributeValue(
228 const DWARFUnit *U, const uint16_t Attr, DWARFFormValue &FormValue) const {
229 if (!AbbrevDecl)
230 return false;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000231
Alexey Samsonovcaabb0e2013-10-17 13:28:16 +0000232 uint32_t AttrIdx = AbbrevDecl->findAttributeIndex(Attr);
233 if (AttrIdx == -1U)
234 return false;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000235
Alexey Samsonovcaabb0e2013-10-17 13:28:16 +0000236 DataExtractor DebugInfoData = U->getDebugInfoExtractor();
237 uint32_t DebugInfoOffset = getOffset();
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000238
Alexey Samsonovcaabb0e2013-10-17 13:28:16 +0000239 // Skip the abbreviation code so we are at the data for the attributes
240 DebugInfoData.getULEB128(&DebugInfoOffset);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000241
Alexey Samsonovcaabb0e2013-10-17 13:28:16 +0000242 // Skip preceding attribute values.
243 for (uint32_t i = 0; i < AttrIdx; ++i) {
244 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(i),
245 DebugInfoData, &DebugInfoOffset, U);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000246 }
247
Alexey Samsonovcaabb0e2013-10-17 13:28:16 +0000248 FormValue = DWARFFormValue(AbbrevDecl->getFormByIndex(AttrIdx));
249 return FormValue.extractValue(DebugInfoData, &DebugInfoOffset, U);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000250}
251
Alexey Samsonove3ba81b2013-08-27 09:20:22 +0000252const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
David Blaikie07e22442013-09-23 22:44:40 +0000253 const DWARFUnit *U, const uint16_t Attr, const char *FailValue) const {
Alexey Samsonove3ba81b2013-08-27 09:20:22 +0000254 DWARFFormValue FormValue;
Alexey Samsonov48cbda52013-10-28 23:01:48 +0000255 if (!getAttributeValue(U, Attr, FormValue))
256 return FailValue;
257 Optional<const char *> Result = FormValue.getAsCString(U);
258 return Result.hasValue() ? Result.getValue() : FailValue;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000259}
260
Alexey Samsonove3ba81b2013-08-27 09:20:22 +0000261uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress(
David Blaikie07e22442013-09-23 22:44:40 +0000262 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
Alexey Samsonove3ba81b2013-08-27 09:20:22 +0000263 DWARFFormValue FormValue;
Alexey Samsonov48cbda52013-10-28 23:01:48 +0000264 if (!getAttributeValue(U, Attr, FormValue))
265 return FailValue;
266 Optional<uint64_t> Result = FormValue.getAsAddress(U);
267 return Result.hasValue() ? Result.getValue() : FailValue;
Alexey Samsonove3ba81b2013-08-27 09:20:22 +0000268}
269
Alexey Samsonov48cbda52013-10-28 23:01:48 +0000270uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant(
David Blaikie07e22442013-09-23 22:44:40 +0000271 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
Alexey Samsonove3ba81b2013-08-27 09:20:22 +0000272 DWARFFormValue FormValue;
Alexey Samsonov48cbda52013-10-28 23:01:48 +0000273 if (!getAttributeValue(U, Attr, FormValue))
274 return FailValue;
275 Optional<uint64_t> Result = FormValue.getAsUnsignedConstant();
276 return Result.hasValue() ? Result.getValue() : FailValue;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000277}
278
David Blaikie07e22442013-09-23 22:44:40 +0000279uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
Alexey Samsonovcaabb0e2013-10-17 13:28:16 +0000280 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
281 DWARFFormValue FormValue;
Alexey Samsonov48cbda52013-10-28 23:01:48 +0000282 if (!getAttributeValue(U, Attr, FormValue))
283 return FailValue;
284 Optional<uint64_t> Result = FormValue.getAsReference(U);
285 return Result.hasValue() ? Result.getValue() : FailValue;
286}
287
288uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset(
289 const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const {
290 DWARFFormValue FormValue;
291 if (!getAttributeValue(U, Attr, FormValue))
292 return FailValue;
293 Optional<uint64_t> Result = FormValue.getAsSectionOffset();
294 return Result.hasValue() ? Result.getValue() : FailValue;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000295}
Benjamin Kramer32664932011-09-14 20:52:27 +0000296
Alexey Samsonovaa909982014-06-13 22:31:03 +0000297uint64_t
298DWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U,
299 uint64_t FailValue) const {
300 uint64_t Result =
301 getAttributeValueAsSectionOffset(U, DW_AT_ranges_base, -1ULL);
302 if (Result != -1ULL)
303 return Result;
304 return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue);
305}
306
David Blaikie07e22442013-09-23 22:44:40 +0000307bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
Eric Christopher206cf642012-10-30 21:36:43 +0000308 uint64_t &LowPC,
309 uint64_t &HighPC) const {
David Blaikie07e22442013-09-23 22:44:40 +0000310 LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL);
Alexey Samsonov76142122013-10-28 23:15:15 +0000311 if (LowPC == -1ULL)
312 return false;
313 HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL);
314 if (HighPC == -1ULL) {
315 // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case
316 // it represents function size.
317 HighPC = getAttributeValueAsUnsignedConstant(U, DW_AT_high_pc, -1ULL);
318 if (HighPC != -1ULL)
319 HighPC += LowPC;
320 }
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000321 return (HighPC != -1ULL);
322}
323
Alexey Samsonov762343d2014-04-18 17:25:46 +0000324DWARFAddressRangesVector
325DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const {
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000326 if (isNULL())
Benjamin Krameree26b622014-04-18 19:01:53 +0000327 return DWARFAddressRangesVector();
Alexey Samsonov762343d2014-04-18 17:25:46 +0000328 // Single range specified by low/high PC.
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000329 uint64_t LowPC, HighPC;
Alexey Samsonov762343d2014-04-18 17:25:46 +0000330 if (getLowAndHighPC(U, LowPC, HighPC)) {
Benjamin Krameree26b622014-04-18 19:01:53 +0000331 return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC));
Alexey Samsonov762343d2014-04-18 17:25:46 +0000332 }
333 // Multiple ranges from .debug_ranges section.
Alexey Samsonov48cbda52013-10-28 23:01:48 +0000334 uint32_t RangesOffset =
335 getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000336 if (RangesOffset != -1U) {
337 DWARFDebugRangeList RangeList;
David Blaikie07e22442013-09-23 22:44:40 +0000338 if (U->extractRangeList(RangesOffset, RangeList))
Alexey Samsonov762343d2014-04-18 17:25:46 +0000339 return RangeList.getAbsoluteRanges(U->getBaseAddress());
340 }
Benjamin Krameree26b622014-04-18 19:01:53 +0000341 return DWARFAddressRangesVector();
Alexey Samsonov762343d2014-04-18 17:25:46 +0000342}
343
344void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges(
345 const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const {
346 if (isNULL())
347 return;
348 if (isSubprogramDIE()) {
349 const auto &DIERanges = getAddressRanges(U);
350 Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
351 }
352
353 const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
354 while (Child) {
355 Child->collectChildrenAddressRanges(U, Ranges);
356 Child = Child->getSibling();
357 }
358}
359
360bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
361 const DWARFUnit *U, const uint64_t Address) const {
362 for (const auto& R : getAddressRanges(U)) {
363 if (R.first <= Address && Address < R.second)
364 return true;
Alexey Samsonovf4462fa2012-07-02 05:54:45 +0000365 }
366 return false;
367}
368
David Blaikie07e22442013-09-23 22:44:40 +0000369const char *
Alexey Samsonovdce67342014-05-15 21:24:32 +0000370DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
Frederic Rissd4de1802014-10-10 15:51:02 +0000371 DINameKind Kind) const {
372 if (!isSubroutineDIE())
373 return nullptr;
374 return getName(U, Kind);
375}
376
377const char *
378DWARFDebugInfoEntryMinimal::getName(const DWARFUnit *U,
379 DINameKind Kind) const {
380 if (Kind == DINameKind::None)
Craig Topper2617dcc2014-04-15 06:32:26 +0000381 return nullptr;
Alexey Samsonovcd014722014-05-17 00:07:48 +0000382 // Try to get mangled name only if it was asked for.
Frederic Rissd4de1802014-10-10 15:51:02 +0000383 if (Kind == DINameKind::LinkageName) {
Alexey Samsonovcd014722014-05-17 00:07:48 +0000384 if (const char *name =
385 getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
386 return name;
387 if (const char *name =
388 getAttributeValueAsString(U, DW_AT_linkage_name, nullptr))
389 return name;
390 }
Craig Topper2617dcc2014-04-15 06:32:26 +0000391 if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
Alexey Samsonovb604ff22012-07-17 15:28:35 +0000392 return name;
393 // Try to get name from specification DIE.
394 uint32_t spec_ref =
David Blaikie07e22442013-09-23 22:44:40 +0000395 getAttributeValueAsReference(U, DW_AT_specification, -1U);
Alexey Samsonovb604ff22012-07-17 15:28:35 +0000396 if (spec_ref != -1U) {
397 DWARFDebugInfoEntryMinimal spec_die;
Frederic Riss58ed53c2014-09-22 12:35:53 +0000398 if (const DWARFUnit *RefU = findUnitAndExtractFast(spec_die, U, &spec_ref)) {
Frederic Rissd4de1802014-10-10 15:51:02 +0000399 if (const char *name = spec_die.getName(RefU, Kind))
Alexey Samsonovb604ff22012-07-17 15:28:35 +0000400 return name;
Alexey Samsonovf4462fa2012-07-02 05:54:45 +0000401 }
402 }
Alexey Samsonovb604ff22012-07-17 15:28:35 +0000403 // Try to get name from abstract origin DIE.
404 uint32_t abs_origin_ref =
David Blaikie07e22442013-09-23 22:44:40 +0000405 getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U);
Alexey Samsonovb604ff22012-07-17 15:28:35 +0000406 if (abs_origin_ref != -1U) {
407 DWARFDebugInfoEntryMinimal abs_origin_die;
Frederic Riss58ed53c2014-09-22 12:35:53 +0000408 if (const DWARFUnit *RefU = findUnitAndExtractFast(abs_origin_die, U,
409 &abs_origin_ref)) {
Frederic Rissd4de1802014-10-10 15:51:02 +0000410 if (const char *name = abs_origin_die.getName(RefU, Kind))
Alexey Samsonovb604ff22012-07-17 15:28:35 +0000411 return name;
412 }
413 }
Craig Topper2617dcc2014-04-15 06:32:26 +0000414 return nullptr;
Alexey Samsonovf4462fa2012-07-02 05:54:45 +0000415}
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000416
David Blaikie07e22442013-09-23 22:44:40 +0000417void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U,
Eric Christopher206cf642012-10-30 21:36:43 +0000418 uint32_t &CallFile,
419 uint32_t &CallLine,
420 uint32_t &CallColumn) const {
Alexey Samsonov48cbda52013-10-28 23:01:48 +0000421 CallFile = getAttributeValueAsUnsignedConstant(U, DW_AT_call_file, 0);
422 CallLine = getAttributeValueAsUnsignedConstant(U, DW_AT_call_line, 0);
423 CallColumn = getAttributeValueAsUnsignedConstant(U, DW_AT_call_column, 0);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000424}
425
Alexey Samsonov3211e612013-08-06 10:49:15 +0000426DWARFDebugInfoEntryInlinedChain
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000427DWARFDebugInfoEntryMinimal::getInlinedChainForAddress(
David Blaikie07e22442013-09-23 22:44:40 +0000428 const DWARFUnit *U, const uint64_t Address) const {
Alexey Samsonov3211e612013-08-06 10:49:15 +0000429 DWARFDebugInfoEntryInlinedChain InlinedChain;
David Blaikie07e22442013-09-23 22:44:40 +0000430 InlinedChain.U = U;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000431 if (isNULL())
432 return InlinedChain;
433 for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) {
434 // Append current DIE to inlined chain only if it has correct tag
435 // (e.g. it is not a lexical block).
436 if (DIE->isSubroutineDIE()) {
Alexey Samsonov3211e612013-08-06 10:49:15 +0000437 InlinedChain.DIEs.push_back(*DIE);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000438 }
439 // Try to get child which also contains provided address.
440 const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild();
441 while (Child) {
David Blaikie07e22442013-09-23 22:44:40 +0000442 if (Child->addressRangeContainsAddress(U, Address)) {
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000443 // Assume there is only one such child.
444 break;
445 }
446 Child = Child->getSibling();
447 }
448 DIE = Child;
449 }
450 // Reverse the obtained chain to make the root of inlined chain last.
Alexey Samsonov3211e612013-08-06 10:49:15 +0000451 std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end());
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000452 return InlinedChain;
453}