summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2018-12-27 09:25:34 +0000
committerPavel Labath <pavel@labath.sk>2018-12-27 09:25:34 +0000
commit3eba3f1a133ba2581f40f4e097e2eb0cc615b190 (patch)
treef5eef1b1603c7b5412976bcf979c53ee45574172 /lldb/source/Plugins
parent7240eb3ba9e3ba456f692772b19b1b6a846a1bec (diff)
downloadbcm5719-llvm-3eba3f1a133ba2581f40f4e097e2eb0cc615b190.tar.gz
bcm5719-llvm-3eba3f1a133ba2581f40f4e097e2eb0cc615b190.zip
DWARF: Fix a bug in array size computation
Summary: r346165 introduced a bug, where we would fail to parse the size of an array if that size happened to match an existing die offset. The logic was: if (DWARFDIE count = die.GetReferencedDie(DW_AT_count)) num_elements = compute_vla_size(count); else num_elements = die.GetUsigned(DW_AT_count); // a fixed-size array The problem with this logic was that GetReferencedDie did not take the form class of the attribute into account, and would happily return a die reference for any form, if its value happened to match some die. As this behavior is inconsistent with how llvm's DWARFFormValue class operates, I chose to fix the problem by making our version of this class match the llvm behavior. For this to work, I had to add an explicit form class check to the .apple_XXX tables parsing code, because they do (incorrectly?) use data forms as die references. Reviewers: aprantl, clayborg Subscribers: JDevlieghere, lldb-commits Differential Revision: https://reviews.llvm.org/D55991 llvm-svn: 350086
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp28
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp4
2 files changed, 19 insertions, 13 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index fc3cf863b30..5d2a8ffdb85 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -604,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:
@@ -613,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; }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index 36211a08557..f83ba6663df 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -279,7 +279,9 @@ bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
switch (header_data.atoms[i].type) {
case eAtomTypeDIEOffset: // DIE offset, check form for encoding
hash_data.offset =
- (dw_offset_t)form_value.Reference(header_data.die_base_offset);
+ DWARFFormValue::IsDataForm(form_value.Form())
+ ? form_value.Unsigned()
+ : form_value.Reference(header_data.die_base_offset);
break;
case eAtomTypeTag: // DW_TAG value for the DIE
OpenPOWER on IntegriCloud