[Lldb-commits] [lldb] r234522 - [IRForTarget] Strenghten handling of alternate mangling.

Siva Chandra sivachandra at google.com
Thu Apr 9 11:48:34 PDT 2015


Author: sivachandra
Date: Thu Apr  9 13:48:34 2015
New Revision: 234522

URL: http://llvm.org/viewvc/llvm-project?rev=234522&view=rev
Log:
[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

Modified:
    lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h
    lldb/trunk/source/Expression/IRForTarget.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h

Modified: lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h?rev=234522&r1=234521&r2=234522&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h Thu Apr  9 13:48:34 2015
@@ -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

Modified: lldb/trunk/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=234522&r1=234521&r2=234522&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRForTarget.cpp (original)
+++ lldb/trunk/source/Expression/IRForTarget.cpp Thu Apr  9 13:48:34 2015
@@ -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::F
     {
         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());

Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=234522&r1=234521&r2=234522&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Thu Apr  9 13:48:34 2015
@@ -281,9 +281,43 @@ ItaniumABILanguageRuntime::IsVTableName
         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

Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h?rev=234522&r1=234521&r2=234522&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h Thu Apr  9 13:48:34 2015
@@ -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





More information about the lldb-commits mailing list