Index: include/lldb/Target/CPPLanguageRuntime.h =================================================================== --- include/lldb/Target/CPPLanguageRuntime.h +++ include/lldb/Target/CPPLanguageRuntime.h @@ -153,6 +153,9 @@ static uint32_t FindEquivalentNames(ConstString type_name, std::vector& equivalents); + virtual size_t + GetAlternateManglings(const ConstString &mangled, std::vector &alternates) = 0; + protected: //------------------------------------------------------------------ // Classes that inherit from CPPLanguageRuntime can see and modify these Index: source/Expression/IRForTarget.cpp =================================================================== --- source/Expression/IRForTarget.cpp +++ source/Expression/IRForTarget.cpp @@ -35,6 +35,7 @@ #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangASTType.h" +#include "lldb/Target/CPPLanguageRuntime.h" #include @@ -226,44 +227,42 @@ { if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr)) { - lldb_private::ConstString altnernate_name; + std::vector alternates; bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr); if (!found_it) { - // Check for an alternate mangling for "std::basic_string" - // that is part of the itanium C++ name mangling scheme - const char *name_cstr = name.GetCString(); - if (name_cstr && strncmp(name_cstr, "_ZNKSbIcE", strlen("_ZNKSbIcE")) == 0) + if (log) + log->Printf("Address of function \"%s\" not found.\n", name.GetCString()); + // Check for an alternate mangling for names from the standard library. + // For example, "std::basic_string<...>" has an alternate mangling scheme per + // the Itanium C++ ABI. + lldb::ProcessSP process_sp = m_data_allocator.GetTarget()->GetProcessSP(); + lldb_private::CPPLanguageRuntime *cpp_runtime = process_sp->GetCPPLanguageRuntime(); + if (cpp_runtime && cpp_runtime->GetAlternateManglings(name, alternates)) { - std::string alternate_mangling("_ZNKSs"); - alternate_mangling.append (name_cstr + strlen("_ZNKSbIcE")); - altnernate_name.SetCString(alternate_mangling.c_str()); - found_it = m_decl_map->GetFunctionAddress (altnernate_name, fun_addr); + for (size_t i = 0; i < alternates.size(); ++i) + { + const lldb_private::ConstString &alternate_name = alternates[i]; + if (log) + log->Printf("Looking up address of function \"%s\" with alternate name \"%s\"", + name.GetCString(), alternate_name.GetCString()); + if ((found_it = m_decl_map->GetFunctionAddress (alternate_name, fun_addr))) + { + if (log) + log->Printf("Found address of function \"%s\" with alternate name \"%s\"", + name.GetCString(), alternate_name.GetCString()); + break; + } + } } } if (!found_it) { lldb_private::Mangled mangled_name(name); - lldb_private::Mangled alt_mangled_name(altnernate_name); - if (log) - { - if (alt_mangled_name) - log->Printf("Function \"%s\" (alternate name \"%s\") has no address", - mangled_name.GetName().GetCString(), - alt_mangled_name.GetName().GetCString()); - else - log->Printf("Function \"%s\" had no address", - mangled_name.GetName().GetCString()); - } - if (m_error_stream) { - if (alt_mangled_name) - m_error_stream->Printf("error: call to a function '%s' (alternate name '%s') that is not present in the target\n", - mangled_name.GetName().GetCString(), - alt_mangled_name.GetName().GetCString()); - else if (mangled_name.GetMangledName()) + if (mangled_name.GetMangledName()) m_error_stream->Printf("error: call to a function '%s' ('%s') that is not present in the target\n", mangled_name.GetName().GetCString(), mangled_name.GetMangledName().GetCString()); Index: source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h =================================================================== --- source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -20,6 +20,9 @@ #include "lldb/Target/CPPLanguageRuntime.h" #include "lldb/Core/Value.h" +#include +#include + namespace lldb_private { class ItaniumABILanguageRuntime : @@ -82,6 +85,9 @@ virtual lldb::SearchFilterSP CreateExceptionSearchFilter (); + virtual size_t + GetAlternateManglings(const ConstString &mangled, std::vector &alternates); + protected: lldb::BreakpointResolverSP @@ -97,6 +103,8 @@ ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead. lldb::BreakpointSP m_cxx_exception_bp_sp; + + static std::map > s_alternate_mangling_prefixes; }; } // namespace lldb_private Index: source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp =================================================================== --- source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -281,9 +281,43 @@ return false; } +size_t +ItaniumABILanguageRuntime::GetAlternateManglings(const ConstString &mangled, std::vector &alternates) +{ + if (!mangled) + return static_cast(0); + + alternates.clear(); + const char *mangled_cstr = mangled.AsCString(); + for (typename std::map >::iterator it = s_alternate_mangling_prefixes.begin(); + it != s_alternate_mangling_prefixes.end(); + ++it) + { + const char *prefix_cstr = it->first.AsCString(); + if (strncmp(mangled_cstr, prefix_cstr, strlen(prefix_cstr)) == 0) + { + const std::vector &alternate_prefixes = it->second; + for (size_t i = 0; i < alternate_prefixes.size(); ++i) + { + std::string alternate_mangling(alternate_prefixes[i].AsCString()); + alternate_mangling.append(mangled_cstr + strlen(prefix_cstr)); + + alternates.push_back(ConstString(alternate_mangling.c_str())); + } + + return alternates.size(); + } + } + + return static_cast(0); +} + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ + +std::map > ItaniumABILanguageRuntime::s_alternate_mangling_prefixes; + LanguageRuntime * ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language) { @@ -304,6 +338,15 @@ PluginManager::RegisterPlugin (GetPluginNameStatic(), "Itanium ABI for the C++ language", CreateInstance); + + // Alternate manglings for std::basic_string<...> + std::vector basic_string_alternates; + basic_string_alternates.push_back(ConstString("_ZNSs")); + basic_string_alternates.push_back(ConstString("_ZNKSs")); + s_alternate_mangling_prefixes[ConstString("_ZNSbIcSt17char_traitsSt15allocatorE")] = + basic_string_alternates; + s_alternate_mangling_prefixes[ConstString("_ZNKSbIcSt17char_traitsSt15allocatorE")] = + basic_string_alternates; } void