1 //===-- DWARFDebugInfoEntry.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 "DWARFDebugInfoEntry.h"
11 #include "DWARFCompileUnit.h"
12 #include "DWARFContext.h"
13 #include "DWARFDebugAbbrev.h"
14 #include "llvm/DebugInfo/DWARFFormValue.h"
15 #include "llvm/Support/Debug.h"
16 #include "llvm/Support/Dwarf.h"
17 #include "llvm/Support/Format.h"
18 #include "llvm/Support/raw_ostream.h"
19 using namespace llvm;
20 using namespace dwarf;
21
dump(raw_ostream & OS,const DWARFCompileUnit * cu,unsigned recurseDepth,unsigned indent) const22 void 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)) {
30 uint32_t abbrCode = debug_info_data.getULEB128(&offset);
31
32 OS << format("\n0x%8.8x: ", Offset);
33 if (abbrCode) {
34 if (AbbrevDecl) {
35 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() ? '*' : ' ');
42
43 // Dump all data in the DIE for the attributes.
44 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) {
53 while (child) {
54 child->dump(OS, cu, recurseDepth-1, indent+2);
55 child = child->getSibling();
56 }
57 }
58 } else {
59 OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
60 << abbrCode << '\n';
61 }
62 } else {
63 OS.indent(indent) << "NULL\n";
64 }
65 }
66 }
67
dumpAttribute(raw_ostream & OS,const DWARFCompileUnit * cu,uint32_t * offset_ptr,uint16_t attr,uint16_t form,unsigned indent) const68 void 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 {
74 OS << format("0x%8.8x: ", *offset_ptr);
75 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);
86
87 DWARFFormValue formValue(form);
88
89 if (!formValue.extractValue(cu->getDebugInfoExtractor(), offset_ptr, cu))
90 return;
91
92 OS << "\t(";
93 formValue.dump(OS, cu);
94 OS << ")\n";
95 }
96
extractFast(const DWARFCompileUnit * CU,const uint8_t * FixedFormSizes,uint32_t * OffsetPtr)97 bool 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.
105 AbbrevDecl = NULL;
106 return true;
107 }
108 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;
131 }
132
133 bool
extract(const DWARFCompileUnit * CU,uint32_t * OffsetPtr)134 DWARFDebugInfoEntryMinimal::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);
156
157 // 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);
161
162 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());
169 }
170 } else if (!DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr,
171 CU)) {
172 // Restore the original offset.
173 *OffsetPtr = Offset;
174 return false;
175 }
176 }
177 return true;
178 }
179
isSubprogramDIE() const180 bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const {
181 return getTag() == DW_TAG_subprogram;
182 }
183
isSubroutineDIE() const184 bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const {
185 uint32_t Tag = getTag();
186 return Tag == DW_TAG_subprogram ||
187 Tag == DW_TAG_inlined_subroutine;
188 }
189
190 uint32_t
getAttributeValue(const DWARFCompileUnit * cu,const uint16_t attr,DWARFFormValue & form_value,uint32_t * end_attr_offset_ptr) const191 DWARFDebugInfoEntryMinimal::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));
214 if (form_value.extractValue(debug_info_data, &offset, cu)) {
215 if (end_attr_offset_ptr)
216 *end_attr_offset_ptr = offset;
217 return attr_offset;
218 }
219 }
220 }
221
222 return 0;
223 }
224
225 const char*
getAttributeValueAsString(const DWARFCompileUnit * cu,const uint16_t attr,const char * fail_value) const226 DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
227 const DWARFCompileUnit* cu,
228 const uint16_t attr,
229 const char* fail_value)
230 const {
231 DWARFFormValue form_value;
232 if (getAttributeValue(cu, attr, form_value)) {
233 DataExtractor stringExtractor(cu->getStringSection(), false, 0);
234 return form_value.getAsCString(&stringExtractor);
235 }
236 return fail_value;
237 }
238
239 uint64_t
getAttributeValueAsUnsigned(const DWARFCompileUnit * cu,const uint16_t attr,uint64_t fail_value) const240 DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
241 const DWARFCompileUnit* cu,
242 const uint16_t attr,
243 uint64_t fail_value) const {
244 DWARFFormValue form_value;
245 if (getAttributeValue(cu, attr, form_value))
246 return form_value.getUnsigned();
247 return fail_value;
248 }
249
250 int64_t
getAttributeValueAsSigned(const DWARFCompileUnit * cu,const uint16_t attr,int64_t fail_value) const251 DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned(
252 const DWARFCompileUnit* cu,
253 const uint16_t attr,
254 int64_t fail_value) const {
255 DWARFFormValue form_value;
256 if (getAttributeValue(cu, attr, form_value))
257 return form_value.getSigned();
258 return fail_value;
259 }
260
261 uint64_t
getAttributeValueAsReference(const DWARFCompileUnit * cu,const uint16_t attr,uint64_t fail_value) const262 DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
263 const DWARFCompileUnit* cu,
264 const uint16_t attr,
265 uint64_t fail_value)
266 const {
267 DWARFFormValue form_value;
268 if (getAttributeValue(cu, attr, form_value))
269 return form_value.getReference(cu);
270 return fail_value;
271 }
272
getLowAndHighPC(const DWARFCompileUnit * CU,uint64_t & LowPC,uint64_t & HighPC) const273 bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFCompileUnit *CU,
274 uint64_t &LowPC,
275 uint64_t &HighPC) const {
276 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
283 void
buildAddressRangeTable(const DWARFCompileUnit * CU,DWARFDebugAranges * DebugAranges) const284 DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *CU,
285 DWARFDebugAranges *DebugAranges)
286 const {
287 if (AbbrevDecl) {
288 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.
294 }
295
296 const DWARFDebugInfoEntryMinimal *child = getFirstChild();
297 while (child) {
298 child->buildAddressRangeTable(CU, DebugAranges);
299 child = child->getSibling();
300 }
301 }
302 }
303
304 bool
addressRangeContainsAddress(const DWARFCompileUnit * CU,const uint64_t Address) const305 DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
306 const DWARFCompileUnit *CU,
307 const uint64_t Address)
308 const {
309 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);
320 }
321 return false;
322 }
323
324 const char*
getSubroutineName(const DWARFCompileUnit * CU) const325 DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFCompileUnit *CU)
326 const {
327 if (!isSubroutineDIE())
328 return 0;
329 // Try to get mangled name if possible.
330 if (const char *name =
331 getAttributeValueAsString(CU, DW_AT_MIPS_linkage_name, 0))
332 return name;
333 if (const char *name = getAttributeValueAsString(CU, DW_AT_linkage_name, 0))
334 return name;
335 if (const char *name = getAttributeValueAsString(CU, DW_AT_name, 0))
336 return name;
337 // Try to get name from specification DIE.
338 uint32_t spec_ref =
339 getAttributeValueAsReference(CU, DW_AT_specification, -1U);
340 if (spec_ref != -1U) {
341 DWARFDebugInfoEntryMinimal spec_die;
342 if (spec_die.extract(CU, &spec_ref)) {
343 if (const char *name = spec_die.getSubroutineName(CU))
344 return name;
345 }
346 }
347 // Try to get name from abstract origin DIE.
348 uint32_t abs_origin_ref =
349 getAttributeValueAsReference(CU, DW_AT_abstract_origin, -1U);
350 if (abs_origin_ref != -1U) {
351 DWARFDebugInfoEntryMinimal abs_origin_die;
352 if (abs_origin_die.extract(CU, &abs_origin_ref)) {
353 if (const char *name = abs_origin_die.getSubroutineName(CU))
354 return name;
355 }
356 }
357 return 0;
358 }
359
getCallerFrame(const DWARFCompileUnit * CU,uint32_t & CallFile,uint32_t & CallLine,uint32_t & CallColumn) const360 void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFCompileUnit *CU,
361 uint32_t &CallFile,
362 uint32_t &CallLine,
363 uint32_t &CallColumn) const {
364 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
369 DWARFDebugInfoEntryInlinedChain
getInlinedChainForAddress(const DWARFCompileUnit * CU,const uint64_t Address) const370 DWARFDebugInfoEntryMinimal::getInlinedChainForAddress(
371 const DWARFCompileUnit *CU, const uint64_t Address) const {
372 DWARFDebugInfoEntryInlinedChain InlinedChain;
373 InlinedChain.CU = CU;
374 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()) {
380 InlinedChain.DIEs.push_back(*DIE);
381 }
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.
394 std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end());
395 return InlinedChain;
396 }
397