dump_syms: Reintroduce warnings inadvertently removed by 47cd498384

Previously, dump_syms produced warnings whenever a DW_AT_specification
or DW_AT_abstract_origin attribute was a forward reference. 47cd498384
allowed those attributes to carry forward references, removing the
warnings altogether. It was not correct to remove the warnings entirely.
References that do not point to valid DIEs should still produce
warnings, whether a back reference or a forward reference.

This reintroduces those warnings as appropriate.

Bug: google-breakpad:813
Test: dumper_unittest SimpleCU.UnknownAbstractOrigin,Specifications.BadOffset
Change-Id: Ie7222c7a1886bab31423f27e2fbcce93e69625b3
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2090103
Reviewed-by: Mike Frysinger <vapier@chromium.org>
This commit is contained in:
Mark Mentovai 2020-03-06 10:40:39 -05:00
parent c7522272ff
commit 52b33b2a4b
2 changed files with 25 additions and 15 deletions

View file

@ -32,7 +32,7 @@
<project path='src/src/third_party/lss' <project path='src/src/third_party/lss'
name='linux-syscall-support/' name='linux-syscall-support/'
revision='8048ece6c16c91acfe0d36d1d3cc0890ab6e945c' revision='f70e2f1641e280e777edfdad7f73a2cfa38139c7'
remote='chromium' /> remote='chromium' />
<project path='src/src/third_party/protobuf/protobuf' <project path='src/src/third_party/protobuf/protobuf'

View file

@ -350,9 +350,10 @@ void DwarfCUToModule::GenericDIEHandler::ProcessAttributeReference(
SpecificationByOffset::iterator spec = specifications->find(data); SpecificationByOffset::iterator spec = specifications->find(data);
if (spec != specifications->end()) { if (spec != specifications->end()) {
specification_ = &spec->second; specification_ = &spec->second;
} else { } else if (data > offset_) {
// The DW_AT_specification is a forward reference.
forward_ref_die_offset_ = data; forward_ref_die_offset_ = data;
} else {
cu_context_->reporter->UnknownSpecification(offset_, data);
} }
break; break;
} }
@ -544,8 +545,10 @@ void DwarfCUToModule::FuncHandler::ProcessAttributeReference(
AbstractOriginByOffset::const_iterator origin = origins.find(data); AbstractOriginByOffset::const_iterator origin = origins.find(data);
if (origin != origins.end()) { if (origin != origins.end()) {
abstract_origin_ = &(origin->second); abstract_origin_ = &(origin->second);
} else { } else if (data > offset_) {
forward_ref_die_offset_ = data; forward_ref_die_offset_ = data;
} else {
cu_context_->reporter->UnknownAbstractOrigin(offset_, data);
} }
break; break;
} }
@ -581,9 +584,9 @@ void DwarfCUToModule::FuncHandler::Finish() {
// to be processed, and fix up the name of the appropriate Module::Function. // to be processed, and fix up the name of the appropriate Module::Function.
// "name_" will have already been fixed up in EndAttributes(). // "name_" will have already been fixed up in EndAttributes().
if (!name_.empty()) { if (!name_.empty()) {
auto Iter = cu_context_->forward_ref_die_to_func.find(offset_); auto iter = cu_context_->forward_ref_die_to_func.find(offset_);
if (Iter != cu_context_->forward_ref_die_to_func.end()) if (iter != cu_context_->forward_ref_die_to_func.end())
Iter->second->name = name_; iter->second->name = name_;
} }
if (!ranges_) { if (!ranges_) {
@ -638,10 +641,17 @@ void DwarfCUToModule::FuncHandler::Finish() {
// If the function address is zero this is a sign that this function // If the function address is zero this is a sign that this function
// description is just empty debug data and should just be discarded. // description is just empty debug data and should just be discarded.
cu_context_->functions.push_back(func.release()); cu_context_->functions.push_back(func.release());
if (forward_ref_die_offset_ != 0) if (forward_ref_die_offset_ != 0) {
cu_context_->forward_ref_die_to_func[forward_ref_die_offset_] = auto iter =
cu_context_->functions.back(); cu_context_->forward_ref_die_to_func.find(forward_ref_die_offset_);
} if (iter == cu_context_->forward_ref_die_to_func.end()) {
cu_context_->reporter->UnknownSpecification(offset_,
forward_ref_die_offset_);
} else {
iter->second = cu_context_->functions.back();
}
}
}
} else if (inline_) { } else if (inline_) {
AbstractOrigin origin(name_); AbstractOrigin origin(name_);
cu_context_->file_context->file_private_->origins[offset_] = origin; cu_context_->file_context->file_private_->origins[offset_] = origin;
@ -695,8 +705,8 @@ void DwarfCUToModule::WarningReporter::UnknownSpecification(uint64 offset,
uint64 target) { uint64 target) {
CUHeading(); CUHeading();
fprintf(stderr, "%s: the DIE at offset 0x%llx has a DW_AT_specification" fprintf(stderr, "%s: the DIE at offset 0x%llx has a DW_AT_specification"
" attribute referring to the die at offset 0x%llx, which either" " attribute referring to the DIE at offset 0x%llx, which was not"
" was not marked as a declaration, or comes later in the file\n", " marked as a declaration\n",
filename_.c_str(), offset, target); filename_.c_str(), offset, target);
} }
@ -704,8 +714,8 @@ void DwarfCUToModule::WarningReporter::UnknownAbstractOrigin(uint64 offset,
uint64 target) { uint64 target) {
CUHeading(); CUHeading();
fprintf(stderr, "%s: the DIE at offset 0x%llx has a DW_AT_abstract_origin" fprintf(stderr, "%s: the DIE at offset 0x%llx has a DW_AT_abstract_origin"
" attribute referring to the die at offset 0x%llx, which either" " attribute referring to the DIE at offset 0x%llx, which was not"
" was not marked as an inline, or comes later in the file\n", " marked as an inline\n",
filename_.c_str(), offset, target); filename_.c_str(), offset, target);
} }