Error ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, lldb::addr_t &func_end, std::shared_ptr<IRExecutionUnit> &execution_unit_sp, ExecutionContext &exe_ctx, bool &can_interpret, ExecutionPolicy execution_policy) { func_addr = LLDB_INVALID_ADDRESS; func_end = LLDB_INVALID_ADDRESS; Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); Error err; std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule()); if (!llvm_module_ap.get()) { err.SetErrorToGenericError(); err.SetErrorString("IR doesn't contain a module"); return err; } // Find the actual name of the function (it's often mangled somehow) ConstString function_name; if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName())) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName()); return err; } else { if (log) log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName()); } execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here llvm_module_ap, // handed off here function_name, exe_ctx.GetTargetSP(), m_compiler->getTargetOpts().Features)); ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL if (decl_map) { Stream *error_stream = NULL; Target *target = exe_ctx.GetTargetPtr(); if (target) error_stream = target->GetDebugger().GetErrorFile().get(); IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), *execution_unit_sp, error_stream, function_name.AsCString()); bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule()); Error interpret_error; can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error); Process *process = exe_ctx.GetProcessPtr(); if (!ir_can_run) { err.SetErrorString("The expression could not be prepared to run in the target"); return err; } if (!can_interpret && execution_policy == eExecutionPolicyNever) { err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString()); return err; } if (!process && execution_policy == eExecutionPolicyAlways) { err.SetErrorString("Expression needed to run in the target, but the target can't be run"); return err; } if (execution_policy == eExecutionPolicyAlways || !can_interpret) { if (m_expr.NeedsValidation() && process) { if (!process->GetDynamicCheckers()) { DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions(); StreamString install_errors; if (!dynamic_checkers->Install(install_errors, exe_ctx)) { if (install_errors.GetString().empty()) err.SetErrorString ("couldn't install checkers, unknown error"); else err.SetErrorString (install_errors.GetString().c_str()); return err; } process->SetDynamicCheckers(dynamic_checkers); if (log) log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers =="); } IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString()); if (!ir_dynamic_checks.runOnModule(*execution_unit_sp->GetModule())) { err.SetErrorToGenericError(); err.SetErrorString("Couldn't add dynamic checks to the expression"); return err; } } execution_unit_sp->GetRunnableInfo(err, func_addr, func_end); } } else { execution_unit_sp->GetRunnableInfo(err, func_addr, func_end); } return err; }
lldb_private::Error ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, lldb::addr_t &func_end, lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx, bool &can_interpret, ExecutionPolicy execution_policy) { func_addr = LLDB_INVALID_ADDRESS; func_end = LLDB_INVALID_ADDRESS; Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); lldb_private::Error err; std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule()); if (!llvm_module_ap.get()) { err.SetErrorToGenericError(); err.SetErrorString("IR doesn't contain a module"); return err; } ConstString function_name; if (execution_policy != eExecutionPolicyTopLevel) { // Find the actual name of the function (it's often mangled somehow) if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName())) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName()); return err; } else { 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; } LLVMUserExpression::IRPasses custom_passes; { auto lang = m_expr.Language(); if (log) log->Printf("%s - Currrent expression language is %s\n", __FUNCTION__, Language::GetNameForLanguageType(lang)); if (lang != lldb::eLanguageTypeUnknown) { auto runtime = exe_ctx.GetProcessSP()->GetLanguageRuntime(lang); if (runtime) runtime->GetIRPasses(custom_passes); } } if (custom_passes.EarlyPasses) { if (log) log->Printf("%s - Running Early IR Passes from LanguageRuntime on expression module '%s'", __FUNCTION__, m_expr.FunctionName()); custom_passes.EarlyPasses->run(*llvm_module_ap); } 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()); ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); // result can be NULL if (decl_map) { Stream *error_stream = NULL; Target *target = exe_ctx.GetTargetPtr(); if (target) error_stream = target->GetDebugger().GetErrorFile().get(); IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), *execution_unit_sp, error_stream, function_name.AsCString()); bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule()); Process *process = exe_ctx.GetProcessPtr(); if (execution_policy != eExecutionPolicyAlways && execution_policy != eExecutionPolicyTopLevel) { lldb_private::Error interpret_error; bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls(); can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error, interpret_function_calls); if (!can_interpret && execution_policy == eExecutionPolicyNever) { err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString()); return err; } } if (!ir_can_run) { err.SetErrorString("The expression could not be prepared to run in the target"); return err; } if (!process && execution_policy == eExecutionPolicyAlways) { err.SetErrorString("Expression needed to run in the target, but the target can't be run"); return err; } if (!process && execution_policy == eExecutionPolicyTopLevel) { err.SetErrorString( "Top-level code needs to be inserted into a runnable target, but the target can't be run"); return err; } if (execution_policy == eExecutionPolicyAlways || (execution_policy != eExecutionPolicyTopLevel && !can_interpret)) { if (m_expr.NeedsValidation() && process) { if (!process->GetDynamicCheckers()) { DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions(); DiagnosticManager install_diagnostics; if (!dynamic_checkers->Install(install_diagnostics, exe_ctx)) { if (install_diagnostics.Diagnostics().size()) err.SetErrorString("couldn't install checkers, unknown error"); else err.SetErrorString(install_diagnostics.GetString().c_str()); return err; } process->SetDynamicCheckers(dynamic_checkers); if (log) log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers =="); } IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString()); llvm::Module *module = execution_unit_sp->GetModule(); if (!module || !ir_dynamic_checks.runOnModule(*module)) { err.SetErrorToGenericError(); err.SetErrorString("Couldn't add dynamic checks to the expression"); return err; } if (custom_passes.LatePasses) { if (log) log->Printf("%s - Running Late IR Passes from LanguageRuntime on expression module '%s'", __FUNCTION__, m_expr.FunctionName()); custom_passes.LatePasses->run(*module); } } } if (execution_policy == eExecutionPolicyAlways || execution_policy == eExecutionPolicyTopLevel || !can_interpret) { execution_unit_sp->GetRunnableInfo(err, func_addr, func_end); } } else { execution_unit_sp->GetRunnableInfo(err, func_addr, func_end); } return err; }
Error ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, lldb::addr_t &func_addr, lldb::addr_t &func_end, ExecutionContext &exe_ctx, IRForTarget::StaticDataAllocator *data_allocator, bool &evaluated_statically, lldb::ClangExpressionVariableSP &const_result, ExecutionPolicy execution_policy) { func_allocation_addr = LLDB_INVALID_ADDRESS; func_addr = LLDB_INVALID_ADDRESS; func_end = LLDB_INVALID_ADDRESS; lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); std::auto_ptr<llvm::ExecutionEngine> execution_engine; Error err; llvm::Module *module = m_code_generator->ReleaseModule(); if (!module) { err.SetErrorToGenericError(); err.SetErrorString("IR doesn't contain a module"); return err; } // Find the actual name of the function (it's often mangled somehow) std::string function_name; if (!FindFunctionInModule(function_name, module, m_expr.FunctionName())) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName()); return err; } else { if (log) log->Printf("Found function %s for %s", function_name.c_str(), m_expr.FunctionName()); } ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL if (decl_map) { Stream *error_stream = NULL; Target *target = exe_ctx.GetTargetPtr(); if (target) error_stream = &target->GetDebugger().GetErrorStream(); IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), execution_policy, const_result, data_allocator, error_stream, function_name.c_str()); ir_for_target.runOnModule(*module); Error &interpreter_error(ir_for_target.getInterpreterError()); if (execution_policy != eExecutionPolicyAlways && interpreter_error.Success()) { if (const_result) const_result->TransferAddress(); evaluated_statically = true; err.Clear(); return err; } Process *process = exe_ctx.GetProcessPtr(); if (!process || execution_policy == eExecutionPolicyNever) { err.SetErrorToGenericError(); if (execution_policy == eExecutionPolicyAlways) err.SetErrorString("Execution needed to run in the target, but the target can't be run"); else err.SetErrorStringWithFormat("Interpreting the expression locally failed: %s", interpreter_error.AsCString()); return err; } if (execution_policy != eExecutionPolicyNever && m_expr.NeedsValidation() && process) { if (!process->GetDynamicCheckers()) { DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions(); StreamString install_errors; if (!dynamic_checkers->Install(install_errors, exe_ctx)) { if (install_errors.GetString().empty()) err.SetErrorString ("couldn't install checkers, unknown error"); else err.SetErrorString (install_errors.GetString().c_str()); return err; } process->SetDynamicCheckers(dynamic_checkers); if (log) log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers =="); } IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.c_str()); if (!ir_dynamic_checks.runOnModule(*module)) { err.SetErrorToGenericError(); err.SetErrorString("Couldn't add dynamic checks to the expression"); return err; } } } // llvm will own this pointer when llvm::ExecutionEngine::createJIT is called // below so we don't need to free it. RecordingMemoryManager *jit_memory_manager = new RecordingMemoryManager(); std::string error_string; if (log) { std::string s; raw_string_ostream oss(s); module->print(oss, NULL); oss.flush(); log->Printf ("Module being sent to JIT: \n%s", s.c_str()); } EngineBuilder builder(module); builder.setEngineKind(EngineKind::JIT) .setErrorStr(&error_string) .setRelocationModel(llvm::Reloc::PIC_) .setJITMemoryManager(jit_memory_manager) .setOptLevel(CodeGenOpt::Less) .setAllocateGVsWithCode(true) .setCodeModel(CodeModel::Small) .setUseMCJIT(true); execution_engine.reset(builder.create()); if (!execution_engine.get()) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str()); return err; } execution_engine->DisableLazyCompilation(); llvm::Function *function = module->getFunction (function_name.c_str()); // We don't actually need the function pointer here, this just forces it to get resolved. void *fun_ptr = execution_engine->getPointerToFunction(function); // Errors usually cause failures in the JIT, but if we're lucky we get here. if (!function) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", function_name.c_str()); return err; } if (!fun_ptr) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", function_name.c_str()); return err; } m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(function_name.c_str(), (lldb::addr_t)fun_ptr)); Process *process = exe_ctx.GetProcessPtr(); if (process == NULL) { err.SetErrorToGenericError(); err.SetErrorString("Couldn't write the JIT compiled code into the target because there is no target"); return err; } jit_memory_manager->CommitAllocations(*process); jit_memory_manager->ReportAllocations(*execution_engine); jit_memory_manager->WriteData(*process); std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end(); for (pos = m_jitted_functions.begin(); pos != end; pos++) { (*pos).m_remote_addr = jit_memory_manager->GetRemoteAddressForLocal ((*pos).m_local_addr); if (!(*pos).m_name.compare(function_name.c_str())) { RecordingMemoryManager::AddrRange func_range = jit_memory_manager->GetRemoteRangeForLocal((*pos).m_local_addr); func_end = func_range.first + func_range.second; func_addr = (*pos).m_remote_addr; } } if (log) { log->Printf("Code can be run in the target."); StreamString disassembly_stream; Error err = DisassembleFunction(disassembly_stream, exe_ctx, jit_memory_manager); if (!err.Success()) { log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error")); } else { log->Printf("Function disassembly:\n%s", disassembly_stream.GetData()); } } execution_engine.reset(); err.Clear(); return err; }
Error ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, lldb::addr_t &func_addr, lldb::addr_t &func_end, ExecutionContext &exe_ctx, IRForTarget::StaticDataAllocator *data_allocator, bool &evaluated_statically, lldb::ClangExpressionVariableSP &const_result, ExecutionPolicy execution_policy) { func_allocation_addr = LLDB_INVALID_ADDRESS; func_addr = LLDB_INVALID_ADDRESS; func_end = LLDB_INVALID_ADDRESS; lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); Error err; llvm::Module *module = m_code_generator->ReleaseModule(); if (!module) { err.SetErrorToGenericError(); err.SetErrorString("IR doesn't contain a module"); return err; } // Find the actual name of the function (it's often mangled somehow) std::string function_name; if (!FindFunctionInModule(function_name, module, m_expr.FunctionName())) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName()); return err; } else { if (log) log->Printf("Found function %s for %s", function_name.c_str(), m_expr.FunctionName()); } ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL if (decl_map) { Stream *error_stream = NULL; Target *target = exe_ctx.GetTargetPtr(); if (target) error_stream = &target->GetDebugger().GetErrorStream(); IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), execution_policy, const_result, data_allocator, error_stream, function_name.c_str()); if (!ir_for_target.runOnModule(*module)) { err.SetErrorToGenericError(); err.SetErrorString("Couldn't prepare the expression for execution in the target"); return err; } if (execution_policy != eExecutionPolicyAlways && ir_for_target.interpretSuccess()) { evaluated_statically = true; err.Clear(); return err; } Process *process = exe_ctx.GetProcessPtr(); if (!process || execution_policy == eExecutionPolicyNever) { err.SetErrorToGenericError(); err.SetErrorString("Execution needed to run in the target, but the target can't be run"); return err; } if (execution_policy != eExecutionPolicyNever && m_expr.NeedsValidation() && process) { if (!process->GetDynamicCheckers()) { DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions(); StreamString install_errors; if (!dynamic_checkers->Install(install_errors, exe_ctx)) { if (install_errors.GetString().empty()) err.SetErrorString ("couldn't install checkers, unknown error"); else err.SetErrorString (install_errors.GetString().c_str()); return err; } process->SetDynamicCheckers(dynamic_checkers); if (log) log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers =="); } IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.c_str()); if (!ir_dynamic_checks.runOnModule(*module)) { err.SetErrorToGenericError(); err.SetErrorString("Couldn't add dynamic checks to the expression"); return err; } } } // llvm will own this pointer when llvm::ExecutionEngine::createJIT is called // below so we don't need to free it. RecordingMemoryManager *jit_memory_manager = new RecordingMemoryManager(); std::string error_string; if (log) { std::string s; raw_string_ostream oss(s); module->print(oss, NULL); oss.flush(); log->Printf ("Module being sent to JIT: \n%s", s.c_str()); } #if defined (USE_STANDARD_JIT) m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, &error_string, jit_memory_manager, CodeGenOpt::Less, true, Reloc::Default, CodeModel::Small)); #else EngineBuilder builder(module); builder.setEngineKind(EngineKind::JIT) .setErrorStr(&error_string) .setRelocationModel(llvm::Reloc::PIC_) .setJITMemoryManager(jit_memory_manager) .setOptLevel(CodeGenOpt::Less) .setAllocateGVsWithCode(true) .setCodeModel(CodeModel::Small) .setUseMCJIT(true); m_execution_engine.reset(builder.create()); #endif if (!m_execution_engine.get()) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str()); return err; } m_execution_engine->DisableLazyCompilation(); llvm::Function *function = module->getFunction (function_name.c_str()); // We don't actually need the function pointer here, this just forces it to get resolved. void *fun_ptr = m_execution_engine->getPointerToFunction(function); // Errors usually cause failures in the JIT, but if we're lucky we get here. if (!function) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", function_name.c_str()); return err; } if (!fun_ptr) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", function_name.c_str()); return err; } m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(function_name.c_str(), (lldb::addr_t)fun_ptr)); Process *process = exe_ctx.GetProcessPtr(); if (process == NULL) { err.SetErrorToGenericError(); err.SetErrorString("Couldn't write the JIT compiled code into the target because there is no target"); return err; } // Look over the regions allocated for the function compiled. The JIT // tries to allocate the functions & stubs close together, so we should try to // write them that way too... // For now I only write functions with no stubs, globals, exception tables, // etc. So I only need to write the functions. size_t alloc_size = 0; std::map<uint8_t *, uint8_t *>::iterator fun_pos = jit_memory_manager->m_functions.begin(); std::map<uint8_t *, uint8_t *>::iterator fun_end = jit_memory_manager->m_functions.end(); for (; fun_pos != fun_end; ++fun_pos) { size_t mem_size = fun_pos->second - fun_pos->first; if (log) log->Printf ("JIT memory: [%p - %p) size = %zu", fun_pos->first, fun_pos->second, mem_size); alloc_size += mem_size; } Error alloc_error; func_allocation_addr = process->AllocateMemory (alloc_size, lldb::ePermissionsReadable|lldb::ePermissionsExecutable, alloc_error); if (func_allocation_addr == LLDB_INVALID_ADDRESS) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't allocate memory for the JITted function: %s", alloc_error.AsCString("unknown error")); return err; } lldb::addr_t cursor = func_allocation_addr; for (fun_pos = jit_memory_manager->m_functions.begin(); fun_pos != fun_end; fun_pos++) { lldb::addr_t lstart = (lldb::addr_t) (*fun_pos).first; lldb::addr_t lend = (lldb::addr_t) (*fun_pos).second; size_t size = lend - lstart; Error write_error; if (process->WriteMemory(cursor, (void *) lstart, size, write_error) != size) { err.SetErrorToGenericError(); err.SetErrorStringWithFormat("Couldn't copy JIT code for function into the target: %s", write_error.AsCString("unknown error")); return err; } jit_memory_manager->AddToLocalToRemoteMap (lstart, size, cursor); cursor += size; } std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end(); for (pos = m_jitted_functions.begin(); pos != end; pos++) { (*pos).m_remote_addr = jit_memory_manager->GetRemoteAddressForLocal ((*pos).m_local_addr); if (!(*pos).m_name.compare(function_name.c_str())) { func_end = jit_memory_manager->GetRemoteRangeForLocal ((*pos).m_local_addr).second; func_addr = (*pos).m_remote_addr; } } if (log) { log->Printf("Code can be run in the target."); StreamString disassembly_stream; Error err = DisassembleFunction(disassembly_stream, exe_ctx, jit_memory_manager); if (!err.Success()) { log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error")); } else { log->Printf("Function disassembly:\n%s", disassembly_stream.GetData()); } } err.Clear(); return err; }