[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