aboutsummaryrefslogtreecommitdiff
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.cpp248
1 files changed, 148 insertions, 100 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index 4fde5748d3f3..5d2a8ffdb85b 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;