blob: 775e68fa23f3a4ab91be35aa29ee76e5c1386fd0 [file] [log] [blame]
Eric Christopherbd5bc212012-08-23 00:52:51 +00001//===-- DWARFDebugInfoEntry.cpp -------------------------------------------===//
Benjamin Kramer72c0d7f2011-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 Samsonovcd614552013-04-17 08:29:02 +000014#include "llvm/DebugInfo/DWARFFormValue.h"
Eric Christopherdd8e9f32013-01-07 19:32:41 +000015#include "llvm/Support/Debug.h"
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000016#include "llvm/Support/Dwarf.h"
17#include "llvm/Support/Format.h"
18#include "llvm/Support/raw_ostream.h"
19using namespace llvm;
20using namespace dwarf;
21
22void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS,
23 const DWARFCompileUnit *cu,
24 unsigned recurseDepth,
25 unsigned indent) const {
26 DataExtractor debug_info_data = cu->getDebugInfoExtractor();
27 uint32_t offset = Offset;
28
29 if (debug_info_data.isValidOffset(offset)) {
Benjamin Kramer80cc2592011-11-05 15:35:00 +000030 uint32_t abbrCode = debug_info_data.getULEB128(&offset);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000031
Benjamin Kramer09422552011-09-14 17:54:56 +000032 OS << format("\n0x%8.8x: ", Offset);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000033 if (abbrCode) {
34 if (AbbrevDecl) {
Benjamin Kramer75c63082011-09-15 05:43:00 +000035 const char *tagString = TagString(getTag());
36 if (tagString)
37 OS.indent(indent) << tagString;
38 else
39 OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag());
40 OS << format(" [%u] %c\n", abbrCode,
41 AbbrevDecl->hasChildren() ? '*' : ' ');
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000042
Eric Christophere5ef3052013-01-07 03:27:58 +000043 // Dump all data in the DIE for the attributes.
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000044 const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
45 for (uint32_t i = 0; i != numAttributes; ++i) {
46 uint16_t attr = AbbrevDecl->getAttrByIndex(i);
47 uint16_t form = AbbrevDecl->getFormByIndex(i);
48 dumpAttribute(OS, cu, &offset, attr, form, indent);
49 }
50
51 const DWARFDebugInfoEntryMinimal *child = getFirstChild();
52 if (recurseDepth > 0 && child) {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000053 while (child) {
Benjamin Kramer15ec0852011-09-14 00:15:32 +000054 child->dump(OS, cu, recurseDepth-1, indent+2);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000055 child = child->getSibling();
56 }
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000057 }
58 } else {
59 OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
60 << abbrCode << '\n';
61 }
62 } else {
Benjamin Kramer09422552011-09-14 17:54:56 +000063 OS.indent(indent) << "NULL\n";
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000064 }
65 }
66}
67
68void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
69 const DWARFCompileUnit *cu,
70 uint32_t* offset_ptr,
71 uint16_t attr,
72 uint16_t form,
73 unsigned indent) const {
David Blaikiea9b69792013-08-19 03:36:23 +000074 OS << " ";
Benjamin Kramer75c63082011-09-15 05:43:00 +000075 OS.indent(indent+2);
76 const char *attrString = AttributeString(attr);
77 if (attrString)
78 OS << attrString;
79 else
80 OS << format("DW_AT_Unknown_%x", attr);
81 const char *formString = FormEncodingString(form);
82 if (formString)
83 OS << " [" << formString << ']';
84 else
85 OS << format(" [DW_FORM_Unknown_%x]", form);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000086
87 DWARFFormValue formValue(form);
88
89 if (!formValue.extractValue(cu->getDebugInfoExtractor(), offset_ptr, cu))
90 return;
91
92 OS << "\t(";
Benjamin Kramer34f864f2011-09-15 16:57:13 +000093 formValue.dump(OS, cu);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000094 OS << ")\n";
95}
96
Alexey Samsonovd6b89ef2013-04-08 14:37:16 +000097bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *CU,
98 const uint8_t *FixedFormSizes,
99 uint32_t *OffsetPtr) {
100 Offset = *OffsetPtr;
101 DataExtractor DebugInfoData = CU->getDebugInfoExtractor();
102 uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
103 if (0 == AbbrCode) {
104 // NULL debug tag entry.
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000105 AbbrevDecl = NULL;
Alexey Samsonovd6b89ef2013-04-08 14:37:16 +0000106 return true;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000107 }
Alexey Samsonovd6b89ef2013-04-08 14:37:16 +0000108 AbbrevDecl = CU->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
109 assert(AbbrevDecl);
110 assert(FixedFormSizes); // For best performance this should be specified!
111
112 // Skip all data in the .debug_info for the attributes
113 for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) {
114 uint16_t Form = AbbrevDecl->getFormByIndex(i);
115
116 // FIXME: Currently we're checking if this is less than the last
117 // entry in the fixed_form_sizes table, but this should be changed
118 // to use dynamic dispatch.
119 uint8_t FixedFormSize =
120 (Form < DW_FORM_ref_sig8) ? FixedFormSizes[Form] : 0;
121 if (FixedFormSize)
122 *OffsetPtr += FixedFormSize;
123 else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr,
124 CU)) {
125 // Restore the original offset.
126 *OffsetPtr = Offset;
127 return false;
128 }
129 }
130 return true;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000131}
132
133bool
Alexey Samsonovd6b89ef2013-04-08 14:37:16 +0000134DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *CU,
135 uint32_t *OffsetPtr) {
136 DataExtractor DebugInfoData = CU->getDebugInfoExtractor();
137 const uint32_t CUEndOffset = CU->getNextCompileUnitOffset();
138 Offset = *OffsetPtr;
139 if ((Offset >= CUEndOffset) || !DebugInfoData.isValidOffset(Offset))
140 return false;
141 uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
142 if (0 == AbbrCode) {
143 // NULL debug tag entry.
144 AbbrevDecl = NULL;
145 return true;
146 }
147 AbbrevDecl = CU->getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
148 if (0 == AbbrevDecl) {
149 // Restore the original offset.
150 *OffsetPtr = Offset;
151 return false;
152 }
153 bool IsCompileUnitTag = (AbbrevDecl->getTag() == DW_TAG_compile_unit);
154 if (IsCompileUnitTag)
155 const_cast<DWARFCompileUnit*>(CU)->setBaseAddress(0);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000156
Alexey Samsonovd6b89ef2013-04-08 14:37:16 +0000157 // Skip all data in the .debug_info for the attributes
158 for (uint32_t i = 0, n = AbbrevDecl->getNumAttributes(); i < n; ++i) {
159 uint16_t Attr = AbbrevDecl->getAttrByIndex(i);
160 uint16_t Form = AbbrevDecl->getFormByIndex(i);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000161
Alexey Samsonovd6b89ef2013-04-08 14:37:16 +0000162 if (IsCompileUnitTag &&
163 ((Attr == DW_AT_entry_pc) || (Attr == DW_AT_low_pc))) {
164 DWARFFormValue FormValue(Form);
165 if (FormValue.extractValue(DebugInfoData, OffsetPtr, CU)) {
166 if (Attr == DW_AT_low_pc || Attr == DW_AT_entry_pc)
167 const_cast<DWARFCompileUnit*>(CU)
168 ->setBaseAddress(FormValue.getUnsigned());
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000169 }
Alexey Samsonovd6b89ef2013-04-08 14:37:16 +0000170 } else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr,
171 CU)) {
172 // Restore the original offset.
173 *OffsetPtr = Offset;
174 return false;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000175 }
176 }
Alexey Samsonovd6b89ef2013-04-08 14:37:16 +0000177 return true;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000178}
179
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000180bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const {
181 return getTag() == DW_TAG_subprogram;
182}
183
184bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const {
185 uint32_t Tag = getTag();
186 return Tag == DW_TAG_subprogram ||
187 Tag == DW_TAG_inlined_subroutine;
188}
189
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000190uint32_t
191DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu,
192 const uint16_t attr,
193 DWARFFormValue &form_value,
194 uint32_t *end_attr_offset_ptr)
195 const {
196 if (AbbrevDecl) {
197 uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr);
198
199 if (attr_idx != -1U) {
200 uint32_t offset = getOffset();
201
202 DataExtractor debug_info_data = cu->getDebugInfoExtractor();
203
204 // Skip the abbreviation code so we are at the data for the attributes
205 debug_info_data.getULEB128(&offset);
206
207 uint32_t idx = 0;
208 while (idx < attr_idx)
209 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++),
210 debug_info_data, &offset, cu);
211
212 const uint32_t attr_offset = offset;
213 form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx));
Benjamin Kramer4aa3fea2011-09-13 21:47:32 +0000214 if (form_value.extractValue(debug_info_data, &offset, cu)) {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000215 if (end_attr_offset_ptr)
216 *end_attr_offset_ptr = offset;
217 return attr_offset;
218 }
219 }
220 }
221
222 return 0;
223}
224
Alexey Samsonov63fd2af2013-08-27 09:20:22 +0000225const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
226 const DWARFCompileUnit *CU, const uint16_t Attr,
227 const char *FailValue) const {
228 DWARFFormValue FormValue;
229 if (getAttributeValue(CU, Attr, FormValue))
230 return FormValue.getAsCString(CU);
231 return FailValue;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000232}
233
Alexey Samsonov63fd2af2013-08-27 09:20:22 +0000234uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress(
235 const DWARFCompileUnit *CU, const uint16_t Attr, uint64_t FailValue) const {
236 DWARFFormValue FormValue;
237 if (getAttributeValue(CU, Attr, FormValue))
238 return FormValue.getAsAddress(CU);
239 return FailValue;
240}
241
242uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
243 const DWARFCompileUnit *CU, const uint16_t Attr, uint64_t FailValue) const {
244 DWARFFormValue FormValue;
245 if (getAttributeValue(CU, Attr, FormValue)) {
246 return FormValue.getUnsigned();
247 }
248 return FailValue;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000249}
250
251int64_t
252DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned(
Eric Christopher203e6f62012-10-30 21:36:43 +0000253 const DWARFCompileUnit* cu,
254 const uint16_t attr,
255 int64_t fail_value) const {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000256 DWARFFormValue form_value;
257 if (getAttributeValue(cu, attr, form_value))
258 return form_value.getSigned();
259 return fail_value;
260}
261
262uint64_t
Benjamin Kramer10df8062011-09-14 20:52:27 +0000263DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
Eric Christopher203e6f62012-10-30 21:36:43 +0000264 const DWARFCompileUnit* cu,
265 const uint16_t attr,
266 uint64_t fail_value)
267 const {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000268 DWARFFormValue form_value;
269 if (getAttributeValue(cu, attr, form_value))
270 return form_value.getReference(cu);
271 return fail_value;
272}
Benjamin Kramer10df8062011-09-14 20:52:27 +0000273
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000274bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFCompileUnit *CU,
Eric Christopher203e6f62012-10-30 21:36:43 +0000275 uint64_t &LowPC,
276 uint64_t &HighPC) const {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000277 HighPC = -1ULL;
Alexey Samsonov63fd2af2013-08-27 09:20:22 +0000278 LowPC = getAttributeValueAsAddress(CU, DW_AT_low_pc, -1ULL);
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000279 if (LowPC != -1ULL)
Alexey Samsonov63fd2af2013-08-27 09:20:22 +0000280 HighPC = getAttributeValueAsAddress(CU, DW_AT_high_pc, -1ULL);
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000281 return (HighPC != -1ULL);
282}
283
Benjamin Kramer10df8062011-09-14 20:52:27 +0000284void
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000285DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *CU,
Alexey Samsonov63fd2af2013-08-27 09:20:22 +0000286 DWARFDebugAranges *DebugAranges,
287 uint32_t CUOffsetInAranges)
Benjamin Kramer10df8062011-09-14 20:52:27 +0000288 const {
289 if (AbbrevDecl) {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000290 if (isSubprogramDIE()) {
291 uint64_t LowPC, HighPC;
Alexey Samsonov63fd2af2013-08-27 09:20:22 +0000292 if (getLowAndHighPC(CU, LowPC, HighPC))
293 DebugAranges->appendRange(CUOffsetInAranges, LowPC, HighPC);
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000294 // FIXME: try to append ranges from .debug_ranges section.
Benjamin Kramer10df8062011-09-14 20:52:27 +0000295 }
296
Alexey Samsonov63fd2af2013-08-27 09:20:22 +0000297 const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
298 while (Child) {
299 Child->buildAddressRangeTable(CU, DebugAranges, CUOffsetInAranges);
300 Child = Child->getSibling();
Benjamin Kramer10df8062011-09-14 20:52:27 +0000301 }
302 }
303}
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000304
305bool
306DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
Eric Christopher203e6f62012-10-30 21:36:43 +0000307 const DWARFCompileUnit *CU,
308 const uint64_t Address)
309 const {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000310 if (isNULL())
311 return false;
312 uint64_t LowPC, HighPC;
313 if (getLowAndHighPC(CU, LowPC, HighPC))
314 return (LowPC <= Address && Address <= HighPC);
315 // Try to get address ranges from .debug_ranges section.
316 uint32_t RangesOffset = getAttributeValueAsReference(CU, DW_AT_ranges, -1U);
317 if (RangesOffset != -1U) {
318 DWARFDebugRangeList RangeList;
319 if (CU->extractRangeList(RangesOffset, RangeList))
320 return RangeList.containsAddress(CU->getBaseAddress(), Address);
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000321 }
322 return false;
323}
324
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000325const char*
Eric Christopher203e6f62012-10-30 21:36:43 +0000326DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFCompileUnit *CU)
327 const {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000328 if (!isSubroutineDIE())
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000329 return 0;
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000330 // Try to get mangled name if possible.
331 if (const char *name =
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000332 getAttributeValueAsString(CU, DW_AT_MIPS_linkage_name, 0))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000333 return name;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000334 if (const char *name = getAttributeValueAsString(CU, DW_AT_linkage_name, 0))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000335 return name;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000336 if (const char *name = getAttributeValueAsString(CU, DW_AT_name, 0))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000337 return name;
338 // Try to get name from specification DIE.
339 uint32_t spec_ref =
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000340 getAttributeValueAsReference(CU, DW_AT_specification, -1U);
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000341 if (spec_ref != -1U) {
342 DWARFDebugInfoEntryMinimal spec_die;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000343 if (spec_die.extract(CU, &spec_ref)) {
344 if (const char *name = spec_die.getSubroutineName(CU))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000345 return name;
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000346 }
347 }
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000348 // Try to get name from abstract origin DIE.
349 uint32_t abs_origin_ref =
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000350 getAttributeValueAsReference(CU, DW_AT_abstract_origin, -1U);
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000351 if (abs_origin_ref != -1U) {
352 DWARFDebugInfoEntryMinimal abs_origin_die;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000353 if (abs_origin_die.extract(CU, &abs_origin_ref)) {
354 if (const char *name = abs_origin_die.getSubroutineName(CU))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000355 return name;
356 }
357 }
358 return 0;
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000359}
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000360
Eric Christopher203e6f62012-10-30 21:36:43 +0000361void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFCompileUnit *CU,
362 uint32_t &CallFile,
363 uint32_t &CallLine,
364 uint32_t &CallColumn) const {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000365 CallFile = getAttributeValueAsUnsigned(CU, DW_AT_call_file, 0);
366 CallLine = getAttributeValueAsUnsigned(CU, DW_AT_call_line, 0);
367 CallColumn = getAttributeValueAsUnsigned(CU, DW_AT_call_column, 0);
368}
369
Alexey Samsonove6642902013-08-06 10:49:15 +0000370DWARFDebugInfoEntryInlinedChain
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000371DWARFDebugInfoEntryMinimal::getInlinedChainForAddress(
Alexey Samsonove6642902013-08-06 10:49:15 +0000372 const DWARFCompileUnit *CU, const uint64_t Address) const {
373 DWARFDebugInfoEntryInlinedChain InlinedChain;
374 InlinedChain.CU = CU;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000375 if (isNULL())
376 return InlinedChain;
377 for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) {
378 // Append current DIE to inlined chain only if it has correct tag
379 // (e.g. it is not a lexical block).
380 if (DIE->isSubroutineDIE()) {
Alexey Samsonove6642902013-08-06 10:49:15 +0000381 InlinedChain.DIEs.push_back(*DIE);
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000382 }
383 // Try to get child which also contains provided address.
384 const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild();
385 while (Child) {
386 if (Child->addressRangeContainsAddress(CU, Address)) {
387 // Assume there is only one such child.
388 break;
389 }
390 Child = Child->getSibling();
391 }
392 DIE = Child;
393 }
394 // Reverse the obtained chain to make the root of inlined chain last.
Alexey Samsonove6642902013-08-06 10:49:15 +0000395 std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end());
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000396 return InlinedChain;
397}