aboutsummaryrefslogtreecommitdiff
path: root/source/Expression/IRExecutionUnit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Expression/IRExecutionUnit.cpp')
-rw-r--r--source/Expression/IRExecutionUnit.cpp165
1 files changed, 143 insertions, 22 deletions
diff --git a/source/Expression/IRExecutionUnit.cpp b/source/Expression/IRExecutionUnit.cpp
index e7cb728778e6..9ca9e25907b6 100644
--- a/source/Expression/IRExecutionUnit.cpp
+++ b/source/Expression/IRExecutionUnit.cpp
@@ -199,28 +199,8 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
disassembler_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);
InstructionList &instruction_list = disassembler_sp->GetInstructionList();
- const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
- const char *disassemble_format = "${addr-file-or-load}: ";
- if (exe_ctx.HasTargetScope())
- {
- disassemble_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat();
- }
-
- for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
- instruction_index < num_instructions;
- ++instruction_index)
- {
- Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
- instruction->Dump (&stream,
- max_opcode_byte_size,
- true,
- true,
- &exe_ctx,
- NULL,
- NULL,
- disassemble_format);
- stream.PutChar('\n');
- }
+ instruction_list.Dump(&stream, true, true, &exe_ctx);
+
// FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
// I'll fix that but for now, just clear the list and it will go away nicely.
disassembler_sp->GetInstructionList().Clear();
@@ -239,6 +219,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,
lldb::addr_t &func_end)
@@ -369,6 +355,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 +617,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\") = <no target>",
+ 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; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++)
+ {
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(i, sym_ctx);
+
+ if (sym_ctx.symbol->GetType() == 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\") = <not found>",
+ 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)
{