diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp')
| -rw-r--r-- | source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp | 248 | 
1 files changed, 148 insertions, 100 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index 4fde5748d3f32..5d2a8ffdb85b3 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -154,6 +154,9 @@ DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size,  DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {} +DWARFFormValue::DWARFFormValue(const DWARFUnit *cu) +    : m_cu(cu), m_form(0), m_value() {} +  DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form)      : m_cu(cu), m_form(form), m_value() {} @@ -165,6 +168,9 @@ void DWARFFormValue::Clear() {  bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,                                    lldb::offset_t *offset_ptr) { +  if (m_form == DW_FORM_implicit_const) +    return true; +    bool indirect = false;    bool is_block = false;    m_value.data = NULL; @@ -176,8 +182,12 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,      switch (m_form) {      case DW_FORM_addr:        assert(m_cu); -      m_value.value.uval = data.GetMaxU64( -          offset_ptr, DWARFUnit::GetAddressByteSize(m_cu)); +      m_value.value.uval = +          data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_cu)); +      break; +    case DW_FORM_block1: +      m_value.value.uval = data.GetU8(offset_ptr); +      is_block = true;        break;      case DW_FORM_block2:        m_value.value.uval = data.GetU16(offset_ptr); @@ -187,94 +197,82 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,        m_value.value.uval = data.GetU32(offset_ptr);        is_block = true;        break; -    case DW_FORM_data2: -      m_value.value.uval = data.GetU16(offset_ptr); -      break; -    case DW_FORM_data4: -      m_value.value.uval = data.GetU32(offset_ptr); -      break; -    case DW_FORM_data8: -      m_value.value.uval = data.GetU64(offset_ptr); -      break; -    case DW_FORM_string: -      m_value.value.cstr = data.GetCStr(offset_ptr); +    case DW_FORM_data16: +      m_value.value.uval = 16; +      is_block = true;        break;      case DW_FORM_exprloc:      case DW_FORM_block:        m_value.value.uval = data.GetULEB128(offset_ptr);        is_block = true;        break; -    case DW_FORM_block1: -      m_value.value.uval = data.GetU8(offset_ptr); -      is_block = true; -      break; -    case DW_FORM_data1: -      m_value.value.uval = data.GetU8(offset_ptr); -      break; -    case DW_FORM_flag: -      m_value.value.uval = data.GetU8(offset_ptr); +    case DW_FORM_string: +      m_value.value.cstr = data.GetCStr(offset_ptr);        break;      case DW_FORM_sdata:        m_value.value.sval = data.GetSLEB128(offset_ptr);        break;      case DW_FORM_strp: +    case DW_FORM_line_strp: +    case DW_FORM_sec_offset:        assert(m_cu);        m_value.value.uval =            data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);        break; -    //  case DW_FORM_APPLE_db_str: -    case DW_FORM_udata: -      m_value.value.uval = data.GetULEB128(offset_ptr); -      break; -    case DW_FORM_ref_addr: -      assert(m_cu); -      ref_addr_size = 4; -      if (m_cu->GetVersion() <= 2) -        ref_addr_size = m_cu->GetAddressByteSize(); -      else -        ref_addr_size = m_cu->IsDWARF64() ? 8 : 4; -      m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); -      break; +    case DW_FORM_addrx1: +    case DW_FORM_strx1:      case DW_FORM_ref1: +    case DW_FORM_data1: +    case DW_FORM_flag:        m_value.value.uval = data.GetU8(offset_ptr);        break; +    case DW_FORM_addrx2: +    case DW_FORM_strx2:      case DW_FORM_ref2: +    case DW_FORM_data2:        m_value.value.uval = data.GetU16(offset_ptr);        break; +    case DW_FORM_addrx3: +    case DW_FORM_strx3: +      m_value.value.uval = data.GetMaxU64(offset_ptr, 3); +      break; +    case DW_FORM_addrx4: +    case DW_FORM_strx4:      case DW_FORM_ref4: +    case DW_FORM_data4:        m_value.value.uval = data.GetU32(offset_ptr);        break; +    case DW_FORM_data8:      case DW_FORM_ref8: +    case DW_FORM_ref_sig8:        m_value.value.uval = data.GetU64(offset_ptr);        break; +    case DW_FORM_addrx: +    case DW_FORM_rnglistx: +    case DW_FORM_strx: +    case DW_FORM_udata:      case DW_FORM_ref_udata: +    case DW_FORM_GNU_str_index: +    case DW_FORM_GNU_addr_index:        m_value.value.uval = data.GetULEB128(offset_ptr);        break; +    case DW_FORM_ref_addr: +      assert(m_cu); +      if (m_cu->GetVersion() <= 2) +        ref_addr_size = m_cu->GetAddressByteSize(); +      else +        ref_addr_size = m_cu->IsDWARF64() ? 8 : 4; +      m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); +      break;      case DW_FORM_indirect:        m_form = data.GetULEB128(offset_ptr);        indirect = true;        break; - -    case DW_FORM_sec_offset: -      assert(m_cu); -      m_value.value.uval = -          data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); -      break;      case DW_FORM_flag_present:        m_value.value.uval = 1;        break; -    case DW_FORM_ref_sig8: -      m_value.value.uval = data.GetU64(offset_ptr); -      break; -    case DW_FORM_GNU_str_index: -      m_value.value.uval = data.GetULEB128(offset_ptr); -      break; -    case DW_FORM_GNU_addr_index: -      m_value.value.uval = data.GetULEB128(offset_ptr); -      break;      default:        return false; -      break;      }    } while (indirect); @@ -346,49 +344,65 @@ bool DWARFFormValue::SkipValue(dw_form_t form,    // 0 bytes values (implied from DW_FORM)    case DW_FORM_flag_present: +  case DW_FORM_implicit_const:      return true; -  // 1 byte values -  case DW_FORM_data1: -  case DW_FORM_flag: -  case DW_FORM_ref1: -    *offset_ptr += 1; -    return true; +    // 1 byte values +    case DW_FORM_addrx1: +    case DW_FORM_data1: +    case DW_FORM_flag: +    case DW_FORM_ref1: +    case DW_FORM_strx1: +      *offset_ptr += 1; +      return true; -  // 2 byte values -  case DW_FORM_data2: -  case DW_FORM_ref2: -    *offset_ptr += 2; -    return true; +    // 2 byte values +    case DW_FORM_addrx2: +    case DW_FORM_data2: +    case DW_FORM_ref2: +    case DW_FORM_strx2: +      *offset_ptr += 2; +      return true; -  // 32 bit for DWARF 32, 64 for DWARF 64 -  case DW_FORM_sec_offset: -  case DW_FORM_strp: -    assert(cu); -    *offset_ptr += (cu->IsDWARF64() ? 8 : 4); -    return true; +    // 3 byte values +    case DW_FORM_addrx3: +    case DW_FORM_strx3: +      *offset_ptr += 3; +      return true; -  // 4 byte values -  case DW_FORM_data4: -  case DW_FORM_ref4: -    *offset_ptr += 4; -    return true; +    // 32 bit for DWARF 32, 64 for DWARF 64 +    case DW_FORM_sec_offset: +    case DW_FORM_strp: +      assert(cu); +      *offset_ptr += (cu->IsDWARF64() ? 8 : 4); +      return true; -  // 8 byte values -  case DW_FORM_data8: -  case DW_FORM_ref8: -  case DW_FORM_ref_sig8: -    *offset_ptr += 8; -    return true; +    // 4 byte values +    case DW_FORM_addrx4: +    case DW_FORM_data4: +    case DW_FORM_ref4: +    case DW_FORM_strx4: +      *offset_ptr += 4; +      return true; -  // signed or unsigned LEB 128 values -  case DW_FORM_sdata: -  case DW_FORM_udata: -  case DW_FORM_ref_udata: -  case DW_FORM_GNU_addr_index: -  case DW_FORM_GNU_str_index: -    debug_info_data.Skip_LEB128(offset_ptr); -    return true; +    // 8 byte values +    case DW_FORM_data8: +    case DW_FORM_ref8: +    case DW_FORM_ref_sig8: +      *offset_ptr += 8; +      return true; + +    // signed or unsigned LEB 128 values +    case DW_FORM_addrx: +    case DW_FORM_rnglistx: +    case DW_FORM_sdata: +    case DW_FORM_udata: +    case DW_FORM_ref_udata: +    case DW_FORM_GNU_addr_index: +    case DW_FORM_GNU_str_index: +    case DW_FORM_strx: +      debug_info_data.Skip_LEB128(offset_ptr); +      return true;    case DW_FORM_indirect: {      dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); @@ -546,6 +560,26 @@ const char *DWARFFormValue::AsCString() const {                                                              index_size);      return symbol_file->get_debug_str_data().PeekCStr(str_offset);    } + +  if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 || +      m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 || +      m_form == DW_FORM_strx4) { + +    // The same code as above. +    if (!symbol_file) +      return nullptr; + +    uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4; +    lldb::offset_t offset = +        m_cu->GetStrOffsetsBase() + m_value.value.uval * indexSize; +    dw_offset_t strOffset = +        symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize); +    return symbol_file->get_debug_str_data().PeekCStr(strOffset); +  } + +  if (m_form == DW_FORM_line_strp) +    return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval); +    return nullptr;  } @@ -556,7 +590,9 @@ dw_addr_t DWARFFormValue::Address() const {      return Unsigned();    assert(m_cu); -  assert(m_form == DW_FORM_GNU_addr_index); +  assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || +         m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || +         m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4);    if (!symbol_file)      return 0; @@ -568,7 +604,7 @@ dw_addr_t DWARFFormValue::Address() const {  }  uint64_t DWARFFormValue::Reference() const { -  uint64_t die_offset = m_value.value.uval; +  uint64_t value = m_value.value.uval;    switch (m_form) {    case DW_FORM_ref1:    case DW_FORM_ref2: @@ -577,32 +613,36 @@ uint64_t DWARFFormValue::Reference() const {    case DW_FORM_ref_udata:      assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile                    // unit relative or we will get this wrong -    die_offset += m_cu->GetOffset(); -    break; +    return value + m_cu->GetOffset(); + +  case DW_FORM_ref_addr: +  case DW_FORM_ref_sig8: +  case DW_FORM_GNU_ref_alt: +    return value;    default: -    break; +    return DW_INVALID_OFFSET;    } - -  return die_offset;  }  uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { -  uint64_t die_offset = m_value.value.uval; +  uint64_t value = m_value.value.uval;    switch (m_form) {    case DW_FORM_ref1:    case DW_FORM_ref2:    case DW_FORM_ref4:    case DW_FORM_ref8:    case DW_FORM_ref_udata: -    die_offset += base_offset; -    break; +    return value + base_offset; + +  case DW_FORM_ref_addr: +  case DW_FORM_ref_sig8: +  case DW_FORM_GNU_ref_alt: +    return value;    default: -    break; +    return DW_INVALID_OFFSET;    } - -  return die_offset;  }  const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } @@ -729,6 +769,8 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value,  bool DWARFFormValue::FormIsSupported(dw_form_t form) {    switch (form) {      case DW_FORM_addr: +    case DW_FORM_addrx: +    case DW_FORM_rnglistx:      case DW_FORM_block2:      case DW_FORM_block4:      case DW_FORM_data2: @@ -741,6 +783,11 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) {      case DW_FORM_flag:      case DW_FORM_sdata:      case DW_FORM_strp: +    case DW_FORM_strx: +    case DW_FORM_strx1: +    case DW_FORM_strx2: +    case DW_FORM_strx3: +    case DW_FORM_strx4:      case DW_FORM_udata:      case DW_FORM_ref_addr:      case DW_FORM_ref1: @@ -755,6 +802,7 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) {      case DW_FORM_ref_sig8:      case DW_FORM_GNU_str_index:      case DW_FORM_GNU_addr_index: +    case DW_FORM_implicit_const:        return true;      default:        break;  | 
