diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp | 1068 |
1 files changed, 562 insertions, 506 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index f8d137f713f..ad18c56b330 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -9,19 +9,17 @@ #include <assert.h> -#include "lldb/Core/dwarf.h" #include "lldb/Core/Stream.h" +#include "lldb/Core/dwarf.h" -#include "DWARFFormValue.h" #include "DWARFCompileUnit.h" +#include "DWARFFormValue.h" class DWARFCompileUnit; using namespace lldb_private; - -static uint8_t g_form_sizes_addr4[] = -{ +static uint8_t g_form_sizes_addr4[] = { 0, // 0x00 unused 4, // 0x01 DW_FORM_addr 0, // 0x02 unused @@ -38,7 +36,8 @@ static uint8_t g_form_sizes_addr4[] = 0, // 0x0d DW_FORM_sdata 4, // 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 + 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 @@ -58,9 +57,7 @@ static uint8_t g_form_sizes_addr4[] = }; -static uint8_t -g_form_sizes_addr8[] = -{ +static uint8_t g_form_sizes_addr8[] = { 0, // 0x00 unused 8, // 0x01 DW_FORM_addr 0, // 0x02 unused @@ -77,7 +74,8 @@ g_form_sizes_addr8[] = 0, // 0x0d DW_FORM_sdata 4, // 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 + 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 @@ -98,9 +96,7 @@ g_form_sizes_addr8[] = // 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[] = -{ +static uint8_t g_form_sizes_addr8_dwarf64[] = { 0, // 0x00 unused 8, // 0x01 DW_FORM_addr 0, // 0x02 unused @@ -117,7 +113,8 @@ g_form_sizes_addr8_dwarf64[] = 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 + 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 @@ -137,553 +134,612 @@ g_form_sizes_addr8_dwarf64[] = }; DWARFFormValue::FixedFormSizes -DWARFFormValue::GetFixedFormSizesForAddressSize (uint8_t addr_size, bool is_dwarf64) -{ - if (!is_dwarf64) { - switch (addr_size) - { - case 4: return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4)); - case 8: return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8)); - } - } else { - if (addr_size == 8) - return FixedFormSizes(g_form_sizes_addr8_dwarf64, sizeof(g_form_sizes_addr8_dwarf64)); - // is_dwarf64 && addr_size == 4 : no provider does this. +DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size, + bool is_dwarf64) { + if (!is_dwarf64) { + switch (addr_size) { + case 4: + return FixedFormSizes(g_form_sizes_addr4, sizeof(g_form_sizes_addr4)); + case 8: + return FixedFormSizes(g_form_sizes_addr8, sizeof(g_form_sizes_addr8)); } - return FixedFormSizes(); -} - -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() -{ -} - -void -DWARFFormValue::Clear() -{ - m_cu = nullptr; - m_form = 0; - memset(&m_value, 0, sizeof(m_value)); + } else { + if (addr_size == 8) + return FixedFormSizes(g_form_sizes_addr8_dwarf64, + sizeof(g_form_sizes_addr8_dwarf64)); + // is_dwarf64 && addr_size == 4 : no provider does this. + } + return FixedFormSizes(); } -bool -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: 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; - 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); 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); break; - case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(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: 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; - case DW_FORM_ref8: m_value.value.uval = data.GetU64(offset_ptr); break; - case DW_FORM_ref_udata: m_value.value.uval = data.GetULEB128(offset_ptr); 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, 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; - 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); - - if (is_block) - { - m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); - if (m_value.data != NULL) - { - *offset_ptr += m_value.value.uval; - } - } +DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {} - return true; -} +DWARFFormValue::DWARFFormValue(const DWARFCompileUnit *cu, dw_form_t form) + : m_cu(cu), m_form(form), m_value() {} -bool -DWARFFormValue::SkipValue(const DWARFDataExtractor& debug_info_data, lldb::offset_t *offset_ptr) const -{ - return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); +void DWARFFormValue::Clear() { + m_cu = nullptr; + m_form = 0; + memset(&m_value, 0, sizeof(m_value)); } -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 - // inlined in the .debug_info - case DW_FORM_exprloc: - case DW_FORM_block: { dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true; - case DW_FORM_block1: { dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); *offset_ptr += size; } return true; - case DW_FORM_block2: { dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); *offset_ptr += size; } return true; - case DW_FORM_block4: { dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); *offset_ptr += size; } return true; - - // Inlined NULL terminated C-strings - case DW_FORM_string: - debug_info_data.GetCStr(offset_ptr); - return true; - - // Compile unit address sized values +bool 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: - *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); - 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) - ref_addr_size = cu->GetAddressByteSize(); - else - ref_addr_size = cu->IsDWARF64() ? 8 : 4; - *offset_ptr += ref_addr_size; - return true; - - // 0 bytes values (implied from DW_FORM) - case DW_FORM_flag_present: - return true; - - // 1 byte values + 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; + 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); + 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); + break; + case DW_FORM_sdata: + m_value.value.sval = data.GetSLEB128(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: + 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: - *offset_ptr += 1; - return true; - - // 2 byte values - case DW_FORM_data2: + m_value.value.uval = data.GetU8(offset_ptr); + break; case DW_FORM_ref2: - *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; - - // 4 byte values - case DW_FORM_data4: + m_value.value.uval = data.GetU16(offset_ptr); + break; case DW_FORM_ref4: - *offset_ptr += 4; - return true; - - // 8 byte values - case DW_FORM_data8: + m_value.value.uval = data.GetU32(offset_ptr); + break; case DW_FORM_ref8: - case DW_FORM_ref_sig8: - *offset_ptr += 8; - return true; - - // signed or unsigned LEB 128 values - case DW_FORM_sdata: - case DW_FORM_udata: + m_value.value.uval = data.GetU64(offset_ptr); + break; 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; - + m_value.value.uval = data.GetULEB128(offset_ptr); + break; case DW_FORM_indirect: - { - dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); - return DWARFFormValue::SkipValue (indirect_form, - debug_info_data, - offset_ptr, - cu); - } + 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, 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; + 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: - break; + return false; + break; } - return false; -} + } while (indirect); + if (is_block) { + m_value.data = data.PeekData(*offset_ptr, m_value.value.uval); + if (m_value.data != NULL) { + *offset_ptr += m_value.value.uval; + } + } -void -DWARFFormValue::Dump(Stream &s) const -{ - uint64_t uvalue = Unsigned(); - bool cu_relative_offset = false; + return true; +} - bool verbose = s.GetVerbose(); +bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr) const { + return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); +} - switch (m_form) - { - case DW_FORM_addr: s.Address(uvalue, sizeof (uint64_t)); break; - case DW_FORM_flag: - case DW_FORM_data1: s.PutHex8(uvalue); break; - case DW_FORM_data2: s.PutHex16(uvalue); break; - case DW_FORM_sec_offset: - case DW_FORM_data4: s.PutHex32(uvalue); break; - case DW_FORM_ref_sig8: - case DW_FORM_data8: s.PutHex64(uvalue); break; - case DW_FORM_string: s.QuotedCString(AsCString()); break; - case DW_FORM_exprloc: - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - if (uvalue > 0) - { - switch (m_form) - { - case DW_FORM_exprloc: - case DW_FORM_block: s.Printf("<0x%" PRIx64 "> ", uvalue); break; - case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue); break; - case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue); break; - case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue); break; - default: break; - } - - const uint8_t* data_ptr = m_value.data; - if (data_ptr) - { - const uint8_t* end_data_ptr = data_ptr + uvalue; // uvalue contains size of block - while (data_ptr < end_data_ptr) - { - s.Printf("%2.2x ", *data_ptr); - ++data_ptr; - } - } - else - s.PutCString("NULL"); - } - break; +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 + // inlined in the .debug_info + case DW_FORM_exprloc: + case DW_FORM_block: { + dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); + *offset_ptr += size; + } + return true; + case DW_FORM_block1: { + dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); + *offset_ptr += size; + } + return true; + case DW_FORM_block2: { + dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); + *offset_ptr += size; + } + return true; + case DW_FORM_block4: { + dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); + *offset_ptr += size; + } + return true; - case DW_FORM_sdata: s.PutSLEB128(uvalue); break; - case DW_FORM_udata: s.PutULEB128(uvalue); break; - case DW_FORM_strp: - { - const char* dbg_str = AsCString(); - if (dbg_str) - { - if (verbose) - s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); - s.QuotedCString(dbg_str); - } - else - { - s.PutHex32(uvalue); - } - } - break; + // Inlined NULL terminated C-strings + case DW_FORM_string: + debug_info_data.GetCStr(offset_ptr); + return true; - case DW_FORM_ref_addr: - { - 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 - break; - } - case DW_FORM_ref1: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break; - case DW_FORM_ref2: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break; - case DW_FORM_ref4: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break; - case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break; - case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break; - - // All DW_FORM_indirect attributes should be resolved prior to calling this function - case DW_FORM_indirect: s.PutCString("DW_FORM_indirect"); break; - case DW_FORM_flag_present: break; - default: - s.Printf("DW_FORM(0x%4.4x)", m_form); - break; - } + // Compile unit address sized values + case DW_FORM_addr: + *offset_ptr += DWARFCompileUnit::GetAddressByteSize(cu); + return true; - 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(" => "); + 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) + ref_addr_size = cu->GetAddressByteSize(); + else + ref_addr_size = cu->IsDWARF64() ? 8 : 4; + *offset_ptr += ref_addr_size; + return true; - s.Printf("{0x%8.8" PRIx64 "}", uvalue + m_cu->GetOffset()); - } -} + // 0 bytes values (implied from DW_FORM) + case DW_FORM_flag_present: + return true; -const char* -DWARFFormValue::AsCString() const -{ - SymbolFileDWARF* symbol_file = m_cu->GetSymbolFileDWARF(); + // 1 byte values + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + *offset_ptr += 1; + return true; - if (m_form == DW_FORM_string) - { - return m_value.value.cstr; - } - else if (m_form == DW_FORM_strp) - { - if (!symbol_file) - return nullptr; + // 2 byte values + case DW_FORM_data2: + case DW_FORM_ref2: + *offset_ptr += 2; + return true; - return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval); - } - else if (m_form == DW_FORM_GNU_str_index) - { - if (!symbol_file) - return nullptr; - - uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4; - lldb::offset_t offset = m_value.value.uval * index_size; - dw_offset_t str_offset = symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, index_size); - return symbol_file->get_debug_str_data().PeekCStr(str_offset); - } - return nullptr; -} + // 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; -dw_addr_t -DWARFFormValue::Address() const -{ - SymbolFileDWARF* symbol_file = m_cu->GetSymbolFileDWARF(); + // 4 byte values + case DW_FORM_data4: + case DW_FORM_ref4: + *offset_ptr += 4; + return true; - if (m_form == DW_FORM_addr) - return Unsigned(); + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + *offset_ptr += 8; + return true; - assert(m_cu); - assert(m_form == DW_FORM_GNU_addr_index); + // 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; - if (!symbol_file) - return 0; + case DW_FORM_indirect: { + dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); + return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr, + cu); + } - uint32_t index_size = m_cu->GetAddressByteSize(); - dw_offset_t addr_base = m_cu->GetAddrBase(); - lldb::offset_t offset = addr_base + m_value.value.uval * index_size; - return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size); + default: + break; + } + return false; } -uint64_t -DWARFFormValue::Reference() const -{ - uint64_t die_offset = 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: - 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(); +void DWARFFormValue::Dump(Stream &s) const { + uint64_t uvalue = Unsigned(); + bool cu_relative_offset = false; + + bool verbose = s.GetVerbose(); + + switch (m_form) { + case DW_FORM_addr: + s.Address(uvalue, sizeof(uint64_t)); + break; + case DW_FORM_flag: + case DW_FORM_data1: + s.PutHex8(uvalue); + break; + case DW_FORM_data2: + s.PutHex16(uvalue); + break; + case DW_FORM_sec_offset: + case DW_FORM_data4: + s.PutHex32(uvalue); + break; + case DW_FORM_ref_sig8: + case DW_FORM_data8: + s.PutHex64(uvalue); + break; + case DW_FORM_string: + s.QuotedCString(AsCString()); + break; + case DW_FORM_exprloc: + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + if (uvalue > 0) { + switch (m_form) { + case DW_FORM_exprloc: + case DW_FORM_block: + s.Printf("<0x%" PRIx64 "> ", uvalue); break; - - default: + case DW_FORM_block1: + s.Printf("<0x%2.2x> ", (uint8_t)uvalue); + break; + case DW_FORM_block2: + s.Printf("<0x%4.4x> ", (uint16_t)uvalue); + break; + case DW_FORM_block4: + s.Printf("<0x%8.8x> ", (uint32_t)uvalue); break; + default: + break; + } + + const uint8_t *data_ptr = m_value.data; + if (data_ptr) { + const uint8_t *end_data_ptr = + data_ptr + uvalue; // uvalue contains size of block + while (data_ptr < end_data_ptr) { + s.Printf("%2.2x ", *data_ptr); + ++data_ptr; + } + } else + s.PutCString("NULL"); } - - return die_offset; -} - -uint64_t -DWARFFormValue::Reference (dw_offset_t base_offset) const -{ - uint64_t die_offset = 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; - - default: - break; + break; + + case DW_FORM_sdata: + s.PutSLEB128(uvalue); + break; + case DW_FORM_udata: + s.PutULEB128(uvalue); + break; + case DW_FORM_strp: { + const char *dbg_str = AsCString(); + if (dbg_str) { + if (verbose) + s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); + s.QuotedCString(dbg_str); + } else { + s.PutHex32(uvalue); } - - return die_offset; + } break; + + case DW_FORM_ref_addr: { + 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 + break; + } + case DW_FORM_ref1: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); + break; + case DW_FORM_ref2: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); + break; + case DW_FORM_ref4: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); + break; + case DW_FORM_ref8: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%8.8" PRIx64, uvalue); + break; + case DW_FORM_ref_udata: + cu_relative_offset = true; + if (verbose) + s.Printf("cu + 0x%" PRIx64, uvalue); + break; + + // All DW_FORM_indirect attributes should be resolved prior to calling this + // function + case DW_FORM_indirect: + s.PutCString("DW_FORM_indirect"); + break; + case DW_FORM_flag_present: + break; + default: + s.Printf("DW_FORM(0x%4.4x)", m_form); + break; + } + + 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 + m_cu->GetOffset()); + } } +const char *DWARFFormValue::AsCString() const { + SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); -const uint8_t* -DWARFFormValue::BlockData() const -{ - return m_value.data; + if (m_form == DW_FORM_string) { + return m_value.value.cstr; + } else if (m_form == DW_FORM_strp) { + if (!symbol_file) + return nullptr; + + return symbol_file->get_debug_str_data().PeekCStr(m_value.value.uval); + } else if (m_form == DW_FORM_GNU_str_index) { + if (!symbol_file) + return nullptr; + + uint32_t index_size = m_cu->IsDWARF64() ? 8 : 4; + lldb::offset_t offset = m_value.value.uval * index_size; + dw_offset_t str_offset = + symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, + index_size); + return symbol_file->get_debug_str_data().PeekCStr(str_offset); + } + return nullptr; } +dw_addr_t DWARFFormValue::Address() const { + SymbolFileDWARF *symbol_file = m_cu->GetSymbolFileDWARF(); -bool -DWARFFormValue::IsBlockForm(const dw_form_t form) -{ - switch (form) - { - case DW_FORM_exprloc: - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - return true; - } - return false; -} + if (m_form == DW_FORM_addr) + return Unsigned(); -bool -DWARFFormValue::IsDataForm(const dw_form_t form) -{ - switch (form) - { - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_data1: - case DW_FORM_data2: - case DW_FORM_data4: - case DW_FORM_data8: - return true; - } - return false; -} + assert(m_cu); + assert(m_form == DW_FORM_GNU_addr_index); -int -DWARFFormValue::Compare (const DWARFFormValue& a_value, - const DWARFFormValue& b_value) -{ - dw_form_t a_form = a_value.Form(); - dw_form_t b_form = b_value.Form(); - if (a_form < b_form) - return -1; - if (a_form > b_form) - return 1; - switch (a_form) - { - case DW_FORM_addr: - case DW_FORM_flag: - case DW_FORM_data1: - case DW_FORM_data2: - case DW_FORM_data4: - case DW_FORM_data8: - case DW_FORM_udata: - case DW_FORM_ref_addr: - case DW_FORM_sec_offset: - case DW_FORM_flag_present: - case DW_FORM_ref_sig8: - case DW_FORM_GNU_addr_index: - { - uint64_t a = a_value.Unsigned(); - uint64_t b = b_value.Unsigned(); - if (a < b) - return -1; - if (a > b) - return 1; - return 0; - } + if (!symbol_file) + return 0; - case DW_FORM_sdata: - { - int64_t a = a_value.Signed(); - int64_t b = b_value.Signed(); - if (a < b) - return -1; - if (a > b) - return 1; - return 0; - } + uint32_t index_size = m_cu->GetAddressByteSize(); + dw_offset_t addr_base = m_cu->GetAddrBase(); + lldb::offset_t offset = addr_base + m_value.value.uval * index_size; + return symbol_file->get_debug_addr_data().GetMaxU64(&offset, index_size); +} - case DW_FORM_string: - case DW_FORM_strp: - case DW_FORM_GNU_str_index: - { - const char *a_string = a_value.AsCString(); - const char *b_string = b_value.AsCString(); - if (a_string == b_string) - return 0; - else if (a_string && b_string) - return strcmp(a_string, b_string); - else if (a_string == NULL) - return -1; // A string is NULL, and B is valid - else - return 1; // A string valid, and B is NULL - } +uint64_t DWARFFormValue::Reference() const { + uint64_t die_offset = 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: + 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: + break; + } + + return die_offset; +} +uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { + uint64_t die_offset = 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; + + default: + break; + } + + return die_offset; +} - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - case DW_FORM_exprloc: - { - uint64_t a_len = a_value.Unsigned(); - uint64_t b_len = b_value.Unsigned(); - if (a_len < b_len) - return -1; - if (a_len > b_len) - return 1; - // The block lengths are the same - return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); - } - break; +const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } - case DW_FORM_ref1: - case DW_FORM_ref2: - case DW_FORM_ref4: - case DW_FORM_ref8: - case DW_FORM_ref_udata: - { - uint64_t a = a_value.Reference(); - uint64_t b = b_value.Reference(); - if (a < b) - return -1; - if (a > b) - return 1; - return 0; - } +bool DWARFFormValue::IsBlockForm(const dw_form_t form) { + switch (form) { + case DW_FORM_exprloc: + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + return true; + } + return false; +} - case DW_FORM_indirect: - assert(!"This shouldn't happen after the form has been extracted..."); - break; +bool DWARFFormValue::IsDataForm(const dw_form_t form) { + switch (form) { + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + return true; + } + return false; +} - default: - assert(!"Unhandled DW_FORM"); - break; - } +int DWARFFormValue::Compare(const DWARFFormValue &a_value, + const DWARFFormValue &b_value) { + dw_form_t a_form = a_value.Form(); + dw_form_t b_form = b_value.Form(); + if (a_form < b_form) return -1; + if (a_form > b_form) + return 1; + switch (a_form) { + case DW_FORM_addr: + case DW_FORM_flag: + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + case DW_FORM_ref_addr: + case DW_FORM_sec_offset: + case DW_FORM_flag_present: + case DW_FORM_ref_sig8: + case DW_FORM_GNU_addr_index: { + uint64_t a = a_value.Unsigned(); + uint64_t b = b_value.Unsigned(); + if (a < b) + return -1; + if (a > b) + return 1; + return 0; + } + + case DW_FORM_sdata: { + int64_t a = a_value.Signed(); + int64_t b = b_value.Signed(); + if (a < b) + return -1; + if (a > b) + return 1; + return 0; + } + + case DW_FORM_string: + case DW_FORM_strp: + case DW_FORM_GNU_str_index: { + const char *a_string = a_value.AsCString(); + const char *b_string = b_value.AsCString(); + if (a_string == b_string) + return 0; + else if (a_string && b_string) + return strcmp(a_string, b_string); + else if (a_string == NULL) + return -1; // A string is NULL, and B is valid + else + return 1; // A string valid, and B is NULL + } + + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + case DW_FORM_exprloc: { + uint64_t a_len = a_value.Unsigned(); + uint64_t b_len = b_value.Unsigned(); + if (a_len < b_len) + return -1; + if (a_len > b_len) + return 1; + // The block lengths are the same + return memcmp(a_value.BlockData(), b_value.BlockData(), a_value.Unsigned()); + } break; + + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: { + uint64_t a = a_value.Reference(); + uint64_t b = b_value.Reference(); + if (a < b) + return -1; + if (a > b) + return 1; + return 0; + } + + case DW_FORM_indirect: + assert(!"This shouldn't happen after the form has been extracted..."); + break; + + default: + assert(!"Unhandled DW_FORM"); + break; + } + return -1; } - |