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