blob: 627fad5afce6f4897caf5deee67ef14a8381bf38 [file] [log] [blame]
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +00001//===-- 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 "DWARFFormValue.h"
15#include "llvm/Support/Dwarf.h"
16#include "llvm/Support/Format.h"
17#include "llvm/Support/raw_ostream.h"
18using namespace llvm;
19using namespace dwarf;
20
21void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS,
22 const DWARFCompileUnit *cu,
23 unsigned recurseDepth,
24 unsigned indent) const {
25 DataExtractor debug_info_data = cu->getDebugInfoExtractor();
26 uint32_t offset = Offset;
27
28 if (debug_info_data.isValidOffset(offset)) {
29 uint64_t abbrCode = debug_info_data.getULEB128(&offset);
30
Benjamin Kramer09422552011-09-14 17:54:56 +000031 OS << format("\n0x%8.8x: ", Offset);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000032 if (abbrCode) {
33 if (AbbrevDecl) {
Benjamin Kramer09422552011-09-14 17:54:56 +000034 OS.indent(indent) << TagString(AbbrevDecl->getTag())
35 << format(" [%u] %c\n", abbrCode,
36 AbbrevDecl->hasChildren() ? '*': ' ');
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000037
38 // Dump all data in the .debug_info for the attributes
39 const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
40 for (uint32_t i = 0; i != numAttributes; ++i) {
41 uint16_t attr = AbbrevDecl->getAttrByIndex(i);
42 uint16_t form = AbbrevDecl->getFormByIndex(i);
43 dumpAttribute(OS, cu, &offset, attr, form, indent);
44 }
45
46 const DWARFDebugInfoEntryMinimal *child = getFirstChild();
47 if (recurseDepth > 0 && child) {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000048 while (child) {
Benjamin Kramer15ec0852011-09-14 00:15:32 +000049 child->dump(OS, cu, recurseDepth-1, indent+2);
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000050 child = child->getSibling();
51 }
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000052 }
53 } else {
54 OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
55 << abbrCode << '\n';
56 }
57 } else {
Benjamin Kramer09422552011-09-14 17:54:56 +000058 OS.indent(indent) << "NULL\n";
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000059 }
60 }
61}
62
63void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS,
64 const DWARFCompileUnit *cu,
65 uint32_t* offset_ptr,
66 uint16_t attr,
67 uint16_t form,
68 unsigned indent) const {
Benjamin Kramer09422552011-09-14 17:54:56 +000069 OS << format("0x%8.8x: ", *offset_ptr);
70 OS.indent(indent+2) << AttributeString(attr)
71 << " [" << FormEncodingString(form) << ']';
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000072
73 DWARFFormValue formValue(form);
74
75 if (!formValue.extractValue(cu->getDebugInfoExtractor(), offset_ptr, cu))
76 return;
77
78 OS << "\t(";
79 formValue.dump(OS, 0, cu);
80 OS << ")\n";
81}
82
83bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *cu,
84 const uint8_t *fixed_form_sizes,
85 uint32_t *offset_ptr) {
86 Offset = *offset_ptr;
87
88 DataExtractor debug_info_data = cu->getDebugInfoExtractor();
89 uint64_t abbrCode = debug_info_data.getULEB128(offset_ptr);
90
91 assert (fixed_form_sizes); // For best performance this should be specified!
92
93 if (abbrCode) {
94 uint32_t offset = *offset_ptr;
95
96 AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode);
97
98 // Skip all data in the .debug_info for the attributes
99 const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
100 uint32_t i;
101 uint16_t form;
102 for (i=0; i<numAttributes; ++i) {
103 form = AbbrevDecl->getFormByIndex(i);
104
105 const uint8_t fixed_skip_size = fixed_form_sizes[form];
106 if (fixed_skip_size)
107 offset += fixed_skip_size;
108 else {
109 bool form_is_indirect = false;
110 do {
111 form_is_indirect = false;
112 uint32_t form_size = 0;
113 switch (form) {
114 // Blocks if inlined data that have a length field and the data bytes
115 // inlined in the .debug_info.
116 case DW_FORM_block:
117 form_size = debug_info_data.getULEB128(&offset);
118 break;
119 case DW_FORM_block1:
120 form_size = debug_info_data.getU8(&offset);
121 break;
122 case DW_FORM_block2:
123 form_size = debug_info_data.getU16(&offset);
124 break;
125 case DW_FORM_block4:
126 form_size = debug_info_data.getU32(&offset);
127 break;
128
129 // Inlined NULL terminated C-strings
130 case DW_FORM_string:
131 debug_info_data.getCStr(&offset);
132 break;
133
134 // Compile unit address sized values
135 case DW_FORM_addr:
136 case DW_FORM_ref_addr:
137 form_size = cu->getAddressByteSize();
138 break;
139
140 // 1 byte values
141 case DW_FORM_data1:
142 case DW_FORM_flag:
143 case DW_FORM_ref1:
144 form_size = 1;
145 break;
146
147 // 2 byte values
148 case DW_FORM_data2:
149 case DW_FORM_ref2:
150 form_size = 2;
151 break;
152
153 // 4 byte values
154 case DW_FORM_strp:
155 case DW_FORM_data4:
156 case DW_FORM_ref4:
157 form_size = 4;
158 break;
159
160 // 8 byte values
161 case DW_FORM_data8:
162 case DW_FORM_ref8:
163 form_size = 8;
164 break;
165
166 // signed or unsigned LEB 128 values
167 case DW_FORM_sdata:
168 case DW_FORM_udata:
169 case DW_FORM_ref_udata:
170 debug_info_data.getULEB128(&offset);
171 break;
172
173 case DW_FORM_indirect:
174 form_is_indirect = true;
175 form = debug_info_data.getULEB128(&offset);
176 break;
177
178 default:
179 *offset_ptr = Offset;
180 return false;
181 }
182 offset += form_size;
183
184 } while (form_is_indirect);
185 }
186 }
187 *offset_ptr = offset;
188 return true;
189 } else {
190 AbbrevDecl = NULL;
191 return true; // NULL debug tag entry
192 }
193
194 return false;
195}
196
197bool
198DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *cu,
199 uint32_t *offset_ptr) {
200 DataExtractor debug_info_data = cu->getDebugInfoExtractor();
201 const uint32_t cu_end_offset = cu->getNextCompileUnitOffset();
202 const uint8_t cu_addr_size = cu->getAddressByteSize();
203 uint32_t offset = *offset_ptr;
204 if ((offset < cu_end_offset) && debug_info_data.isValidOffset(offset)) {
205 Offset = offset;
206
207 uint64_t abbrCode = debug_info_data.getULEB128(&offset);
208
209 if (abbrCode) {
210 AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode);
211
212 if (AbbrevDecl) {
213 uint16_t tag = AbbrevDecl->getTag();
214
215 bool isCompileUnitTag = tag == DW_TAG_compile_unit;
216 if(cu && isCompileUnitTag)
217 const_cast<DWARFCompileUnit*>(cu)->setBaseAddress(0);
218
219 // Skip all data in the .debug_info for the attributes
220 const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
221 for (uint32_t i = 0; i != numAttributes; ++i) {
222 uint16_t attr = AbbrevDecl->getAttrByIndex(i);
223 uint16_t form = AbbrevDecl->getFormByIndex(i);
224
225 if (isCompileUnitTag &&
226 ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
227 DWARFFormValue form_value(form);
228 if (form_value.extractValue(debug_info_data, &offset, cu)) {
229 if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
230 const_cast<DWARFCompileUnit*>(cu)
231 ->setBaseAddress(form_value.getUnsigned());
232 }
233 } else {
234 bool form_is_indirect = false;
235 do {
236 form_is_indirect = false;
237 register uint32_t form_size = 0;
238 switch (form) {
239 // Blocks if inlined data that have a length field and the data
240 // bytes // inlined in the .debug_info
241 case DW_FORM_block:
242 form_size = debug_info_data.getULEB128(&offset);
243 break;
244 case DW_FORM_block1:
245 form_size = debug_info_data.getU8(&offset);
246 break;
247 case DW_FORM_block2:
248 form_size = debug_info_data.getU16(&offset);
249 break;
250 case DW_FORM_block4:
251 form_size = debug_info_data.getU32(&offset);
252 break;
253
254 // Inlined NULL terminated C-strings
255 case DW_FORM_string:
256 debug_info_data.getCStr(&offset);
257 break;
258
259 // Compile unit address sized values
260 case DW_FORM_addr:
261 case DW_FORM_ref_addr:
262 form_size = cu_addr_size;
263 break;
264
265 // 1 byte values
266 case DW_FORM_data1:
267 case DW_FORM_flag:
268 case DW_FORM_ref1:
269 form_size = 1;
270 break;
271
272 // 2 byte values
273 case DW_FORM_data2:
274 case DW_FORM_ref2:
275 form_size = 2;
276 break;
277
278 // 4 byte values
279 case DW_FORM_strp:
280 form_size = 4;
281 break;
282
283 case DW_FORM_data4:
284 case DW_FORM_ref4:
285 form_size = 4;
286 break;
287
288 // 8 byte values
289 case DW_FORM_data8:
290 case DW_FORM_ref8:
291 form_size = 8;
292 break;
293
294 // signed or unsigned LEB 128 values
295 case DW_FORM_sdata:
296 case DW_FORM_udata:
297 case DW_FORM_ref_udata:
298 debug_info_data.getULEB128(&offset);
299 break;
300
301 case DW_FORM_indirect:
302 form = debug_info_data.getULEB128(&offset);
303 form_is_indirect = true;
304 break;
305
306 default:
307 *offset_ptr = offset;
308 return false;
309 }
310
311 offset += form_size;
312 } while (form_is_indirect);
313 }
314 }
315 *offset_ptr = offset;
316 return true;
317 }
318 } else {
319 AbbrevDecl = NULL;
320 *offset_ptr = offset;
321 return true; // NULL debug tag entry
322 }
323 }
324
325 return false;
326}
327
328uint32_t
329DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu,
330 const uint16_t attr,
331 DWARFFormValue &form_value,
332 uint32_t *end_attr_offset_ptr)
333 const {
334 if (AbbrevDecl) {
335 uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr);
336
337 if (attr_idx != -1U) {
338 uint32_t offset = getOffset();
339
340 DataExtractor debug_info_data = cu->getDebugInfoExtractor();
341
342 // Skip the abbreviation code so we are at the data for the attributes
343 debug_info_data.getULEB128(&offset);
344
345 uint32_t idx = 0;
346 while (idx < attr_idx)
347 DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++),
348 debug_info_data, &offset, cu);
349
350 const uint32_t attr_offset = offset;
351 form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx));
Benjamin Kramer4aa3fea2011-09-13 21:47:32 +0000352 if (form_value.extractValue(debug_info_data, &offset, cu)) {
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +0000353 if (end_attr_offset_ptr)
354 *end_attr_offset_ptr = offset;
355 return attr_offset;
356 }
357 }
358 }
359
360 return 0;
361}
362
363const char*
364DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
365 const DWARFCompileUnit* cu,
366 const uint16_t attr,
367 const char* fail_value) const {
368 DWARFFormValue form_value;
369 if (getAttributeValue(cu, attr, form_value)) {
370 DataExtractor stringExtractor(cu->getContext().getStringSection(),
371 false, 0);
372 return form_value.getAsCString(&stringExtractor);
373 }
374 return fail_value;
375}
376
377uint64_t
378DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
379 const DWARFCompileUnit* cu,
380 const uint16_t attr,
381 uint64_t fail_value) const {
382 DWARFFormValue form_value;
383 if (getAttributeValue(cu, attr, form_value))
384 return form_value.getUnsigned();
385 return fail_value;
386}
387
388int64_t
389DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned(
390 const DWARFCompileUnit* cu,
391 const uint16_t attr,
392 int64_t fail_value) const {
393 DWARFFormValue form_value;
394 if (getAttributeValue(cu, attr, form_value))
395 return form_value.getSigned();
396 return fail_value;
397}
398
399uint64_t
400DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(const DWARFCompileUnit* cu,
401 const uint16_t attr,
402 uint64_t fail_value) const {
403 DWARFFormValue form_value;
404 if (getAttributeValue(cu, attr, form_value))
405 return form_value.getReference(cu);
406 return fail_value;
407}