diff options
| author | Pavel Labath <pavel@labath.sk> | 2018-12-27 09:25:34 +0000 |
|---|---|---|
| committer | Pavel Labath <pavel@labath.sk> | 2018-12-27 09:25:34 +0000 |
| commit | 3eba3f1a133ba2581f40f4e097e2eb0cc615b190 (patch) | |
| tree | f5eef1b1603c7b5412976bcf979c53ee45574172 /lldb/source/Plugins | |
| parent | 7240eb3ba9e3ba456f692772b19b1b6a846a1bec (diff) | |
| download | bcm5719-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.cpp | 28 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp | 4 |
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 |

