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