[dump_syms] Relax name matching for marking symbols as multiple

Previously, the logic to mark a symbol as "multiple" would always fire
for C++ symbols for Apple `.dSYM`s built with `-gmlt`.

This was because for a C++ symbol like `void foo::bar::Baz()`, the
DWARF data would contain the truncated function name `Baz`, but the
STABS would contain the fully-qualified name `void foo::bar::Baz()`.

This CL relaxes the name matching to not mark as multiple:

1) Symbols which were missing names entirely in the DWARF (e.g, "<name omitted">)`
2) Symbols whose fully-qualified name includes the truncated name as a substring

Bug: https://bugs.chromium.org/p/google-breakpad/issues/detail?id=883
Change-Id: I26ded7ca84d964aa4a73da19e4bdd7e686e2c998
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/4470047
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Ben Hamilton 2023-04-24 13:53:09 -06:00 committed by Joshua Peraza
parent f548d75c9f
commit bfde407de5

View file

@ -157,8 +157,22 @@ bool Module::AddFunction(Function* function) {
Extern* found_ext = it_ext->get(); Extern* found_ext = it_ext->get();
bool name_mismatch = found_ext->name != function->name; bool name_mismatch = found_ext->name != function->name;
if (enable_multiple_field_) { if (enable_multiple_field_) {
bool is_multiple_based_on_name;
// In the case of a .dSYM built with -gmlt, the external name will be the
// fully-qualified symbol name, but the function name will be the partial
// name (or omitted).
//
// Don't mark multiple in this case.
if (name_mismatch &&
(function->name == "<name omitted>" ||
found_ext->name.find(function->name.str()) != string::npos)) {
is_multiple_based_on_name = false;
} else {
is_multiple_based_on_name = name_mismatch;
}
// If the PUBLIC is for the same symbol as the FUNC, don't mark multiple. // If the PUBLIC is for the same symbol as the FUNC, don't mark multiple.
function->is_multiple |= name_mismatch || found_ext->is_multiple; function->is_multiple |=
is_multiple_based_on_name || found_ext->is_multiple;
} }
if (name_mismatch && prefer_extern_name_) { if (name_mismatch && prefer_extern_name_) {
function->name = AddStringToPool(it_ext->get()->name); function->name = AddStringToPool(it_ext->get()->name);