[Lldb-commits] [lldb] r260734 - Centralized symbol lookup in IRExecutionUnit, and fixed the code model.

Sean Callanan via lldb-commits lldb-commits at lists.llvm.org
Fri Feb 12 13:11:25 PST 2016


Author: spyffe
Date: Fri Feb 12 15:11:25 2016
New Revision: 260734

URL: http://llvm.org/viewvc/llvm-project?rev=260734&view=rev
Log:
Centralized symbol lookup in IRExecutionUnit, and fixed the code model.

I'm preparing to remove symbol lookup from IRForTarget, where it constitutes a
dreadful hack working around no-longer-existing JIT bugs.  Thanks to our 
contributors, IRForTarget has a lot of smarts that IRExecutionUnit doesn't have,
so I've cleaned them up a bit and moved them over to IRExecutionUnit.

Also for historical reasons, IRExecutionUnit used the "Small" code model on non-
ELF platforms (namely, OS X).  That's no longer necessary, and we can use the
same code model as everyone else on OS X.  I've fixed that.

Modified:
    lldb/trunk/include/lldb/Expression/IRExecutionUnit.h
    lldb/trunk/source/Expression/IRExecutionUnit.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp

Modified: lldb/trunk/include/lldb/Expression/IRExecutionUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRExecutionUnit.h?rev=260734&r1=260733&r2=260734&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRExecutionUnit.h (original)
+++ lldb/trunk/include/lldb/Expression/IRExecutionUnit.h Fri Feb 12 15:11:25 2016
@@ -28,6 +28,7 @@
 #include "lldb/Expression/IRMemoryMap.h"
 #include "lldb/Host/Mutex.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
 
 namespace llvm {
     
@@ -71,6 +72,7 @@ public:
                      std::unique_ptr<llvm::Module> &module_ap,
                      ConstString &name,
                      const lldb::TargetSP &target_sp,
+                     const SymbolContext &sym_ctx,
                      std::vector<std::string> &cpu_features);
     
     //------------------------------------------------------------------
@@ -131,7 +133,16 @@ public:
     
     lldb::ModuleSP
     GetJITModule ();
+        
+    static lldb::addr_t
+    FindSymbol(const ConstString &name,
+               const SymbolContext &sc);
     
+    lldb::addr_t
+    FindSymbol(const ConstString &name)
+    {
+        return FindSymbol(name, m_sym_ctx);
+    }
 private:
     //------------------------------------------------------------------
     /// Look up the object in m_address_map that contains a given address,
@@ -275,9 +286,6 @@ private:
         void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
         }
         
