From 80d48155cf47e37d5c4dfc3b28d4ee8c7844ca34 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 9 May 2018 08:21:25 +0000 Subject: [PATCH] [DWARF] Align non-accelerated function fullname searching with the apple-tables path Summary: Before this patch the two paths were doing very different things - the apple path searched the .apple_names section, which contained mangled names, as well as basenames of all functions. It returned any name it found. - the non-accelerated path looked in the "full name" index we built ourselves, which contained mangled as well as demangled names of all functions (but no basenames). Then however, if it did not find a match it did an extra search in the basename index, with some special handling for anonymous namespaces. This aligns the two paths by changing the non-accelerated path to return the same results as in the apple-tables one. In pratice, this means we will search in both the "basename", "method" and "fullname" indexes (in the manual indexes these are separate indexes. This means the function will return some slightly inappropriate results (e.g. bar::baz::foo when one asks for a "full name" foo), but this can be handled by additional filtering, independently indexing method. I've also stopped inserting demangled names into the "fullname" index, as that is inconsistent with the apple path. Reviewers: clayborg, JDevlieghere Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D46576 llvm-svn: 331855 --- .../SymbolFile/DWARF/find-basic-function.cpp | 12 ++++- .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 14 +----- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 46 ++++++------------- 3 files changed, 27 insertions(+), 45 deletions(-) diff --git a/lldb/lit/SymbolFile/DWARF/find-basic-function.cpp b/lldb/lit/SymbolFile/DWARF/find-basic-function.cpp index 39d81ae7eb32..a3adee5d9408 100644 --- a/lldb/lit/SymbolFile/DWARF/find-basic-function.cpp +++ b/lldb/lit/SymbolFile/DWARF/find-basic-function.cpp @@ -8,6 +8,8 @@ // RUN: FileCheck --check-prefix=METHOD %s // RUN: lldb-test symbols --name=foo --find=function --function-flags=full %t | \ // RUN: FileCheck --check-prefix=FULL %s +// RUN: lldb-test symbols --name=_Z3fooi --find=function --function-flags=full %t | \ +// RUN: FileCheck --check-prefix=FULL-MANGLED %s // RUN: lldb-test symbols --name=foo --context=context --find=function --function-flags=base %t | \ // RUN: FileCheck --check-prefix=CONTEXT %s // RUN: lldb-test symbols --name=not_there --find=function %t | \ @@ -24,9 +26,17 @@ // METHOD-DAG: name = "sbar::foo(int)", mangled = "_ZN4sbar3fooEi" // METHOD-DAG: name = "ffbar()::sbar::foo()", mangled = "_ZZ5ffbarvEN4sbar3fooEv" -// FULL: Found 2 functions: +// FULL: Found 7 functions: // FULL-DAG: name = "foo()", mangled = "_Z3foov" // FULL-DAG: name = "foo(int)", mangled = "_Z3fooi" +// FULL-DAG: name = "bar::foo()", mangled = "_ZN3bar3fooEv" +// FULL-DAG: name = "bar::baz::foo()", mangled = "_ZN3bar3baz3fooEv" +// FULL-DAG: name = "sbar::foo()", mangled = "_ZN4sbar3fooEv" +// FULL-DAG: name = "sbar::foo(int)", mangled = "_ZN4sbar3fooEi" +// FULL-DAG: name = "ffbar()::sbar::foo()", mangled = "_ZZ5ffbarvEN4sbar3fooEv" + +// FULL-MANGLED: Found 1 functions: +// FULL-DAG: name = "foo(int)", mangled = "_Z3fooi" // CONTEXT: Found 1 functions: // CONTEXT-DAG: name = "bar::foo()", mangled = "_ZN3bar3fooEv" diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index d515dd73e12f..4501e5acafc8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -897,13 +897,8 @@ void DWARFUnit::IndexPrivate( if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { - Mangled mangled(ConstString(mangled_cstr), true); - func_fullnames.Insert(mangled.GetMangledName(), + func_fullnames.Insert(ConstString(mangled_cstr), DIERef(cu_offset, die.GetOffset())); - ConstString demangled = mangled.GetDemangledName(cu_language); - if (demangled) - func_fullnames.Insert(demangled, - DIERef(cu_offset, die.GetOffset())); } } } @@ -922,13 +917,8 @@ void DWARFUnit::IndexPrivate( if (name && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { - Mangled mangled(ConstString(mangled_cstr), true); - func_fullnames.Insert(mangled.GetMangledName(), + func_fullnames.Insert(ConstString(mangled_cstr), DIERef(cu_offset, die.GetOffset())); - ConstString demangled = mangled.GetDemangledName(cu_language); - if (demangled) - func_fullnames.Insert(demangled, - DIERef(cu_offset, die.GetOffset())); } } else func_fullnames.Insert(ConstString(name), diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index cd13b4c72c4e..967a31eb4217 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2626,44 +2626,26 @@ SymbolFileDWARF::FindFunctions(const ConstString &name, if (!m_indexed) Index(); + DIEArray die_offsets; if (name_type_mask & eFunctionNameTypeFull) { - FindFunctions(name, m_function_fullname_index, include_inlines, sc_list); + uint32_t num_matches = m_function_basename_index.Find(name, die_offsets); + num_matches += m_function_method_index.Find(name, die_offsets); + num_matches += m_function_fullname_index.Find(name, die_offsets); + for (uint32_t i = 0; i < num_matches; i++) { + const DIERef &die_ref = die_offsets[i]; + DWARFDIE die = info->GetDIE(die_ref); + if (die) { + if (!DIEInDeclContext(parent_decl_ctx, die)) + continue; // The containing decl contexts don't match - // FIXME Temporary workaround for global/anonymous namespace - // functions debugging FreeBSD and Linux binaries. If we didn't find any - // functions in the global namespace try looking in the basename index - // but ignore any returned functions that have a namespace but keep - // functions which have an anonymous namespace - // TODO: The arch in the object file isn't correct for MSVC - // binaries on windows, we should find a way to make it correct and - // handle those symbols as well. - if (sc_list.GetSize() == original_size) { - ArchSpec arch; - if (!parent_decl_ctx && GetObjectFile()->GetArchitecture(arch) && - arch.GetTriple().isOSBinFormatELF()) { - SymbolContextList temp_sc_list; - FindFunctions(name, m_function_basename_index, include_inlines, - temp_sc_list); - SymbolContext sc; - for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++) { - if (temp_sc_list.GetContextAtIndex(i, sc)) { - ConstString mangled_name = - sc.GetFunctionName(Mangled::ePreferMangled); - ConstString demangled_name = - sc.GetFunctionName(Mangled::ePreferDemangled); - // Mangled names on Linux and FreeBSD are of the form: - // _ZN18function_namespace13function_nameEv. - if (strncmp(mangled_name.GetCString(), "_ZN", 3) || - !strncmp(demangled_name.GetCString(), "(anonymous namespace)", - 21)) { - sc_list.Append(sc); - } - } + if (resolved_dies.find(die.GetDIE()) == resolved_dies.end()) { + if (ResolveFunction(die, include_inlines, sc_list)) + resolved_dies.insert(die.GetDIE()); } } } + die_offsets.clear(); } - DIEArray die_offsets; if (name_type_mask & eFunctionNameTypeBase) { uint32_t num_base = m_function_basename_index.Find(name, die_offsets); for (uint32_t i = 0; i < num_base; i++) {