Home | History | Annotate | Download | only in DebugInfo
      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 << 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 
     67 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 
     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
    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
    342 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*
    377 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
    391 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
    402 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
    413 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
    424 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