Set addr_base_ before parsing attributes.

If there is an address index reference to .debug_addr section before
DW_AT_addr_base, addr_base_ will be 0. It will retrieve wrong address.
An example could be DW_AT_loc_pc occurs before DW_AT_addr_base.

Change-Id: Id2b337f5235470cc9beaf05a62efebbde797dacf
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2900806
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Zequan Wu 2021-05-17 12:50:42 -07:00 committed by Sterling Augustine
parent 13ba5a1549
commit 6842fa5aa8
2 changed files with 19 additions and 17 deletions

View file

@ -467,11 +467,12 @@ void CompilationUnit::ProcessFormStringIndex(
ProcessAttributeString(dieoffset, attr, form, str);
}
// Special function for pre-processing the DW_AT_str_offsets_base in a
// DW_TAG_compile_unit die (for DWARF v5). We must make sure to find and
// process the DW_AT_str_offsets_base attribute before attempting to read
// any string attribute in the compile unit.
const uint8_t* CompilationUnit::ProcessStrOffsetBaseAttribute(
// Special function for pre-processing the
// DW_AT_str_offsets_base and DW_AT_addr_base in a DW_TAG_compile_unit die (for
// DWARF v5). We must make sure to find and process the
// DW_AT_str_offsets_base and DW_AT_addr_base attributes before attempting to
// read any string and address attribute in the compile unit.
const uint8_t* CompilationUnit::ProcessOffsetBaseAttribute(
uint64_t dieoffset, const uint8_t* start, enum DwarfAttribute attr,
enum DwarfForm form, uint64_t implicit_const) {
size_t len;
@ -483,7 +484,7 @@ const uint8_t* CompilationUnit::ProcessStrOffsetBaseAttribute(
form = static_cast<enum DwarfForm>(reader_->ReadUnsignedLEB128(start,
&len));
start += len;
return ProcessStrOffsetBaseAttribute(dieoffset, start, attr, form,
return ProcessOffsetBaseAttribute(dieoffset, start, attr, form,
implicit_const);
case DW_FORM_flag_present:
@ -516,11 +517,12 @@ const uint8_t* CompilationUnit::ProcessStrOffsetBaseAttribute(
// This is the important one here!
case DW_FORM_sec_offset:
if (attr == dwarf2reader::DW_AT_str_offsets_base)
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadOffset(start));
if (attr == dwarf2reader::DW_AT_str_offsets_base ||
attr == dwarf2reader::DW_AT_addr_base)
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadOffset(start));
else
reader_->ReadOffset(start);
reader_->ReadOffset(start);
return start + reader_->OffsetSize();
case DW_FORM_ref1:
@ -858,16 +860,16 @@ const uint8_t* CompilationUnit::ProcessDIE(uint64_t dieoffset,
const uint8_t* start,
const Abbrev& abbrev) {
// With DWARF v5, the compile_unit die may contain a
// DW_AT_str_offsets_base. If it does, that attribute must be found
// and processed before trying to process the other attributes; otherwise
// the string values will all come out incorrect.
// DW_AT_str_offsets_base or DW_AT_addr_base. If it does, that attribute must
// be found and processed before trying to process the other attributes;
// otherwise the string or address values will all come out incorrect.
if (abbrev.tag == DW_TAG_compile_unit && header_.version == 5) {
uint64_t dieoffset_copy = dieoffset;
const uint8_t* start_copy = start;
for (AttributeList::const_iterator i = abbrev.attributes.begin();
i != abbrev.attributes.end();
i++) {
start_copy = ProcessStrOffsetBaseAttribute(dieoffset_copy, start_copy,
start_copy = ProcessOffsetBaseAttribute(dieoffset_copy, start_copy,
i->attr_, i->form_,
i->value_);
}

View file

@ -538,9 +538,9 @@ class CompilationUnit {
enum DwarfForm form,
uint64_t implicit_const);
// Special version of ProcessAttribute, for finding str_offsets_base in
// DW_TAG_compile_unit, for DWARF v5.
const uint8_t* ProcessStrOffsetBaseAttribute(uint64_t dieoffset,
// Special version of ProcessAttribute, for finding str_offsets_base and
// DW_AT_addr_base in DW_TAG_compile_unit, for DWARF v5.
const uint8_t* ProcessOffsetBaseAttribute(uint64_t dieoffset,
const uint8_t* start,
enum DwarfAttribute attr,
enum DwarfForm form,