Sketch out a DWARF parser.
[oota-llvm.git] / lib / DebugInfo / DWARFDebugInfoEntry.cpp
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 "DWARFFormValue.h"
15 #include "llvm/Support/Dwarf.h"
16 #include "llvm/Support/Format.h"
17 #include "llvm/Support/raw_ostream.h"
18 using namespace llvm;
19 using namespace dwarf;
20
21 void 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
65 void 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
85 bool 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
199 bool
200 DWARFDebugInfoEntryMinimal::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
330 uint32_t
331 DWARFDebugInfoEntryMinimal::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
366 const char*
367 DWARFDebugInfoEntryMinimal::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
380 uint64_t
381 DWARFDebugInfoEntryMinimal::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
391 int64_t
392 DWARFDebugInfoEntryMinimal::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
402 uint64_t
403 DWARFDebugInfoEntryMinimal::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 }