-        //------------------------------------------------------------------
-        /// Passthrough interface stub
-        //------------------------------------------------------------------
         uint64_t getSymbolAddress(const std::string &Name) override;
 
         void *getPointerToNamedFunction(const std::string &Name,
@@ -387,6 +395,7 @@ private:
     std::vector<std::string>                m_cpu_features;
     llvm::SmallVector<JittedFunction, 1>    m_jitted_functions;     ///< A vector of all functions that have been JITted into machine code
     const ConstString                       m_name;
+    SymbolContext                           m_sym_ctx;              ///< Used for symbol lookups
     std::vector<ConstString>                m_failed_lookups;
     
     std::atomic<bool>                       m_did_jit;

Modified: lldb/trunk/source/Expression/IRExecutionUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRExecutionUnit.cpp?rev=260734&r1=260733&r2=260734&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRExecutionUnit.cpp (original)
+++ lldb/trunk/source/Expression/IRExecutionUnit.cpp Fri Feb 12 15:11:25 2016
@@ -20,18 +20,24 @@
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Section.h"
+#include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Expression/IRExecutionUnit.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 
+#include "lldb/../../source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+
 using namespace lldb_private;
 
 IRExecutionUnit::IRExecutionUnit (std::unique_ptr<llvm::LLVMContext> &context_ap,
                                   std::unique_ptr<llvm::Module> &module_ap,
                                   ConstString &name,
                                   const lldb::TargetSP &target_sp,
+                                  const SymbolContext &sym_ctx,
                                   std::vector<std::string> &cpu_features) :
     IRMemoryMap(target_sp),
     m_context_ap(context_ap.release()),
@@ -39,6 +45,7 @@ IRExecutionUnit::IRExecutionUnit (std::u
     m_module(m_module_ap.get()),
     m_cpu_features(cpu_features),
     m_name(name),
+    m_sym_ctx(sym_ctx),
     m_did_jit(false),
     m_function_load_addr(LLDB_INVALID_ADDRESS),
     m_function_end_load_addr(LLDB_INVALID_ADDRESS)
@@ -285,14 +292,14 @@ IRExecutionUnit::GetRunnableInfo(Error &
     if (triple.isOSBinFormatELF())
     {
         relocModel = llvm::Reloc::Static;
-        // This will be small for 32-bit and large for 64-bit.
-        codeModel = llvm::CodeModel::JITDefault;
     }
     else
     {
         relocModel = llvm::Reloc::PIC_;
-        codeModel = llvm::CodeModel::Small;
     }
+    
+    // This will be small for 32-bit and large for 64-bit.
+    codeModel = llvm::CodeModel::JITDefault;
 
     m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, &error);
 
@@ -637,94 +644,344 @@ IRExecutionUnit::MemoryManager::allocate
     return return_value;
 }
 
-uint64_t
-IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name)
+static void
+FindCodeSymbolInContext(const ConstString &name,
+                        const SymbolContext &sym_ctx,
+                        uint32_t name_type_mask,
+                        SymbolContextList &sc_list)
+{
+    sc_list.Clear();
+    SymbolContextList temp_sc_list;
+    if (sym_ctx.module_sp)
+        sym_ctx.module_sp->FindFunctions(name,
+                                         NULL,
+                                         name_type_mask,
+                                         true,  // include_symbols
+                                         false, // include_inlines
+                                         true,  // append
+                                         temp_sc_list);
+    if (temp_sc_list.GetSize() == 0)
+    {
+        if (sym_ctx.target_sp)
+            sym_ctx.target_sp->GetImages().FindFunctions(name,
+                                                         name_type_mask,
+                                                         true,  // include_symbols
+                                                         false, // include_inlines
+                                                         true,  // append
+                                                         temp_sc_list);
+    }
+
+    SymbolContextList internal_symbol_sc_list;
+    unsigned temp_sc_list_size = temp_sc_list.GetSize();
+    for (unsigned i = 0; i < temp_sc_list_size; i++)
+    {
+        SymbolContext sc;
+        temp_sc_list.GetContextAtIndex(i, sc);
+        if (sc.function)
+        {
+            sc_list.Append(sc);
+        }
+        else if (sc.symbol)
+        {
+            if (sc.symbol->IsExternal())
+            {
+                sc_list.Append(sc);
+            }
+            else
+            {
+                internal_symbol_sc_list.Append(sc);
+            }
+        }
+    }
+
+    // If we had internal symbols and we didn't find any external symbols or
+    // functions in debug info, then fallback to the internal symbols
+    if (sc_list.GetSize() == 0 && internal_symbol_sc_list.GetSize())
+    {
+        sc_list = internal_symbol_sc_list;
+    }
+}
+
+static ConstString
+FindBestAlternateMangledName(const ConstString &demangled,
+                             const lldb::LanguageType &lang_type,
+                             const SymbolContext &sym_ctx)
 {
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-    
-    SymbolContextList sc_list;
-    
-    ExecutionContextScope *exe_scope = m_parent.GetBestExecutionContextScope();
-    
-    lldb::TargetSP target_sp = exe_scope->CalculateTarget();
-    
-    const char *name = Name.c_str();
+    CPlusPlusLanguage::MethodName cpp_name(demangled);
+    std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
+
+    if (!scope_qualified_name.size())
+        return ConstString();
+
+    if (!sym_ctx.module_sp)
+        return ConstString();
+
+    SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor();
+    if (!sym_vendor)
+        return ConstString();
+
+    lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile();
+    if (!sym_file)
+        return ConstString();
+
+    std::vector<ConstString> alternates;
+    sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
+
+    std::vector<ConstString> param_and_qual_matches;
+    std::vector<ConstString> param_matches;
+    for (size_t i = 0; i < alternates.size(); i++)
+    {
+        ConstString alternate_mangled_name = alternates[i];
+        Mangled mangled(alternate_mangled_name, true);
+        ConstString demangled = mangled.GetDemangledName(lang_type);
+
+        CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
+        if (!cpp_name.IsValid())
+            continue;
+
+        if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments())
+        {
+            if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
+                param_and_qual_matches.push_back(alternate_mangled_name);
+            else
+                param_matches.push_back(alternate_mangled_name);
+        }
+    }
+
+    if (param_and_qual_matches.size())
+        return param_and_qual_matches[0]; // It is assumed that there will be only one!
+    else if (param_matches.size())
+        return param_matches[0]; // Return one of them as a best match
+    else
+        return ConstString();
+}
+
+struct SearchSpec
+{
+    ConstString name;
+    uint32_t    mask;
+
+    SearchSpec(ConstString n, uint32_t m = lldb::eFunctionNameTypeAuto) :
+        name(n),
+        mask(m)
+    {
+    }
+};
+
+static void
+CollectCandidateCNames(std::vector<SearchSpec> &C_specs, const ConstString &name)
+{
+    C_specs.push_back(SearchSpec(name));
+    if (name.AsCString()[0] == '_')
+        C_specs.push_back(ConstString(&name.AsCString()[1]));
+}
+
+static void
+CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs, const std::vector<SearchSpec> &C_specs, const SymbolContext &sc)
+{
+    for (const SearchSpec &C_spec : C_specs)
+    {
+        const ConstString &name = C_spec.name;
+
+        if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString()))
+        {
+            Mangled mangled(name, true);
+            ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
+            
+            if (demangled)
+            {
+                ConstString best_alternate_mangled_name = FindBestAlternateMangledName(demangled, lldb::eLanguageTypeC_plus_plus, sc);
+                
+                if (best_alternate_mangled_name)
+                {
+                    CPP_specs.push_back(best_alternate_mangled_name);
+                }
+                
+                CPP_specs.push_back(SearchSpec(demangled, lldb::eFunctionNameTypeFull));
+            }
+        }
+        
+        // Maybe we're looking for a const symbol but the debug info told us it was const...
+        if (!strncmp(name.GetCString(), "_ZN", 3) &&
+            strncmp(name.GetCString(), "_ZNK", 4))
+        {
+            std::string fixed_scratch("_ZNK");
+            fixed_scratch.append(name.GetCString() + 3);
+            CPP_specs.push_back(ConstString(fixed_scratch.c_str()));
+        }
+        
+        // Maybe we're looking for a static symbol but we thought it was global...
+        if (!strncmp(name.GetCString(), "_Z", 2) &&
+            strncmp(name.GetCString(), "_ZL", 3))
+        {
+            std::string fixed_scratch("_ZL");
+            fixed_scratch.append(name.GetCString() + 2);
+            CPP_specs.push_back(ConstString(fixed_scratch.c_str()));
+        }
+
+    }
+}
+
+static lldb::addr_t
+FindInSymbols(const std::vector<SearchSpec> &specs, const lldb_private::SymbolContext &sc)
+{
+    for (const SearchSpec &spec : specs)
+    {
+        SymbolContextList sc_list;
+        
+        if (sc.module_sp)
+        {
+            sc.module_sp->FindFunctions(spec.name,
+                                        NULL,
+                                        spec.mask,
+                                        true,  // include_symbols
+                                        false, // include_inlines
+                                        true,  // append
+                                        sc_list);
+        }
     
-    ConstString bare_name_cs(name);
-    ConstString name_cs;
+        if (sc_list.GetSize() == 0 && sc.target_sp)
+        {
+            sc.target_sp->GetImages().FindFunctions(spec.name,
+                                                    spec.mask,
+                                                    true,  // include_symbols
+                                                    false, // include_inlines
+                                                    true,  // append
+                                                    sc_list);
+        }
+        
+        if (sc_list.GetSize() == 0 && sc.target_sp)
+        {
+            sc.target_sp->GetImages().FindSymbolsWithNameAndType(spec.name, lldb::eSymbolTypeAny, sc_list);
+        }
+
+        lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS;
+        
+        for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si)
+        {
+            bool is_external = false;
+            
+            SymbolContext candidate_sc;
+            
+            sc_list.GetContextAtIndex(si, candidate_sc);
+            if (candidate_sc.function)
+            {
+                is_external = true;
+            }
+            else if (sc.symbol)
+            {
+                if (sc.symbol->IsExternal())
+                {
+                    is_external = true;
+                }
+            }
+            
+            lldb::addr_t load_address = candidate_sc.symbol->ResolveCallableAddress(*sc.target_sp);
+            
+            if (load_address == LLDB_INVALID_ADDRESS)
+                load_address = candidate_sc.symbol->GetAddress().GetLoadAddress(sc.target_sp.get());
+
+            if (load_address != LLDB_INVALID_ADDRESS)
+            {
+                if (is_external)
+                {
+                    return load_address;
+                }
+                else
+                {
+                    best_internal_load_address = load_address;
+                }
+            }
+        }
+        if (best_internal_load_address != LLDB_INVALID_ADDRESS)
+        {
+            return best_internal_load_address;
+        }
+    }
     
