Make forward reference DIEs cross compilation units.

Before this change, forward_ref_die_to_func is always empty.
Because forward reference DIEs could cross compilation units,
forward_ref_die_to_func is moved into FilePrivate.
By using "grep "name omitted" sym | wc -l", the number of functions
with no name is reduced from 26951 to 203 if forward reference only is
allowed within CU. It's reduced from 203 to 6 if crossing compilation
units is allowed.

Change-Id: Ie2a457abfc0c4d8e68fe0fa595a27ea4abf33a76
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2904093
Reviewed-by: Mike Frysinger <vapier@chromium.org>
This commit is contained in:
Zequan Wu 2021-05-18 12:18:23 -07:00 committed by Mike Frysinger
parent 6842fa5aa8
commit 275e6d46a4

View file

@ -126,6 +126,10 @@ struct DwarfCUToModule::FilePrivate {
SpecificationByOffset specifications; SpecificationByOffset specifications;
AbstractOriginByOffset origins; AbstractOriginByOffset origins;
// Keep a list of forward references from DW_AT_abstract_origin and
// DW_AT_specification attributes so names can be fixed up.
std::map<uint64_t, Module::Function*> forward_ref_die_to_func;
}; };
DwarfCUToModule::FileContext::FileContext(const string& filename, DwarfCUToModule::FileContext::FileContext(const string& filename,
@ -265,10 +269,6 @@ struct DwarfCUToModule::CUContext {
// //
// Destroying this destroys all the functions this vector points to. // Destroying this destroys all the functions this vector points to.
vector<Module::Function*> functions; vector<Module::Function*> functions;
// Keep a list of forward references from DW_AT_abstract_origin and
// DW_AT_specification attributes so names can be fixed up.
std::map<uint64_t, Module::Function*> forward_ref_die_to_func;
}; };
// Information about the context of a particular DIE. This is for // Information about the context of a particular DIE. This is for
@ -642,8 +642,11 @@ 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 =
if (iter != cu_context_->forward_ref_die_to_func.end()) cu_context_->file_context->file_private_->forward_ref_die_to_func.find(
offset_);
if (iter !=
cu_context_->file_context->file_private_->forward_ref_die_to_func.end())
iter->second->name = name_; iter->second->name = name_;
} }
@ -708,14 +711,9 @@ void DwarfCUToModule::FuncHandler::Finish() {
// 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) {
auto iter = cu_context_->file_context->file_private_
cu_context_->forward_ref_die_to_func.find(forward_ref_die_offset_); ->forward_ref_die_to_func[forward_ref_die_offset_] =
if (iter == cu_context_->forward_ref_die_to_func.end()) { cu_context_->functions.back();
cu_context_->reporter->UnknownSpecification(offset_,
forward_ref_die_offset_);
} else {
iter->second = cu_context_->functions.back();
}
} }
} }
} else if (inline_) { } else if (inline_) {