Home | History | Annotate | Download | only in DebugInfo
      1 //===-- DWARFFormValue.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 "DWARFFormValue.h"
     11 #include "DWARFCompileUnit.h"
     12 #include "DWARFContext.h"
     13 #include "llvm/Support/Debug.h"
     14 #include "llvm/Support/Dwarf.h"
     15 #include "llvm/Support/Format.h"
     16 #include "llvm/Support/raw_ostream.h"
     17 #include <cassert>
     18 using namespace llvm;
     19 using namespace dwarf;
     20 
     21 static const uint8_t form_sizes_addr4[] = {
     22   0, // 0x00 unused
     23   4, // 0x01 DW_FORM_addr
     24   0, // 0x02 unused
     25   0, // 0x03 DW_FORM_block2
     26   0, // 0x04 DW_FORM_block4
     27   2, // 0x05 DW_FORM_data2
     28   4, // 0x06 DW_FORM_data4
     29   8, // 0x07 DW_FORM_data8
     30   0, // 0x08 DW_FORM_string
     31   0, // 0x09 DW_FORM_block
     32   0, // 0x0a DW_FORM_block1
     33   1, // 0x0b DW_FORM_data1
     34   1, // 0x0c DW_FORM_flag
     35   0, // 0x0d DW_FORM_sdata
     36   4, // 0x0e DW_FORM_strp
     37   0, // 0x0f DW_FORM_udata
     38   4, // 0x10 DW_FORM_ref_addr
     39   1, // 0x11 DW_FORM_ref1
     40   2, // 0x12 DW_FORM_ref2
     41   4, // 0x13 DW_FORM_ref4
     42   8, // 0x14 DW_FORM_ref8
     43   0, // 0x15 DW_FORM_ref_udata
     44   0, // 0x16 DW_FORM_indirect
     45   4, // 0x17 DW_FORM_sec_offset
     46   0, // 0x18 DW_FORM_exprloc
     47   0, // 0x19 DW_FORM_flag_present
     48   8, // 0x20 DW_FORM_ref_sig8
     49 };
     50 
     51 static const uint8_t form_sizes_addr8[] = {
     52   0, // 0x00 unused
     53   8, // 0x01 DW_FORM_addr
     54   0, // 0x02 unused
     55   0, // 0x03 DW_FORM_block2
     56   0, // 0x04 DW_FORM_block4
     57   2, // 0x05 DW_FORM_data2
     58   4, // 0x06 DW_FORM_data4
     59   8, // 0x07 DW_FORM_data8
     60   0, // 0x08 DW_FORM_string
     61   0, // 0x09 DW_FORM_block
     62   0, // 0x0a DW_FORM_block1
     63   1, // 0x0b DW_FORM_data1
     64   1, // 0x0c DW_FORM_flag
     65   0, // 0x0d DW_FORM_sdata
     66   4, // 0x0e DW_FORM_strp
     67   0, // 0x0f DW_FORM_udata
     68   8, // 0x10 DW_FORM_ref_addr
     69   1, // 0x11 DW_FORM_ref1
     70   2, // 0x12 DW_FORM_ref2
     71   4, // 0x13 DW_FORM_ref4
     72   8, // 0x14 DW_FORM_ref8
     73   0, // 0x15 DW_FORM_ref_udata
     74   0, // 0x16 DW_FORM_indirect
     75   4, // 0x17 DW_FORM_sec_offset
     76   0, // 0x18 DW_FORM_exprloc
     77   0, // 0x19 DW_FORM_flag_present
     78   8, // 0x20 DW_FORM_ref_sig8
     79 };
     80 
     81 const uint8_t *
     82 DWARFFormValue::getFixedFormSizesForAddressSize(uint8_t addr_size) {
     83   switch (addr_size) {
     84   case 4: return form_sizes_addr4;
     85   case 8: return form_sizes_addr8;
     86   }
     87   return NULL;
     88 }
     89 
     90 bool
     91 DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr,
     92                              const DWARFCompileUnit *cu) {
     93   bool indirect = false;
     94   bool is_block = false;
     95   Value.data = NULL;
     96   // Read the value for the form into value and follow and DW_FORM_indirect
     97   // instances we run into
     98   do {
     99     indirect = false;
    100     switch (Form) {
    101     case DW_FORM_addr:
    102     case DW_FORM_ref_addr: {
    103       RelocAddrMap::const_iterator AI
    104         = cu->getRelocMap()->find(*offset_ptr);
    105       if (AI != cu->getRelocMap()->end()) {
    106         const std::pair<uint8_t, int64_t> &R = AI->second;
    107         Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize()) +
    108                      R.second;
    109       } else
    110         Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize());
    111       break;
    112     }
    113     case DW_FORM_exprloc:
    114     case DW_FORM_block:
    115       Value.uval = data.getULEB128(offset_ptr);
    116       is_block = true;
    117       break;
    118     case DW_FORM_block1:
    119       Value.uval = data.getU8(offset_ptr);
    120       is_block = true;
    121       break;
    122     case DW_FORM_block2:
    123       Value.uval = data.getU16(offset_ptr);
    124       is_block = true;
    125       break;
    126     case DW_FORM_block4:
    127       Value.uval = data.getU32(offset_ptr);
    128       is_block = true;
    129       break;
    130     case DW_FORM_data1:
    131     case DW_FORM_ref1:
    132     case DW_FORM_flag:
    133       Value.uval = data.getU8(offset_ptr);
    134       break;
    135     case DW_FORM_data2:
    136     case DW_FORM_ref2:
    137       Value.uval = data.getU16(offset_ptr);
    138       break;
    139     case DW_FORM_data4:
    140     case DW_FORM_ref4:
    141       Value.uval = data.getU32(offset_ptr);
    142       break;
    143     case DW_FORM_data8:
    144     case DW_FORM_ref8:
    145       Value.uval = data.getU64(offset_ptr);
    146       break;
    147     case DW_FORM_sdata:
    148       Value.sval = data.getSLEB128(offset_ptr);
    149       break;
    150     case DW_FORM_strp: {
    151       RelocAddrMap::const_iterator AI
    152         = cu->getRelocMap()->find(*offset_ptr);
    153       if (AI != cu->getRelocMap()->end()) {
    154         const std::pair<uint8_t, int64_t> &R = AI->second;
    155         Value.uval = data.getU32(offset_ptr) + R.second;
    156       } else
    157         Value.uval = data.getU32(offset_ptr);
    158       break;
    159     }
    160     case DW_FORM_udata:
    161     case DW_FORM_ref_udata:
    162       Value.uval = data.getULEB128(offset_ptr);
    163       break;
    164     case DW_FORM_string:
    165       Value.cstr = data.getCStr(offset_ptr);
    166       // Set the string value to also be the data for inlined cstr form
    167       // values only so we can tell the differnence between DW_FORM_string
    168       // and DW_FORM_strp form values
    169       Value.data = (const uint8_t*)Value.cstr;
    170       break;
    171     case DW_FORM_indirect:
    172       Form = data.getULEB128(offset_ptr);
    173       indirect = true;
    174       break;
    175     case DW_FORM_sec_offset:
    176       // FIXME: This is 64-bit for DWARF64.
    177       Value.uval = data.getU32(offset_ptr);
    178       break;
    179     case DW_FORM_flag_present:
    180       Value.uval = 1;
    181       break;
    182     case DW_FORM_ref_sig8:
    183       Value.uval = data.getU64(offset_ptr);
    184       break;
    185     case DW_FORM_GNU_addr_index:
    186       Value.uval = data.getULEB128(offset_ptr);
    187       break;
    188     case DW_FORM_GNU_str_index:
    189       Value.uval = data.getULEB128(offset_ptr);
    190       break;
    191     default:
    192       return false;
    193     }
    194   } while (indirect);
    195 
    196   if (is_block) {
    197     StringRef str = data.getData().substr(*offset_ptr, Value.uval);
    198     Value.data = NULL;
    199     if (!str.empty()) {
    200       Value.data = reinterpret_cast<const uint8_t *>(str.data());
    201       *offset_ptr += Value.uval;
    202     }
    203   }
    204 
    205   return true;
    206 }
    207 
    208 bool
    209 DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
    210                           const DWARFCompileUnit *cu) const {
    211   return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu);
    212 }
    213 
    214 bool
    215 DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
    216                           uint32_t *offset_ptr, const DWARFCompileUnit *cu) {
    217   bool indirect = false;
    218   do {
    219     indirect = false;
    220     switch (form) {
    221     // Blocks if inlined data that have a length field and the data bytes
    222     // inlined in the .debug_info
    223     case DW_FORM_exprloc:
    224     case DW_FORM_block: {
    225       uint64_t size = debug_info_data.getULEB128(offset_ptr);
    226       *offset_ptr += size;
    227       return true;
    228     }
    229     case DW_FORM_block1: {
    230       uint8_t size = debug_info_data.getU8(offset_ptr);
    231       *offset_ptr += size;
    232       return true;
    233     }
    234     case DW_FORM_block2: {
    235       uint16_t size = debug_info_data.getU16(offset_ptr);
    236       *offset_ptr += size;
    237       return true;
    238     }
    239     case DW_FORM_block4: {
    240       uint32_t size = debug_info_data.getU32(offset_ptr);
    241       *offset_ptr += size;
    242       return true;
    243     }
    244 
    245     // Inlined NULL terminated C-strings
    246     case DW_FORM_string:
    247       debug_info_data.getCStr(offset_ptr);
    248       return true;
    249 
    250     // Compile unit address sized values
    251     case DW_FORM_addr:
    252     case DW_FORM_ref_addr:
    253       *offset_ptr += cu->getAddressByteSize();
    254       return true;
    255 
    256     // 0 byte values - implied from the form.
    257     case DW_FORM_flag_present:
    258       return true;
    259 
    260     // 1 byte values
    261     case DW_FORM_data1:
    262     case DW_FORM_flag:
    263     case DW_FORM_ref1:
    264       *offset_ptr += 1;
    265       return true;
    266 
    267     // 2 byte values
    268     case DW_FORM_data2:
    269     case DW_FORM_ref2:
    270       *offset_ptr += 2;
    271       return true;
    272 
    273     // 4 byte values
    274     case DW_FORM_strp:
    275     case DW_FORM_data4:
    276     case DW_FORM_ref4:
    277       *offset_ptr += 4;
    278       return true;
    279 
    280     // 8 byte values
    281     case DW_FORM_data8:
    282     case DW_FORM_ref8:
    283     case DW_FORM_ref_sig8:
    284       *offset_ptr += 8;
    285       return true;
    286 
    287     // signed or unsigned LEB 128 values
    288     //  case DW_FORM_APPLE_db_str:
    289     case DW_FORM_sdata:
    290     case DW_FORM_udata:
    291     case DW_FORM_ref_udata:
    292     case DW_FORM_GNU_str_index:
    293     case DW_FORM_GNU_addr_index:
    294       debug_info_data.getULEB128(offset_ptr);
    295       return true;
    296 
    297     case DW_FORM_indirect:
    298       indirect = true;
    299       form = debug_info_data.getULEB128(offset_ptr);
    300       break;
    301 
    302     // FIXME: 4 for DWARF32, 8 for DWARF64.
    303     case DW_FORM_sec_offset:
    304       *offset_ptr += 4;
    305       return true;
    306 
    307     default:
    308       return false;
    309     }
    310   } while (indirect);
    311   return true;
    312 }
    313 
    314 void
    315 DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const {
    316   DataExtractor debug_str_data(cu->getStringSection(), true, 0);
    317   DataExtractor debug_str_offset_data(cu->getStringOffsetSection(), true, 0);
    318   uint64_t uvalue = getUnsigned();
    319   bool cu_relative_offset = false;
    320 
    321   switch (Form) {
    322   case DW_FORM_addr:      OS << format("0x%016" PRIx64, uvalue); break;
    323   case DW_FORM_GNU_addr_index: {
    324     StringRef AddrOffsetSec = cu->getAddrOffsetSection();
    325     OS << format(" indexed (%8.8x) address = ", (uint32_t)uvalue);
    326     if (AddrOffsetSec.size() != 0) {
    327       DataExtractor DA(AddrOffsetSec, true, cu->getAddressByteSize());
    328       OS << format("0x%016" PRIx64, getIndirectAddress(&DA, cu));
    329     } else
    330       OS << "<no .debug_addr section>";
    331     break;
    332   }
    333   case DW_FORM_flag_present: OS << "true"; break;
    334   case DW_FORM_flag:
    335   case DW_FORM_data1:     OS << format("0x%02x", (uint8_t)uvalue); break;
    336   case DW_FORM_data2:     OS << format("0x%04x", (uint16_t)uvalue); break;
    337   case DW_FORM_data4:     OS << format("0x%08x", (uint32_t)uvalue); break;
    338   case DW_FORM_ref_sig8:
    339   case DW_FORM_data8:     OS << format("0x%016" PRIx64, uvalue); break;
    340   case DW_FORM_string:
    341     OS << '"';
    342     OS.write_escaped(getAsCString(NULL));
    343     OS << '"';
    344     break;
    345   case DW_FORM_exprloc:
    346   case DW_FORM_block:
    347   case DW_FORM_block1:
    348   case DW_FORM_block2:
    349   case DW_FORM_block4:
    350     if (uvalue > 0) {
    351       switch (Form) {
    352       case DW_FORM_exprloc:
    353       case DW_FORM_block:  OS << format("<0x%" PRIx64 "> ", uvalue);     break;
    354       case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue);  break;
    355       case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break;
    356       case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break;
    357       default: break;
    358       }
    359 
    360       const uint8_t* data_ptr = Value.data;
    361       if (data_ptr) {
    362         // uvalue contains size of block
    363         const uint8_t* end_data_ptr = data_ptr + uvalue;
    364         while (data_ptr < end_data_ptr) {
    365           OS << format("%2.2x ", *data_ptr);
    366           ++data_ptr;
    367         }
    368       }
    369       else
    370         OS << "NULL";
    371     }
    372     break;
    373 
    374   case DW_FORM_sdata:     OS << getSigned();   break;
    375   case DW_FORM_udata:     OS << getUnsigned(); break;
    376   case DW_FORM_strp: {
    377     OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
    378     const char* dbg_str = getAsCString(&debug_str_data);
    379     if (dbg_str) {
    380       OS << '"';
    381       OS.write_escaped(dbg_str);
    382       OS << '"';
    383     }
    384     break;
    385   }
    386   case DW_FORM_GNU_str_index: {
    387     OS << format(" indexed (%8.8x) string = ", (uint32_t)uvalue);
    388     const char *dbg_str = getIndirectCString(&debug_str_data,
    389                                              &debug_str_offset_data);
    390     if (dbg_str) {
    391       OS << '"';
    392       OS.write_escaped(dbg_str);
    393       OS << '"';
    394     }
    395     break;
    396   }
    397   case DW_FORM_ref_addr:
    398     OS << format("0x%016" PRIx64, uvalue);
    399     break;
    400   case DW_FORM_ref1:
    401     cu_relative_offset = true;
    402     OS << format("cu + 0x%2.2x", (uint8_t)uvalue);
    403     break;
    404   case DW_FORM_ref2:
    405     cu_relative_offset = true;
    406     OS << format("cu + 0x%4.4x", (uint16_t)uvalue);
    407     break;
    408   case DW_FORM_ref4:
    409     cu_relative_offset = true;
    410     OS << format("cu + 0x%4.4x", (uint32_t)uvalue);
    411     break;
    412   case DW_FORM_ref8:
    413     cu_relative_offset = true;
    414     OS << format("cu + 0x%8.8" PRIx64, uvalue);
    415     break;
    416   case DW_FORM_ref_udata:
    417     cu_relative_offset = true;
    418     OS << format("cu + 0x%" PRIx64, uvalue);
    419     break;
    420 
    421     // All DW_FORM_indirect attributes should be resolved prior to calling
    422     // this function
    423   case DW_FORM_indirect:
    424     OS << "DW_FORM_indirect";
    425     break;
    426 
    427     // Should be formatted to 64-bit for DWARF64.
    428   case DW_FORM_sec_offset:
    429     OS << format("0x%08x", (uint32_t)uvalue);
    430     break;
    431 
    432   default:
    433     OS << format("DW_FORM(0x%4.4x)", Form);
    434     break;
    435   }
    436 
    437   if (cu_relative_offset)
    438     OS << format(" => {0x%8.8" PRIx64 "}", uvalue + (cu ? cu->getOffset() : 0));
    439 }
    440 
    441 const char*
    442 DWARFFormValue::getAsCString(const DataExtractor *debug_str_data_ptr) const {
    443   if (isInlinedCStr()) {
    444     return Value.cstr;
    445   } else if (debug_str_data_ptr) {
    446     uint32_t offset = Value.uval;
    447     return debug_str_data_ptr->getCStr(&offset);
    448   }
    449   return NULL;
    450 }
    451 
    452 const char*
    453 DWARFFormValue::getIndirectCString(const DataExtractor *DS,
    454                                    const DataExtractor *DSO) const {
    455   if (!DS || !DSO) return NULL;
    456 
    457   uint32_t offset = Value.uval * 4;
    458   uint32_t soffset = DSO->getU32(&offset);
    459   return DS->getCStr(&soffset);
    460 }
    461 
    462 uint64_t
    463 DWARFFormValue::getIndirectAddress(const DataExtractor *DA,
    464                                    const DWARFCompileUnit *cu) const {
    465   if (!DA) return 0;
    466 
    467   uint32_t offset = Value.uval * cu->getAddressByteSize();
    468   return DA->getAddress(&offset);
    469 }
    470 
    471 uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const {
    472   uint64_t die_offset = Value.uval;
    473   switch (Form) {
    474   case DW_FORM_ref1:
    475   case DW_FORM_ref2:
    476   case DW_FORM_ref4:
    477   case DW_FORM_ref8:
    478   case DW_FORM_ref_udata:
    479       die_offset += (cu ? cu->getOffset() : 0);
    480       break;
    481   default:
    482       break;
    483   }
    484 
    485   return die_offset;
    486 }
    487 
    488 bool
    489 DWARFFormValue::resolveCompileUnitReferences(const DWARFCompileUnit *cu) {
    490   switch (Form) {
    491   case DW_FORM_ref1:
    492   case DW_FORM_ref2:
    493   case DW_FORM_ref4:
    494   case DW_FORM_ref8:
    495   case DW_FORM_ref_udata:
    496     Value.uval += cu->getOffset();
    497     Form = DW_FORM_ref_addr;
    498     return true;
    499   default:
    500     break;
    501   }
    502   return false;
    503 }
    504 
    505 const uint8_t *DWARFFormValue::BlockData() const {
    506   if (!isInlinedCStr())
    507     return Value.data;
    508   return NULL;
    509 }
    510 
    511 bool DWARFFormValue::isBlockForm(uint16_t form) {
    512   switch (form) {
    513   case DW_FORM_exprloc:
    514   case DW_FORM_block:
    515   case DW_FORM_block1:
    516   case DW_FORM_block2:
    517   case DW_FORM_block4:
    518     return true;
    519   }
    520   return false;
    521 }
    522 
    523 bool DWARFFormValue::isDataForm(uint16_t form) {
    524   switch (form) {
    525   case DW_FORM_sdata:
    526   case DW_FORM_udata:
    527   case DW_FORM_data1:
    528   case DW_FORM_data2:
    529   case DW_FORM_data4:
    530   case DW_FORM_data8:
    531     return true;
    532   }
    533   return false;
    534 }
    535