-    if (name[0] == '_')
-        name_cs = ConstString(name + 1);
+    return LLDB_INVALID_ADDRESS;
+}
+
+static lldb::addr_t
+FindInRuntimes(const std::vector<SearchSpec> &specs, const lldb_private::SymbolContext &sc)
+{
+    lldb::TargetSP target_sp = sc.target_sp;
     
     if (!target_sp)
     {
-        if (log)
-            log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <no target>",
-                        Name.c_str());
-        
-        m_parent.ReportSymbolLookupError(name_cs);
-        
-        return 0xbad0bad0;
+        return LLDB_INVALID_ADDRESS;
     }
     
-    uint32_t num_matches = 0;
-    lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
+    lldb::ProcessSP process_sp = sc.target_sp->GetProcessSP();
     
-    if (!name_cs.IsEmpty())
+    if (!process_sp)
     {
-        target_sp->GetImages().FindSymbolsWithNameAndType(name_cs, lldb::eSymbolTypeAny, sc_list);
-        num_matches = sc_list.GetSize();
+        return LLDB_INVALID_ADDRESS;
     }
-    
-    if (!num_matches)
+
+    ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
+
+    if (runtime)
     {
-        target_sp->GetImages().FindSymbolsWithNameAndType(bare_name_cs, lldb::eSymbolTypeAny, sc_list);
-        num_matches = sc_list.GetSize();
+        for (const SearchSpec &spec : specs)
+        {
+            lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(spec.name);
+            
+            if (symbol_load_addr != LLDB_INVALID_ADDRESS)
+                return symbol_load_addr;
+        }
     }
