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