forked from OSchip/llvm-project
[IRForTarget] Strenghten handling of alternate mangling.
Summary: This fixes an issue with GCC generated binaries wherein an expression with method invocations on std::string variables was failing. Such use cases are tested in TestSTL (albeit, in a test marked with @unittest2.expectedFailure because of other reasons). The reason for this particular failure with GCC is that the generated DWARF for std::basic_string<...> is incomplete, which makes clang not to use the alternate mangling scheme. GCC correctly generates the name of basic_string<...>: DW_AT_name "basic_string<char, std::char_traits<char>, std::allocator<char> >" It also lists the template parameters of basic_string correctly: DW_TAG_template_type_parameter DW_AT_name "_CharT" DW_AT_type <0x0000009c> DW_TAG_template_type_parameter DW_AT_name "_Traits" DW_AT_type <0x00000609> DW_TAG_template_type_parameter DW_AT_name "_Alloc" DW_AT_type <0x000007fb> However, it does not list the template parameters of std::char_traits<>. This makes Clang feel (while parsing the expression) that the string variable is not actually a basic_string instance, and consequently does not use the alternate mangling scheme. Test Plan: dotest.py -C gcc -p TestSTL -- See it go past the "for" loop expression successfully. Reviewers: clayborg, spyffe Reviewed By: clayborg, spyffe Subscribers: tberghammer, zturner, lldb-commits Differential Revision: http://reviews.llvm.org/D8846 llvm-svn: 234522
This commit is contained in:
parent
10821e5283
commit
0f404e0575
|
@ -153,6 +153,9 @@ public:
|
|||
static uint32_t
|
||||
FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents);
|
||||
|
||||
virtual size_t
|
||||
GetAlternateManglings(const ConstString &mangled, std::vector<ConstString> &alternates) = 0;
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
// Classes that inherit from CPPLanguageRuntime can see and modify these
|
||||
|
|
|
@ -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 <map>
|
||||
|
||||
|
@ -226,44 +227,42 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
|
|||
{
|
||||
if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
|
||||
{
|
||||
lldb_private::ConstString altnernate_name;
|
||||
std::vector<lldb_private::ConstString> alternates;
|
||||
bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr);
|
||||
if (!found_it)
|
||||
{
|
||||
// Check for an alternate mangling for "std::basic_string<char>"
|
||||
// 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());
|
||||
|
|
|
@ -281,9 +281,43 @@ ItaniumABILanguageRuntime::IsVTableName (const char *name)
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t
|
||||
ItaniumABILanguageRuntime::GetAlternateManglings(const ConstString &mangled, std::vector<ConstString> &alternates)
|
||||
{
|
||||
if (!mangled)
|
||||
return static_cast<size_t>(0);
|
||||
|
||||
alternates.clear();
|
||||
const char *mangled_cstr = mangled.AsCString();
|
||||
for (typename std::map<ConstString, std::vector<ConstString> >::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<ConstString> &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<size_t>(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Static Functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
std::map<ConstString, std::vector<ConstString> > ItaniumABILanguageRuntime::s_alternate_mangling_prefixes;
|
||||
|
||||
LanguageRuntime *
|
||||
ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language)
|
||||
{
|
||||
|
@ -304,6 +338,15 @@ ItaniumABILanguageRuntime::Initialize()
|
|||
PluginManager::RegisterPlugin (GetPluginNameStatic(),
|
||||
"Itanium ABI for the C++ language",
|
||||
CreateInstance);
|
||||
|
||||
// Alternate manglings for std::basic_string<...>
|
||||
std::vector<ConstString> basic_string_alternates;
|
||||
basic_string_alternates.push_back(ConstString("_ZNSs"));
|
||||
basic_string_alternates.push_back(ConstString("_ZNKSs"));
|
||||
s_alternate_mangling_prefixes[ConstString("_ZNSbIcSt17char_traits<char>St15allocator<char>E")] =
|
||||
basic_string_alternates;
|
||||
s_alternate_mangling_prefixes[ConstString("_ZNKSbIcSt17char_traits<char>St15allocator<char>E")] =
|
||||
basic_string_alternates;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include "lldb/Target/CPPLanguageRuntime.h"
|
||||
#include "lldb/Core/Value.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ItaniumABILanguageRuntime :
|
||||
|
@ -82,6 +85,9 @@ namespace lldb_private {
|
|||
virtual lldb::SearchFilterSP
|
||||
CreateExceptionSearchFilter ();
|
||||
|
||||
virtual size_t
|
||||
GetAlternateManglings(const ConstString &mangled, std::vector<ConstString> &alternates);
|
||||
|
||||
protected:
|
||||
|
||||
lldb::BreakpointResolverSP
|
||||
|
@ -97,6 +103,8 @@ namespace lldb_private {
|
|||
ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead.
|
||||
|
||||
lldb::BreakpointSP m_cxx_exception_bp_sp;
|
||||
|
||||
static std::map<ConstString, std::vector<ConstString> > s_alternate_mangling_prefixes;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
Loading…
Reference in New Issue