-        
-    lldb::addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
     
-    for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++)
-    {
-        SymbolContext sym_ctx;
-        sc_list.GetContextAtIndex(i, sym_ctx);
-        
-        symbol_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target_sp);
+    return LLDB_INVALID_ADDRESS;
+}
 
-        if (symbol_load_addr == LLDB_INVALID_ADDRESS)
-            symbol_load_addr = sym_ctx.symbol->GetAddress().GetLoadAddress(target_sp.get());
-    }
+lldb::addr_t
+IRExecutionUnit::FindSymbol(const lldb_private::ConstString &name, const lldb_private::SymbolContext &sc)
+{
+    std::vector<SearchSpec> candidate_C_names;
+    std::vector<SearchSpec> candidate_CPlusPlus_names;
     
-    if (symbol_load_addr == LLDB_INVALID_ADDRESS && process_sp && name_cs)
+    CollectCandidateCNames(candidate_C_names, name);
+
+    lldb::addr_t ret = FindInSymbols(candidate_C_names, sc);
+    if (ret == LLDB_INVALID_ADDRESS)
+        ret = FindInRuntimes(candidate_C_names, sc);
+    
+    if (ret == LLDB_INVALID_ADDRESS)
     {
-        // Try the Objective-C language runtime.
-        
-        ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
-        
-        if (runtime)
-            symbol_load_addr = runtime->LookupRuntimeSymbol(name_cs);
+        CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names, sc);
+        ret = FindInSymbols(candidate_CPlusPlus_names, sc);
     }
     
-    if (symbol_load_addr == LLDB_INVALID_ADDRESS)
+    return ret;
+}
+
+uint64_t
+IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    ConstString name_cs(Name.c_str());
+    
+    lldb::addr_t ret = m_parent.FindSymbol(name_cs);
+    
+    if (ret == LLDB_INVALID_ADDRESS)
     {
         if (log)
             log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
-                        name);
-        
-        m_parent.ReportSymbolLookupError(bare_name_cs);
-        
+                        Name.c_str());
+
+        m_parent.ReportSymbolLookupError(name_cs);
         return 0xbad0bad0;
     }
-    
-    if (log)
-        log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
-                    name,
-                    symbol_load_addr);
-    
-    if (symbol_load_addr == 0)
-        return 0xbad00add;
-    
-    return symbol_load_addr;
+    else
+    {
+        if (log)
+            log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
+                        Name.c_str(),
+                        ret);
+        return ret;
+    }
 }
 
 void *

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp?rev=260734&r1=260733&r2=260734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp Fri Feb 12 15:11:25 2016
@@ -612,11 +612,23 @@ ClangExpressionParser::PrepareForExecuti
         if (log)
             log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
     }
+    
+    SymbolContext sc;
+    
+    if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP())
+    {
+        sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
+    }
+    else if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP())
+    {
+        sc.target_sp = target_sp;
+    }
 
     execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
                                                  llvm_module_ap, // handed off here
                                                  function_name,
                                                  exe_ctx.GetTargetSP(),
+                                                 sc,
                                                  m_compiler->getTargetOpts().Features));
 
     ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());




More information about the lldb-commits mailing list