[dump_syms] Fix DW_AT_specification warning on Mac.

1. Visit DW_TAG_class_type when it's inside DW_TAG_subprogram.
2. Only warn when we can't get the name for the DIE and it has DW_AT_specification that is not in the specification map.

Bug: 1078932
Change-Id: Id3126aec305658f8f65c01675a8e9e3ea03f3651
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3579855
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Zequan Wu 2022-04-12 09:59:21 -07:00 committed by Joshua Peraza
parent e09741c609
commit 8b68c72a3f

View File

@ -286,6 +286,7 @@ class DwarfCUToModule::GenericDIEHandler: public DIEHandler {
offset_(offset),
declaration_(false),
specification_(NULL),
no_specification(false),
abstract_origin_(NULL),
forward_ref_die_offset_(0), specification_offset_(0) { }
@ -331,6 +332,10 @@ class DwarfCUToModule::GenericDIEHandler: public DIEHandler {
// Otherwise, this is NULL.
Specification* specification_;
// If this DIE has DW_AT_specification with offset smaller than this DIE and
// we can't find that in the specification map.
bool no_specification;
// If this DIE has a DW_AT_abstract_origin attribute, this is the
// AbstractOrigin structure for the DIE the attribute refers to.
// Otherwise, this is NULL.
@ -393,7 +398,7 @@ void DwarfCUToModule::GenericDIEHandler::ProcessAttributeReference(
} else if (data > offset_) {
forward_ref_die_offset_ = data;
} else {
cu_context_->reporter->UnknownSpecification(offset_, data);
no_specification = true;
}
specification_offset_ = data;
break;
@ -479,7 +484,7 @@ StringView DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() {
// counts; otherwise, use this DIE's context.
if (specification_) {
enclosing_name = &specification_->enclosing_name;
} else {
} else if (parent_context_) {
enclosing_name = &parent_context_->name;
}
}
@ -601,7 +606,7 @@ DIEHandler* DwarfCUToModule::InlineHandler::FindChildHandler(
enum DwarfTag tag) {
switch (tag) {
case DW_TAG_inlined_subroutine:
return new InlineHandler(cu_context_, new DIEContext(), offset,
return new InlineHandler(cu_context_, nullptr, offset,
inline_nest_level_ + 1, child_inlines_);
default:
return NULL;
@ -672,6 +677,24 @@ void DwarfCUToModule::InlineHandler::Finish() {
inlines_.push_back(std::move(in));
}
// A handler for DIEs that contain functions and contribute a
// component to their names: namespaces, classes, etc.
class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler {
public:
NamedScopeHandler(CUContext* cu_context,
DIEContext* parent_context,
uint64_t offset,
bool handle_inline)
: GenericDIEHandler(cu_context, parent_context, offset),
handle_inline_(handle_inline) {}
bool EndAttributes();
DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag);
private:
DIEContext child_context_; // A context for our children.
bool handle_inline_;
};
// A handler class for DW_TAG_subprogram DIEs.
class DwarfCUToModule::FuncHandler: public GenericDIEHandler {
public:
@ -709,6 +732,7 @@ class DwarfCUToModule::FuncHandler: public GenericDIEHandler {
bool inline_;
vector<unique_ptr<Module::Inline>> child_inlines_;
bool handle_inline_;
DIEContext child_context_; // A context for our children.
};
void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned(
@ -757,8 +781,13 @@ DIEHandler* DwarfCUToModule::FuncHandler::FindChildHandler(
switch (tag) {
case DW_TAG_inlined_subroutine:
if (handle_inline_)
return new InlineHandler(cu_context_, new DIEContext(), offset, 0,
return new InlineHandler(cu_context_, nullptr, offset, 0,
child_inlines_);
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
return new NamedScopeHandler(cu_context_, &child_context_, offset,
handle_inline_);
default:
return NULL;
}
@ -770,6 +799,10 @@ bool DwarfCUToModule::FuncHandler::EndAttributes() {
if (name_.empty() && abstract_origin_) {
name_ = abstract_origin_->name;
}
child_context_.name = name_;
if (name_.empty() && no_specification) {
cu_context_->reporter->UnknownSpecification(offset_, specification_offset_);
}
return true;
}
@ -868,26 +901,11 @@ void DwarfCUToModule::FuncHandler::Finish() {
}
}
// A handler for DIEs that contain functions and contribute a
// component to their names: namespaces, classes, etc.
class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler {
public:
NamedScopeHandler(CUContext* cu_context,
DIEContext* parent_context,
uint64_t offset,
bool handle_inline)
: GenericDIEHandler(cu_context, parent_context, offset),
handle_inline_(handle_inline) {}
bool EndAttributes();
DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag);
private:
DIEContext child_context_; // A context for our children.
bool handle_inline_;
};
bool DwarfCUToModule::NamedScopeHandler::EndAttributes() {
child_context_.name = ComputeQualifiedName();
if (child_context_.name.empty() && no_specification) {
cu_context_->reporter->UnknownSpecification(offset_, specification_offset_);
}
return true;
}