Home | History | Annotate | Download | only in DWARF
      1 //===-- DWARFFormValue.cpp --------------------------------------*- C++ -*-===//
      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 <assert.h>
     11 
     12 #include "lldb/Core/dwarf.h"
     13 #include "lldb/Core/Stream.h"
     14 
     15 #include "DWARFFormValue.h"
     16 #include "DWARFCompileUnit.h"
     17 
     18 class DWARFCompileUnit;
     19 
     20 using namespace lldb_private;
     21 
     22 
     23 static uint8_t g_form_sizes_addr4[] =
     24 {
     25     0, // 0x00 unused
     26     4, // 0x01 DW_FORM_addr
     27     0, // 0x02 unused
     28     0, // 0x03 DW_FORM_block2
     29     0, // 0x04 DW_FORM_block4
     30     2, // 0x05 DW_FORM_data2
     31     4, // 0x06 DW_FORM_data4
     32     8, // 0x07 DW_FORM_data8
     33     0, // 0x08 DW_FORM_string
     34     0, // 0x09 DW_FORM_block
     35     0, // 0x0a DW_FORM_block1
     36     1, // 0x0b DW_FORM_data1
     37     1, // 0x0c DW_FORM_flag
     38     0, // 0x0d DW_FORM_sdata
     39     4, // 0x0e DW_FORM_strp
     40     0, // 0x0f DW_FORM_udata
     41     0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
     42     1, // 0x11 DW_FORM_ref1
     43     2, // 0x12 DW_FORM_ref2
     44     4, // 0x13 DW_FORM_ref4
     45     8, // 0x14 DW_FORM_ref8
     46     0, // 0x15 DW_FORM_ref_udata
     47     0, // 0x16 DW_FORM_indirect
     48     4, // 0x17 DW_FORM_sec_offset
     49     0, // 0x18 DW_FORM_exprloc
     50     0, // 0x19 DW_FORM_flag_present
     51     0, // 0x1a
     52     0, // 0x1b
     53     0, // 0x1c
     54     0, // 0x1d
     55     0, // 0x1e
     56     0, // 0x1f
     57     8, // 0x20 DW_FORM_ref_sig8
     58 
     59 };
     60 
     61 static uint8_t
     62 g_form_sizes_addr8[] =
     63 {
     64     0, // 0x00 unused
     65     8, // 0x01 DW_FORM_addr
     66     0, // 0x02 unused
     67     0, // 0x03 DW_FORM_block2
     68     0, // 0x04 DW_FORM_block4
     69     2, // 0x05 DW_FORM_data2
     70     4, // 0x06 DW_FORM_data4
     71     8, // 0x07 DW_FORM_data8
     72     0, // 0x08 DW_FORM_string
     73     0, // 0x09 DW_FORM_block
     74     0, // 0x0a DW_FORM_block1
     75     1, // 0x0b DW_FORM_data1
     76     1, // 0x0c DW_FORM_flag
     77     0, // 0x0d DW_FORM_sdata
     78     4, // 0x0e DW_FORM_strp
     79     0, // 0x0f DW_FORM_udata
     80     0, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
     81     1, // 0x11 DW_FORM_ref1
     82     2, // 0x12 DW_FORM_ref2
     83     4, // 0x13 DW_FORM_ref4
     84     8, // 0x14 DW_FORM_ref8
     85     0, // 0x15 DW_FORM_ref_udata
     86     0, // 0x16 DW_FORM_indirect
     87     4, // 0x17 DW_FORM_sec_offset
     88     0, // 0x18 DW_FORM_exprloc
     89     0, // 0x19 DW_FORM_flag_present
     90     0, // 0x1a
     91     0, // 0x1b
     92     0, // 0x1c
     93     0, // 0x1d
     94     0, // 0x1e
     95     0, // 0x1f
     96     8, // 0x20 DW_FORM_ref_sig8
     97 };
     98 
     99 const uint8_t *
    100 DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size)
    101 {
    102     switch (addr_size)
    103     {
    104     case 4: return g_form_sizes_addr4;
    105     case 8: return g_form_sizes_addr8;
    106     }
    107     return NULL;
    108 }
    109 
    110 DWARFFormValue::DWARFFormValue(dw_form_t form) :
    111     m_form(form),
    112     m_value()
    113 {
    114 }
    115 
    116 bool
    117 DWARFFormValue::ExtractValue(const DataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu)
    118 {
    119     bool indirect = false;
    120     bool is_block = false;
    121     m_value.data = NULL;
    122     // Read the value for the form into value and follow and DW_FORM_indirect instances we run into
    123     do
    124     {
    125         indirect = false;
    126         switch (m_form)
    127         {
    128         case DW_FORM_addr:      m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu));  break;
    129         case DW_FORM_block2:    m_value.value.uval = data.GetU16(offset_ptr); is_block = true;          break;
    130         case DW_FORM_block4:    m_value.value.uval = data.GetU32(offset_ptr); is_block = true;          break;
    131         case DW_FORM_data2:     m_value.value.uval = data.GetU16(offset_ptr);                           break;
    132         case DW_FORM_data4:     m_value.value.uval = data.GetU32(offset_ptr);                           break;
    133         case DW_FORM_data8:     m_value.value.uval = data.GetU64(offset_ptr);                           break;
    134         case DW_FORM_string:    m_value.value.cstr = data.GetCStr(offset_ptr);
    135                                 // Set the string value to also be the data for inlined cstr form values only
    136                                 // so we can tell the differnence between DW_FORM_string and DW_FORM_strp form
    137                                 // values;
    138                                 m_value.data = (uint8_t*)m_value.value.cstr;                            break;
    139         case DW_FORM_exprloc:
    140         case DW_FORM_block:     m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true;      break;
    141         case DW_FORM_block1:    m_value.value.uval = data.GetU8(offset_ptr); is_block = true;           break;
    142         case DW_FORM_data1:     m_value.value.uval = data.GetU8(offset_ptr);                            break;
    143         case DW_FORM_flag:      m_value.value.uval = data.GetU8(offset_ptr);                            break;
    144         case DW_FORM_sdata:     m_value.value.sval = data.GetSLEB128(offset_ptr);                       break;
    145         case DW_FORM_strp:      m_value.value.uval = data.GetU32(offset_ptr);                           break;
    146     //  case DW_FORM_APPLE_db_str:
    147         case DW_FORM_udata:     m_value.value.uval = data.GetULEB128(offset_ptr);                       break;
    148         case DW_FORM_ref_addr:
    149             if (cu->GetVersion() <= 2)
    150                 m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu));
    151             else
    152                 m_value.value.uval = data.GetU32(offset_ptr); // 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
    153             break;
    154         case DW_FORM_ref1:      m_value.value.uval = data.GetU8(offset_ptr);                            break;
    155         case DW_FORM_ref2:      m_value.value.uval = data.GetU16(offset_ptr);                           break;
    156         case DW_FORM_ref4:      m_value.value.uval = data.GetU32(offset_ptr);                           break;
    157         case DW_FORM_ref8:      m_value.value.uval = data.GetU64(offset_ptr);                           break;
    158         case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr);                       break;
    159         case DW_FORM_indirect:
    160             m_form = data.GetULEB128(offset_ptr);
    161             indirect = true;
    162             break;
    163 
    164         case DW_FORM_sec_offset:    m_value.value.uval = data.GetU32(offset_ptr);                       break;
    165         case DW_FORM_flag_present:  m_value.value.uval = 1;                                             break;
    166         case DW_FORM_ref_sig8:      m_value.value.uval = data.GetU64(offset_ptr);                       break;
    167         default:
    168             return false;
    169             break;
    170         }
    171     } while (indirect);
    172 
    173     if (is_block)
    174     {
    175         m_value.data = data.PeekData(*offset_ptr, m_value.value.uval);
    176         if (m_value.data != NULL)
    177         {
    178             *offset_ptr += m_value.value.uval;
    179         }
    180     }
    181 
    182     return true;
    183 }
    184 
    185 bool
    186 DWARFFormValue::SkipValue(const DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const
    187 {
    188     return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, cu);
    189 }
    190 
    191 bool
    192 DWARFFormValue::SkipValue(dw_form_t form, const DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu)
    193 {
    194     switch (form)
    195     {
    196     // Blocks if inlined data that have a length field and the data bytes
    197     // inlined in the .debug_info
    198     case DW_FORM_exprloc:
    199     case DW_FORM_block:  { dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true;
    200     case DW_FORM_block1: { dw_uleb128_t size = debug_info_data.GetU8(offset_ptr);      *offset_ptr += size; } return true;
    201     case DW_FORM_block2: { dw_uleb128_t size = debug_info_data.GetU16(offset_ptr);     *offset_ptr += size; } return true;
    202     case DW_FORM_block4: { dw_uleb128_t size = debug_info_data.GetU32(offset_ptr);     *offset_ptr += size; } return true;
    203 
    204     // Inlined NULL terminated C-strings
    205     case DW_FORM_string:
    206         debug_info_data.GetCStr(offset_ptr);
    207         return true;
    208 
    209     // Compile unit address sized values
    210     case DW_FORM_addr:
    211         *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
    212         return true;
    213 
    214     case DW_FORM_ref_addr:
    215         if (cu->GetVersion() <= 2)
    216             *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu);
    217         else
    218             *offset_ptr += 4;// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
    219         return true;
    220 
    221     // 0 bytes values (implied from DW_FORM)
    222     case DW_FORM_flag_present:
    223         return true;
    224 
    225     // 1 byte values
    226     case DW_FORM_data1:
    227     case DW_FORM_flag:
    228     case DW_FORM_ref1:
    229         *offset_ptr += 1;
    230         return true;
    231 
    232     // 2 byte values
    233     case DW_FORM_data2:
    234     case DW_FORM_ref2:
    235         *offset_ptr += 2;
    236         return true;
    237 
    238     // 32 bit for DWARF 32, 64 for DWARF 64
    239     case DW_FORM_sec_offset:
    240         *offset_ptr += 4;
    241         return true;
    242 
    243     // 4 byte values
    244     case DW_FORM_strp:
    245     case DW_FORM_data4:
    246     case DW_FORM_ref4:
    247         *offset_ptr += 4;
    248         return true;
    249 
    250     // 8 byte values
    251     case DW_FORM_data8:
    252     case DW_FORM_ref8:
    253     case DW_FORM_ref_sig8:
    254         *offset_ptr += 8;
    255         return true;
    256 
    257     // signed or unsigned LEB 128 values
    258     case DW_FORM_sdata:
    259     case DW_FORM_udata:
    260     case DW_FORM_ref_udata:
    261         debug_info_data.Skip_LEB128(offset_ptr);
    262         return true;
    263 
    264     case DW_FORM_indirect:
    265         {
    266             dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
    267             return DWARFFormValue::SkipValue (indirect_form,
    268                                               debug_info_data,
    269                                               offset_ptr,
    270                                               cu);
    271         }
    272 
    273     default:
    274         break;
    275     }
    276     return false;
    277 }
    278 
    279 
    280 void
    281 DWARFFormValue::Dump(Stream &s, const DataExtractor* debug_str_data, const DWARFCompileUnit* cu) const
    282 {
    283     uint64_t uvalue = Unsigned();
    284     bool cu_relative_offset = false;
    285 
    286     bool verbose = s.GetVerbose();
    287 
    288     switch (m_form)
    289     {
    290     case DW_FORM_addr:      s.Address(uvalue, sizeof (uint64_t)); break;
    291     case DW_FORM_flag:
    292     case DW_FORM_data1:     s.PutHex8(uvalue);     break;
    293     case DW_FORM_data2:     s.PutHex16(uvalue);        break;
    294     case DW_FORM_sec_offset:
    295     case DW_FORM_data4:     s.PutHex32(uvalue);        break;
    296     case DW_FORM_ref_sig8:
    297     case DW_FORM_data8:     s.PutHex64(uvalue);        break;
    298     case DW_FORM_string:    s.QuotedCString(AsCString(NULL));          break;
    299     case DW_FORM_exprloc:
    300     case DW_FORM_block:
    301     case DW_FORM_block1:
    302     case DW_FORM_block2:
    303     case DW_FORM_block4:
    304         if (uvalue > 0)
    305         {
    306             switch (m_form)
    307             {
    308             case DW_FORM_exprloc:
    309             case DW_FORM_block:  s.Printf("<0x%" PRIx64 "> ", uvalue);                break;
    310             case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue);      break;
    311             case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue);     break;
    312             case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue);     break;
    313             default:                                                            break;
    314             }
    315 
    316             const uint8_t* data_ptr = m_value.data;
    317             if (data_ptr)
    318             {
    319                 const uint8_t* end_data_ptr = data_ptr + uvalue;    // uvalue contains size of block
    320                 while (data_ptr < end_data_ptr)
    321                 {
    322                     s.Printf("%2.2x ", *data_ptr);
    323                     ++data_ptr;
    324                 }
    325             }
    326             else
    327                 s.PutCString("NULL");
    328         }
    329         break;
    330 
    331     case DW_FORM_sdata:     s.PutSLEB128(uvalue); break;
    332     case DW_FORM_udata:     s.PutULEB128(uvalue); break;
    333     case DW_FORM_strp:
    334         if (debug_str_data)
    335         {
    336             if (verbose)
    337                 s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);
    338 
    339             const char* dbg_str = AsCString(debug_str_data);
    340             if (dbg_str)
    341                 s.QuotedCString(dbg_str);
    342         }
    343         else
    344         {
    345             s.PutHex32(uvalue);
    346         }
    347         break;
    348 
    349     case DW_FORM_ref_addr:
    350     {
    351         if (cu->GetVersion() <= 2)
    352             s.Address(uvalue, sizeof (uint64_t) * 2);
    353         else
    354             s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
    355         break;
    356     }
    357     case DW_FORM_ref1:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break;
    358     case DW_FORM_ref2:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break;
    359     case DW_FORM_ref4:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break;
    360     case DW_FORM_ref8:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break;
    361     case DW_FORM_ref_udata: cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break;
    362 
    363     // All DW_FORM_indirect attributes should be resolved prior to calling this function
    364     case DW_FORM_indirect:  s.PutCString("DW_FORM_indirect"); break;
    365     case DW_FORM_flag_present: break;
    366     default:
    367         s.Printf("DW_FORM(0x%4.4x)", m_form);
    368         break;
    369     }
    370 
    371     if (cu_relative_offset)
    372     {
    373         if (verbose)
    374             s.PutCString(" => ");
    375 
    376         s.Printf("{0x%8.8" PRIx64 "}", (uvalue + (cu ? cu->GetOffset() : 0)));
    377     }
    378 }
    379 
    380 const char*
    381 DWARFFormValue::AsCString(const DataExtractor* debug_str_data_ptr) const
    382 {
    383     if (IsInlinedCStr())
    384         return m_value.value.cstr;
    385     else if (debug_str_data_ptr)
    386         return debug_str_data_ptr->PeekCStr(m_value.value.uval);
    387     return NULL;
    388 }
    389 
    390 uint64_t
    391 DWARFFormValue::Reference(const DWARFCompileUnit* cu) const
    392 {
    393     uint64_t die_offset = m_value.value.uval;
    394     switch (m_form)
    395     {
    396     case DW_FORM_ref1:
    397     case DW_FORM_ref2:
    398     case DW_FORM_ref4:
    399     case DW_FORM_ref8:
    400     case DW_FORM_ref_udata:
    401         die_offset += (cu ? cu->GetOffset() : 0);
    402         break;
    403 
    404     default:
    405         break;
    406     }
    407 
    408     return die_offset;
    409 }
    410 
    411 uint64_t
    412 DWARFFormValue::Reference (dw_offset_t base_offset) const
    413 {
    414     uint64_t die_offset = m_value.value.uval;
    415     switch (m_form)
    416     {
    417         case DW_FORM_ref1:
    418         case DW_FORM_ref2:
    419         case DW_FORM_ref4:
    420         case DW_FORM_ref8:
    421         case DW_FORM_ref_udata:
    422             die_offset += base_offset;
    423             break;
    424 
    425         default:
    426             break;
    427     }
    428 
    429     return die_offset;
    430 }
    431 
    432 //----------------------------------------------------------------------
    433 // Resolve any compile unit specific references so that we don't need
    434 // the compile unit at a later time in order to work with the form
    435 // value.
    436 //----------------------------------------------------------------------
    437 bool
    438 DWARFFormValue::ResolveCompileUnitReferences(const DWARFCompileUnit* cu)
    439 {
    440     switch (m_form)
    441     {
    442     case DW_FORM_ref1:
    443     case DW_FORM_ref2:
    444     case DW_FORM_ref4:
    445     case DW_FORM_ref8:
    446     case DW_FORM_ref_udata:
    447         m_value.value.uval += cu->GetOffset();
    448         m_form = DW_FORM_ref_addr;
    449         return true;
    450         break;
    451 
    452     default:
    453         break;
    454     }
    455 
    456     return false;
    457 }
    458 
    459 const uint8_t*
    460 DWARFFormValue::BlockData() const
    461 {
    462     if (!IsInlinedCStr())
    463         return m_value.data;
    464     return NULL;
    465 }
    466 
    467 
    468 bool
    469 DWARFFormValue::IsBlockForm(const dw_form_t form)
    470 {
    471     switch (form)
    472     {
    473     case DW_FORM_block:
    474     case DW_FORM_block1:
    475     case DW_FORM_block2:
    476     case DW_FORM_block4:
    477         return true;
    478     }
    479     return false;
    480 }
    481 
    482 bool
    483 DWARFFormValue::IsDataForm(const dw_form_t form)
    484 {
    485     switch (form)
    486     {
    487     case DW_FORM_sdata:
    488     case DW_FORM_udata:
    489     case DW_FORM_data1:
    490     case DW_FORM_data2:
    491     case DW_FORM_data4:
    492     case DW_FORM_data8:
    493         return true;
    494     }
    495     return false;
    496 }
    497 
    498 int
    499 DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_value, const DWARFCompileUnit* a_cu, const DWARFCompileUnit* b_cu, const DataExtractor* debug_str_data_ptr)
    500 {
    501     dw_form_t a_form = a_value.Form();
    502     dw_form_t b_form = b_value.Form();
    503     if (a_form < b_form)
    504         return -1;
    505     if (a_form > b_form)
    506         return 1;
    507     switch (a_form)
    508     {
    509     case DW_FORM_addr:
    510     case DW_FORM_flag:
    511     case DW_FORM_data1:
    512     case DW_FORM_data2:
    513     case DW_FORM_data4:
    514     case DW_FORM_data8:
    515     case DW_FORM_udata:
    516     case DW_FORM_ref_addr:
    517     case DW_FORM_sec_offset:
    518     case DW_FORM_flag_present:
    519     case DW_FORM_ref_sig8:
    520         {
    521             uint64_t a = a_value.Unsigned();
    522             uint64_t b = b_value.Unsigned();
    523             if (a < b)
    524                 return -1;
    525             if (a > b)
    526                 return 1;
    527             return 0;
    528         }
    529 
    530     case DW_FORM_sdata:
    531         {
    532             int64_t a = a_value.Signed();
    533             int64_t b = b_value.Signed();
    534             if (a < b)
    535                 return -1;
    536             if (a > b)
    537                 return 1;
    538             return 0;
    539         }
    540 
    541     case DW_FORM_string:
    542     case DW_FORM_strp:
    543         {
    544             const char *a_string = a_value.AsCString(debug_str_data_ptr);
    545             const char *b_string = b_value.AsCString(debug_str_data_ptr);
    546             if (a_string == b_string)
    547                 return 0;
    548             else if (a_string && b_string)
    549                 return strcmp(a_string, b_string);
    550             else if (a_string == NULL)
    551                 return -1;  // A string is NULL, and B is valid
    552             else
    553                 return 1;   // A string valid, and B is NULL
    554         }
    555 
    556 
    557     case DW_FORM_block:
    558     case DW_FORM_block1:
    559     case DW_FORM_block2:
    560     case DW_FORM_block4:
    561     case DW_FORM_exprloc:
    562         {
    563             uint64_t a_len = a_value.Unsigned();
    564             uint64_t b_len = b_value.Unsigned();
    565             if (a_len < b_len)
    566                 return -1;
    567             if (a_len > b_len)
    568                 return 1;
    569             // The block lengths are the same
    570             return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned());
    571         }
    572         break;
    573 
    574     case DW_FORM_ref1:
    575     case DW_FORM_ref2:
    576     case DW_FORM_ref4:
    577     case DW_FORM_ref8:
    578     case DW_FORM_ref_udata:
    579         {
    580             uint64_t a = a_value.Reference(a_cu);
    581             uint64_t b = b_value.Reference(b_cu);
    582             if (a < b)
    583                 return -1;
    584             if (a > b)
    585                 return 1;
    586             return 0;
    587         }
    588 
    589     case DW_FORM_indirect:
    590         assert(!"This shouldn't happen after the form has been extracted...");
    591         break;
    592 
    593     default:
    594         assert(!"Unhandled DW_FORM");
    595         break;
    596     }
    597     return -1;
    598 }
    599 
    600