• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
dump(raw_ostream & OS,const DWARFCompileUnit * cu,unsigned recurseDepth,unsigned indent) const21 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 << 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 
dumpAttribute(raw_ostream & OS,const DWARFCompileUnit * cu,uint32_t * offset_ptr,uint16_t attr,uint16_t form,unsigned indent) const67 void 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 
extractFast(const DWARFCompileUnit * cu,const uint8_t * fixed_form_sizes,uint32_t * offset_ptr)96 bool 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   return false;
208 }
209 
210 bool
extract(const DWARFCompileUnit * cu,uint32_t * offset_ptr)211 DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *cu,
212                                     uint32_t *offset_ptr) {
213   DataExtractor debug_info_data = cu->getDebugInfoExtractor();
214   const uint32_t cu_end_offset = cu->getNextCompileUnitOffset();
215   const uint8_t cu_addr_size = cu->getAddressByteSize();
216   uint32_t offset = *offset_ptr;
217   if ((offset < cu_end_offset) && debug_info_data.isValidOffset(offset)) {
218     Offset = offset;
219 
220     uint64_t abbrCode = debug_info_data.getULEB128(&offset);
221 
222     if (abbrCode) {
223       AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode);
224 
225       if (AbbrevDecl) {
226         uint16_t tag = AbbrevDecl->getTag();
227 
228         bool isCompileUnitTag = tag == DW_TAG_compile_unit;
229         if(cu && isCompileUnitTag)
230           const_cast<DWARFCompileUnit*>(cu)->setBaseAddress(0);
231 
232         // Skip all data in the .debug_info for the attributes
233         const uint32_t numAttributes = AbbrevDecl->getNumAttributes();
234         for (uint32_t i = 0; i != numAttributes; ++i) {
235           uint16_t attr = AbbrevDecl->getAttrByIndex(i);
236           uint16_t form = AbbrevDecl->getFormByIndex(i);
237 
238           if (isCompileUnitTag &&
239               ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
240             DWARFFormValue form_value(form);
241             if (form_value.extractValue(debug_info_data, &offset, cu)) {
242               if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
243                 const_cast<DWARFCompileUnit*>(cu)
244                   ->setBaseAddress(form_value.getUnsigned());
245             }
246           } else {
247             bool form_is_indirect = false;
248             do {
249               form_is_indirect = false;
250               register uint32_t form_size = 0;
251               switch (form) {
252               // Blocks if inlined data that have a length field and the data
253               // bytes // inlined in the .debug_info
254               case DW_FORM_block:
255                 form_size = debug_info_data.getULEB128(&offset);
256                 break;
257               case DW_FORM_block1:
258                 form_size = debug_info_data.getU8(&offset);
259                 break;
260               case DW_FORM_block2:
261                 form_size = debug_info_data.getU16(&offset);
262                 break;
263               case DW_FORM_block4:
264                 form_size = debug_info_data.getU32(&offset);
265                 break;
266 
267               // Inlined NULL terminated C-strings
268               case DW_FORM_string:
269                 debug_info_data.getCStr(&offset);
270                 break;
271 
272               // Compile unit address sized values
273               case DW_FORM_addr:
274               case DW_FORM_ref_addr:
275                 form_size = cu_addr_size;
276                 break;
277 
278               // 1 byte values
279               case DW_FORM_data1:
280               case DW_FORM_flag:
281               case DW_FORM_ref1:
282                 form_size = 1;
283                 break;
284 
285               // 2 byte values
286               case DW_FORM_data2:
287               case DW_FORM_ref2:
288                 form_size = 2;
289                 break;
290 
291                 // 4 byte values
292               case DW_FORM_strp:
293                 form_size = 4;
294                 break;
295 
296               case DW_FORM_data4:
297               case DW_FORM_ref4:
298                 form_size = 4;
299                 break;
300 
301               // 8 byte values
302               case DW_FORM_data8:
303               case DW_FORM_ref8:
304                 form_size = 8;
305                 break;
306 
307               // signed or unsigned LEB 128 values
308               case DW_FORM_sdata:
309               case DW_FORM_udata:
310               case DW_FORM_ref_udata:
311                 debug_info_data.getULEB128(&offset);
312                 break;
313 
314               case DW_FORM_indirect:
315                 form = debug_info_data.getULEB128(&offset);
316                 form_is_indirect = true;
317                 break;
318 
319               default:
320                 *offset_ptr = offset;
321                 return false;
322               }
323 
324               offset += form_size;
325             } while (form_is_indirect);
326           }
327         }
328         *offset_ptr = offset;
329         return true;
330       }
331     } else {
332       AbbrevDecl = NULL;
333       *offset_ptr = offset;
334       return true;    // NULL debug tag entry
335     }
336   }
337 
338   return false;
339 }
340 
341 uint32_t
getAttributeValue(const DWARFCompileUnit * cu,const uint16_t attr,DWARFFormValue & form_value,uint32_t * end_attr_offset_ptr) const342 DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu,
343                                               const uint16_t attr,
344                                               DWARFFormValue &form_value,
345                                               uint32_t *end_attr_offset_ptr)
346                                               const {
347   if (AbbrevDecl) {
348     uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr);
349 
350     if (attr_idx != -1U) {
351       uint32_t offset = getOffset();
352 
353       DataExtractor debug_info_data = cu->getDebugInfoExtractor();
354 
355       // Skip the abbreviation code so we are at the data for the attributes
356       debug_info_data.getULEB128(&offset);
357 
358       uint32_t idx = 0;
359       while (idx < attr_idx)
360         DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++),
361                                   debug_info_data, &offset, cu);
362 
363       const uint32_t attr_offset = offset;
364       form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx));
365       if (form_value.extractValue(debug_info_data, &offset, cu)) {
366         if (end_attr_offset_ptr)
367           *end_attr_offset_ptr = offset;
368         return attr_offset;
369       }
370     }
371   }
372 
373   return 0;
374 }
375 
376 const char*
getAttributeValueAsString(const DWARFCompileUnit * cu,const uint16_t attr,const char * fail_value) const377 DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
378     const DWARFCompileUnit* cu,
379     const uint16_t attr,
380     const char* fail_value) const {
381   DWARFFormValue form_value;
382   if (getAttributeValue(cu, attr, form_value)) {
383     DataExtractor stringExtractor(cu->getContext().getStringSection(),
384         false, 0);
385     return form_value.getAsCString(&stringExtractor);
386   }
387   return fail_value;
388 }
389 
390 uint64_t
getAttributeValueAsUnsigned(const DWARFCompileUnit * cu,const uint16_t attr,uint64_t fail_value) const391 DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned(
392     const DWARFCompileUnit* cu,
393     const uint16_t attr,
394     uint64_t fail_value) const {
395   DWARFFormValue form_value;
396   if (getAttributeValue(cu, attr, form_value))
397       return form_value.getUnsigned();
398   return fail_value;
399 }
400 
401 int64_t
getAttributeValueAsSigned(const DWARFCompileUnit * cu,const uint16_t attr,int64_t fail_value) const402 DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned(
403     const DWARFCompileUnit* cu,
404     const uint16_t attr,
405     int64_t fail_value) const {
406   DWARFFormValue form_value;
407   if (getAttributeValue(cu, attr, form_value))
408       return form_value.getSigned();
409   return fail_value;
410 }
411 
412 uint64_t
getAttributeValueAsReference(const DWARFCompileUnit * cu,const uint16_t attr,uint64_t fail_value) const413 DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
414                                                   const DWARFCompileUnit* cu,
415                                                   const uint16_t attr,
416                                                   uint64_t fail_value) const {
417   DWARFFormValue form_value;
418   if (getAttributeValue(cu, attr, form_value))
419       return form_value.getReference(cu);
420   return fail_value;
421 }
422 
423 void
buildAddressRangeTable(const DWARFCompileUnit * cu,DWARFDebugAranges * debug_aranges) const424 DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *cu,
425                                                DWARFDebugAranges *debug_aranges)
426                                                    const {
427   if (AbbrevDecl) {
428     uint16_t tag = AbbrevDecl->getTag();
429     if (tag == DW_TAG_subprogram) {
430       uint64_t hi_pc = -1ULL;
431       uint64_t lo_pc = getAttributeValueAsUnsigned(cu, DW_AT_low_pc, -1ULL);
432       if (lo_pc != -1ULL)
433         hi_pc = getAttributeValueAsUnsigned(cu, DW_AT_high_pc, -1ULL);
434       if (hi_pc != -1ULL)
435         debug_aranges->appendRange(cu->getOffset(), lo_pc, hi_pc);
436     }
437 
438     const DWARFDebugInfoEntryMinimal *child = getFirstChild();
439     while (child) {
440       child->buildAddressRangeTable(cu, debug_aranges);
441       child = child->getSibling();
442     }
443   }
444 }
445