blob: 9abf8dd2623b1c641ceb51b8874766355560ddff [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
225const char*
226DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
Eric Christopher203e6f62012-10-30 21:36:43 +0000227 const DWARFCompileUnit* cu,
228 const uint16_t attr,
229 const char* fail_value)
230 const {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000231 DWARFFormValue form_value;
232 if (getAttributeValue(cu, attr, form_value)) {
Eric Christopher82de10a2013-01-02 23:52:13 +0000233 DataExtractor stringExtractor(cu->getStringSection(), false, 0);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000234 return form_value.getAsCString(&stringExtractor);
235 }
236 return fail_value;
237}
238
239uint64_t
240DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
Eric Christopher203e6f62012-10-30 21:36:43 +0000241 const DWARFCompileUnit* cu,
242 const uint16_t attr,
243 uint64_t fail_value) const {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000244 DWARFFormValue form_value;
245 if (getAttributeValue(cu, attr, form_value))
246 return form_value.getUnsigned();
247 return fail_value;
248}
249
250int64_t
251DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned(
Eric Christopher203e6f62012-10-30 21:36:43 +0000252 const DWARFCompileUnit* cu,
253 const uint16_t attr,
254 int64_t fail_value) const {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000255 DWARFFormValue form_value;
256 if (getAttributeValue(cu, attr, form_value))
257 return form_value.getSigned();
258 return fail_value;
259}
260
261uint64_t
Benjamin Kramer10df8062011-09-14 20:52:27 +0000262DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
Eric Christopher203e6f62012-10-30 21:36:43 +0000263 const DWARFCompileUnit* cu,
264 const uint16_t attr,
265 uint64_t fail_value)
266 const {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000267 DWARFFormValue form_value;
268 if (getAttributeValue(cu, attr, form_value))
269 return form_value.getReference(cu);
270 return fail_value;
271}
Benjamin Kramer10df8062011-09-14 20:52:27 +0000272
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000273bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFCompileUnit *CU,
Eric Christopher203e6f62012-10-30 21:36:43 +0000274 uint64_t &LowPC,
275 uint64_t &HighPC) const {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000276 HighPC = -1ULL;
277 LowPC = getAttributeValueAsUnsigned(CU, DW_AT_low_pc, -1ULL);
278 if (LowPC != -1ULL)
279 HighPC = getAttributeValueAsUnsigned(CU, DW_AT_high_pc, -1ULL);
280 return (HighPC != -1ULL);
281}
282
Benjamin Kramer10df8062011-09-14 20:52:27 +0000283void
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000284DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *CU,
285 DWARFDebugAranges *DebugAranges)
Benjamin Kramer10df8062011-09-14 20:52:27 +0000286 const {
287 if (AbbrevDecl) {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000288 if (isSubprogramDIE()) {
289 uint64_t LowPC, HighPC;
290 if (getLowAndHighPC(CU, LowPC, HighPC)) {
291 DebugAranges->appendRange(CU->getOffset(), LowPC, HighPC);
292 }
293 // FIXME: try to append ranges from .debug_ranges section.
Benjamin Kramer10df8062011-09-14 20:52:27 +0000294 }
295
296 const DWARFDebugInfoEntryMinimal *child = getFirstChild();
297 while (child) {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000298 child->buildAddressRangeTable(CU, DebugAranges);
Benjamin Kramer10df8062011-09-14 20:52:27 +0000299 child = child->getSibling();
300 }
301 }
302}
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000303
304bool
305DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
Eric Christopher203e6f62012-10-30 21:36:43 +0000306 const DWARFCompileUnit *CU,
307 const uint64_t Address)
308 const {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000309 if (isNULL())
310 return false;
311 uint64_t LowPC, HighPC;
312 if (getLowAndHighPC(CU, LowPC, HighPC))
313 return (LowPC <= Address && Address <= HighPC);
314 // Try to get address ranges from .debug_ranges section.
315 uint32_t RangesOffset = getAttributeValueAsReference(CU, DW_AT_ranges, -1U);
316 if (RangesOffset != -1U) {
317 DWARFDebugRangeList RangeList;
318 if (CU->extractRangeList(RangesOffset, RangeList))
319 return RangeList.containsAddress(CU->getBaseAddress(), Address);
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000320 }
321 return false;
322}
323
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000324const char*
Eric Christopher203e6f62012-10-30 21:36:43 +0000325DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFCompileUnit *CU)
326 const {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000327 if (!isSubroutineDIE())
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000328 return 0;
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000329 // Try to get mangled name if possible.
330 if (const char *name =
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000331 getAttributeValueAsString(CU, DW_AT_MIPS_linkage_name, 0))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000332 return name;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000333 if (const char *name = getAttributeValueAsString(CU, DW_AT_linkage_name, 0))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000334 return name;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000335 if (const char *name = getAttributeValueAsString(CU, DW_AT_name, 0))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000336 return name;
337 // Try to get name from specification DIE.
338 uint32_t spec_ref =
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000339 getAttributeValueAsReference(CU, DW_AT_specification, -1U);
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000340 if (spec_ref != -1U) {
341 DWARFDebugInfoEntryMinimal spec_die;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000342 if (spec_die.extract(CU, &spec_ref)) {
343 if (const char *name = spec_die.getSubroutineName(CU))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000344 return name;
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000345 }
346 }
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000347 // Try to get name from abstract origin DIE.
348 uint32_t abs_origin_ref =
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000349 getAttributeValueAsReference(CU, DW_AT_abstract_origin, -1U);
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000350 if (abs_origin_ref != -1U) {
351 DWARFDebugInfoEntryMinimal abs_origin_die;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000352 if (abs_origin_die.extract(CU, &abs_origin_ref)) {
353 if (const char *name = abs_origin_die.getSubroutineName(CU))
Alexey Samsonov9d26b0b2012-07-17 15:28:35 +0000354 return name;
355 }
356 }
357 return 0;
Alexey Samsonov3e25c4a2012-07-02 05:54:45 +0000358}
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000359
Eric Christopher203e6f62012-10-30 21:36:43 +0000360void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFCompileUnit *CU,
361 uint32_t &CallFile,
362 uint32_t &CallLine,
363 uint32_t &CallColumn) const {
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000364 CallFile = getAttributeValueAsUnsigned(CU, DW_AT_call_file, 0);
365 CallLine = getAttributeValueAsUnsigned(CU, DW_AT_call_line, 0);
366 CallColumn = getAttributeValueAsUnsigned(CU, DW_AT_call_column, 0);
367}
368
Alexey Samsonove6642902013-08-06 10:49:15 +0000369DWARFDebugInfoEntryInlinedChain
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000370DWARFDebugInfoEntryMinimal::getInlinedChainForAddress(
Alexey Samsonove6642902013-08-06 10:49:15 +0000371 const DWARFCompileUnit *CU, const uint64_t Address) const {
372 DWARFDebugInfoEntryInlinedChain InlinedChain;
373 InlinedChain.CU = CU;
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000374 if (isNULL())
375 return InlinedChain;
376 for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) {
377 // Append current DIE to inlined chain only if it has correct tag
378 // (e.g. it is not a lexical block).
379 if (DIE->isSubroutineDIE()) {
Alexey Samsonove6642902013-08-06 10:49:15 +0000380 InlinedChain.DIEs.push_back(*DIE);
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000381 }
382 // Try to get child which also contains provided address.
383 const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild();
384 while (Child) {
385 if (Child->addressRangeContainsAddress(CU, Address)) {
386 // Assume there is only one such child.
387 break;
388 }
389 Child = Child->getSibling();
390 }
391 DIE = Child;
392 }
393 // Reverse the obtained chain to make the root of inlined chain last.
Alexey Samsonove6642902013-08-06 10:49:15 +0000394 std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end());
Alexey Samsonov5eae90d2012-09-04 08:12:33 +0000395 return InlinedChain;
396}