summaryrefslogtreecommitdiff
path: root/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp')
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp153
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)