diff --git a/lldb/include/lldb/Expression/IRExecutionUnit.h b/lldb/include/lldb/Expression/IRExecutionUnit.h index c15c65c92a3b..bd1a795a158e 100644 --- a/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -207,6 +207,9 @@ private: DisassembleFunction (Stream &stream, lldb::ProcessSP &process_sp); + void + ReportSymbolLookupError(const ConstString &name); + class MemoryManager : public llvm::SectionMemoryManager { public: @@ -282,10 +285,10 @@ private: //------------------------------------------------------------------ /// Passthrough interface stub //------------------------------------------------------------------ + virtual uint64_t getSymbolAddress(const std::string &Name); + virtual void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true) { - return m_default_mm_ap->getPointerToNamedFunction(Name, AbortOnFailure); - } + bool AbortOnFailure = true); private: std::unique_ptr m_default_mm_ap; ///< The memory allocator to use in actually creating space. All calls are passed through to it. IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for. @@ -390,6 +393,7 @@ private: std::vector m_cpu_features; llvm::SmallVector m_jitted_functions; ///< A vector of all functions that have been JITted into machine code const ConstString m_name; + std::vector m_failed_lookups; std::atomic m_did_jit; diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index e7cb728778e6..73974f720287 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -238,6 +238,12 @@ static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, void *Con } } +void +IRExecutionUnit::ReportSymbolLookupError(const ConstString &name) +{ + m_failed_lookups.push_back(name); +} + void IRExecutionUnit::GetRunnableInfo(Error &error, lldb::addr_t &func_addr, @@ -369,6 +375,33 @@ IRExecutionUnit::GetRunnableInfo(Error &error, ReportAllocations(*m_execution_engine_ap); WriteData(process_sp); + if (m_failed_lookups.size()) + { + StreamString ss; + + ss.PutCString("Couldn't lookup symbols:\n"); + + bool emitNewLine = false; + + for (const ConstString &failed_lookup : m_failed_lookups) + { + if (emitNewLine) + ss.PutCString("\n"); + emitNewLine = true; + ss.PutCString(" "); + ss.PutCString(Mangled(failed_lookup).GetDemangledName().AsCString()); + } + + m_failed_lookups.clear(); + + error.SetErrorString(ss.GetData()); + + return; + } + + m_function_load_addr = LLDB_INVALID_ADDRESS; + m_function_end_load_addr = LLDB_INVALID_ADDRESS; + for (JittedFunction &jitted_function : m_jitted_functions) { jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr); @@ -604,6 +637,114 @@ IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size, return return_value; } +uint64_t +IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name) +{ + 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(); + + ConstString bare_name_cs(name); + ConstString name_cs; + + if (name[0] == '_') + name_cs = ConstString(name + 1); + + if (!target_sp) + { + if (log) + log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = ", + Name.c_str()); + + m_parent.ReportSymbolLookupError(name_cs); + + return 0xbad0bad0; + } + + uint32_t num_matches = 0; + lldb::ProcessSP process_sp = exe_scope->CalculateProcess(); + + if (!name_cs.IsEmpty()) + { + target_sp->GetImages().FindSymbolsWithNameAndType(name_cs, lldb::eSymbolTypeAny, sc_list); + num_matches = sc_list.GetSize(); + } + + if (!num_matches) + { + target_sp->GetImages().FindSymbolsWithNameAndType(bare_name_cs, lldb::eSymbolTypeAny, sc_list); + num_matches = sc_list.GetSize(); + } + + lldb::addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; + + for (uint32_t i=0; iGetType() == lldb::eSymbolTypeUndefined) + continue; + + const Address *sym_address = &sym_ctx.symbol->GetAddress(); + + if (!sym_address || !sym_address->IsValid()) + continue; + + symbol_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target_sp); + + if (symbol_load_addr == LLDB_INVALID_ADDRESS) + { + symbol_load_addr = sym_ctx.symbol->GetAddress().GetLoadAddress(target_sp.get()); + } + } + + if (symbol_load_addr == LLDB_INVALID_ADDRESS && process_sp && name_cs) + { + // Try the Objective-C language runtime. + + ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime(); + + if (runtime) + symbol_load_addr = runtime->LookupRuntimeSymbol(name_cs); + } + + if (symbol_load_addr == LLDB_INVALID_ADDRESS) + { + if (log) + log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = ", + name); + + m_parent.ReportSymbolLookupError(bare_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; +} + +void * +IRExecutionUnit::MemoryManager::getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure) { + assert (sizeof(void *) == 8); + + return (void*)getSymbolAddress(Name); +} + lldb::addr_t IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address) {