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