diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp')
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp | 153 |
1 files changed, 97 insertions, 56 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index ab8e68ab5516e..a8c550e9176f2 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -96,36 +96,92 @@ g_form_sizes_addr8[] = 8, // 0x20 DW_FORM_ref_sig8 }; +// Difference with g_form_sizes_addr8: +// DW_FORM_strp and DW_FORM_sec_offset are 8 instead of 4 +static uint8_t +g_form_sizes_addr8_dwarf64[] = +{ + 0, // 0x00 unused + 8, // 0x01 DW_FORM_addr + 0, // 0x02 unused + 0, // 0x03 DW_FORM_block2 + 0, // 0x04 DW_FORM_block4 + 2, // 0x05 DW_FORM_data2 + 4, // 0x06 DW_FORM_data4 + 8, // 0x07 DW_FORM_data8 + 0, // 0x08 DW_FORM_string + 0, // 0x09 DW_FORM_block + 0, // 0x0a DW_FORM_block1 + 1, // 0x0b DW_FORM_data1 + 1, // 0x0c DW_FORM_flag + 0, // 0x0d DW_FORM_sdata + 8, // 0x0e DW_FORM_strp + 0, // 0x0f DW_FORM_udata + 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 + 1, // 0x11 DW_FORM_ref1 + 2, // 0x12 DW_FORM_ref2 + 4, // 0x13 DW_FORM_ref4 + 8, // 0x14 DW_FORM_ref8 + 0, // 0x15 DW_FORM_ref_udata + 0, // 0x16 DW_FORM_indirect + 8, // 0x17 DW_FORM_sec_offset + 0, // 0x18 DW_FORM_exprloc + 0, // 0x19 DW_FORM_flag_present + 0, // 0x1a + 0, // 0x1b + 0, // 0x1c + 0, // 0x1d + 0, // 0x1e + 0, // 0x1f + 8, // 0x20 DW_FORM_ref_sig8 +}; + const uint8_t * -DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size) +DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64) { - switch (addr_size) - { - case 4: return g_form_sizes_addr4; - case 8: return g_form_sizes_addr8; + if (!is_dwarf64) { + switch (addr_size) + { + case 4: return g_form_sizes_addr4; + case 8: return g_form_sizes_addr8; + } + } else { + if (addr_size == 8) + return g_form_sizes_addr8_dwarf64; + // is_dwarf64 && addr_size == 4 : no provider does this. } return NULL; } -DWARFFormValue::DWARFFormValue(dw_form_t form) : +DWARFFormValue::DWARFFormValue() : + m_cu (NULL), + m_form(0), + m_value() +{ +} + +DWARFFormValue::DWARFFormValue(const DWARFCompileUnit* cu, dw_form_t form) : + m_cu (cu), m_form(form), m_value() { } bool -DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu) +DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* offset_ptr) { bool indirect = false; bool is_block = false; m_value.data = NULL; + uint8_t ref_addr_size; // Read the value for the form into value and follow and DW_FORM_indirect instances we run into do { indirect = false; switch (m_form) { - case DW_FORM_addr: m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); break; + case DW_FORM_addr: assert(m_cu); + m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(m_cu)); break; case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); is_block = true; break; case DW_FORM_block4: 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; @@ -142,15 +198,17 @@ DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* off 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); break; case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break; - case DW_FORM_strp: m_value.value.uval = data.GetU32(offset_ptr); break; + case DW_FORM_strp: assert(m_cu); + m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::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: - if (cu->GetVersion() <= 2) - m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::GetAddressByteSize(cu)); - else - m_value.value.uval = data.GetU32(offset_ptr); // 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet - 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_ref1: m_value.value.uval = data.GetU8(offset_ptr); break; case DW_FORM_ref2: m_value.value.uval = data.GetU16(offset_ptr); break; case DW_FORM_ref4: m_value.value.uval = data.GetU32(offset_ptr); break; @@ -161,7 +219,8 @@ DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* off indirect = true; break; - case DW_FORM_sec_offset: m_value.value.uval = data.GetU32(offset_ptr); break; + case DW_FORM_sec_offset: assert(m_cu); + m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFCompileUnit::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; default: @@ -183,14 +242,15 @@ DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* off } bool -DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const +DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const { - return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, cu); + return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); } bool DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) { + uint8_t ref_addr_size; switch (form) { // Blocks if inlined data that have a length field and the data bytes @@ -212,10 +272,13 @@ DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_d return true; case DW_FORM_ref_addr: + ref_addr_size = 4; + assert (cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong if (cu->GetVersion() <= 2) - *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); + ref_addr_size = cu->GetAddressByteSize(); else - *offset_ptr += 4;// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet + ref_addr_size = cu->IsDWARF64() ? 8 : 4; + *offset_ptr += ref_addr_size; return true; // 0 bytes values (implied from DW_FORM) @@ -237,11 +300,12 @@ DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_d // 32 bit for DWARF 32, 64 for DWARF 64 case DW_FORM_sec_offset: - *offset_ptr += 4; + case DW_FORM_strp: + assert(cu); + *offset_ptr += (cu->IsDWARF64() ? 8 : 4); return true; // 4 byte values - case DW_FORM_strp: case DW_FORM_data4: case DW_FORM_ref4: *offset_ptr += 4; @@ -278,7 +342,7 @@ DWARFFormValue::SkipValue(dw_form_t form, const DWARFDataExtractor& debug_info_d void -DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data, const DWARFCompileUnit* cu) const +DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data) const { uint64_t uvalue = Unsigned(); bool cu_relative_offset = false; @@ -348,7 +412,8 @@ DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data, const case DW_FORM_ref_addr: { - if (cu->GetVersion() <= 2) + assert (m_cu); // CU must be valid for DW_FORM_ref_addr objects or we will get this wrong + if (m_cu->GetVersion() <= 2) s.Address(uvalue, sizeof (uint64_t) * 2); else s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet @@ -370,10 +435,11 @@ DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data, const if (cu_relative_offset) { + assert (m_cu); // CU must be valid for DW_FORM_ref forms that are compile unit relative or we will get this wrong if (verbose) s.PutCString(" => "); - s.Printf("{0x%8.8" PRIx64 "}", (uvalue + (cu ? cu->GetOffset() : 0))); + s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset()); } } @@ -388,7 +454,7 @@ DWARFFormValue::AsCString(const DWARFDataExtractor* debug_str_data_ptr) const } uint64_t -DWARFFormValue::Reference(const DWARFCompileUnit* cu) const +DWARFFormValue::Reference() const { uint64_t die_offset = m_value.value.uval; switch (m_form) @@ -398,7 +464,8 @@ DWARFFormValue::Reference(const DWARFCompileUnit* cu) const case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: - die_offset += (cu ? cu->GetOffset() : 0); + 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; default: @@ -429,32 +496,6 @@ DWARFFormValue::Reference (dw_offset_t base_offset) const return die_offset; } -//---------------------------------------------------------------------- -// Resolve any compile unit specific references so that we don't need -// the compile unit at a later time in order to work with the form -// value. -//---------------------------------------------------------------------- -bool -DWARFFormValue::ResolveCompileUnitReferences(const DWARFCompileUnit* cu) -{ - switch (m_form) - { - case DW_FORM_ref1: - case DW_FORM_ref2: - case DW_FORM_ref4: - case DW_FORM_ref8: - case DW_FORM_ref_udata: - m_value.value.uval += cu->GetOffset(); - m_form = DW_FORM_ref_addr; - return true; - break; - - default: - break; - } - - return false; -} const uint8_t* DWARFFormValue::BlockData() const @@ -496,7 +537,7 @@ DWARFFormValue::IsDataForm(const dw_form_t form) } int -DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_value, const DWARFCompileUnit* a_cu, const DWARFCompileUnit* b_cu, const DWARFDataExtractor* debug_str_data_ptr) +DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_value, const DWARFDataExtractor* debug_str_data_ptr) { dw_form_t a_form = a_value.Form(); dw_form_t b_form = b_value.Form(); @@ -577,8 +618,8 @@ DWARFFormValue::Compare (const DWARFFormValue& a_value, const DWARFFormValue& b_ case DW_FORM_ref8: case DW_FORM_ref_udata: { - uint64_t a = a_value.Reference(a_cu); - uint64_t b = b_value.Reference(b_cu); + uint64_t a = a_value.Reference(); + uint64_t b = b_value.Reference(); if (a < b) return -1; if (a > b) |