bool ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx, lldb::TargetSP &target_sp, lldb::ProcessSP &process_sp, lldb::StackFrameSP &frame_sp) { lldb::ProcessSP expected_process_sp = m_process_wp.lock(); process_sp = exe_ctx.GetProcessSP(); if (process_sp != expected_process_sp) return false; process_sp = exe_ctx.GetProcessSP(); target_sp = exe_ctx.GetTargetSP(); frame_sp = exe_ctx.GetFrameSP(); if (m_address.IsValid()) { if (!frame_sp) return false; else return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get())); } return true; }
void UserExpression::InstallContext(ExecutionContext &exe_ctx) { m_jit_process_wp = exe_ctx.GetProcessSP(); lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP(); if (frame_sp) m_address = frame_sp->GetFrameCodeAddress(); }
GoInterpreter(ExecutionContext &exe_ctx, const char *expr) : m_exe_ctx(exe_ctx), m_frame(exe_ctx.GetFrameSP()), m_parser(expr) { if (m_frame) { const SymbolContext &ctx = m_frame->GetSymbolContext(eSymbolContextFunction); ConstString fname = ctx.GetFunctionName(); if (fname.GetLength() > 0) { size_t dot = fname.GetStringRef().find('.'); if (dot != llvm::StringRef::npos) m_package = llvm::StringRef(fname.AsCString(), dot); } } }
bool ClangUserExpression::AddInitialArguments (ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, Stream &error_stream) { lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS; lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS; if (m_needs_object_ptr) { lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP(); if (!frame_sp) return true; ConstString object_name; if (m_in_cplusplus_method) { object_name.SetCString("this"); } else if (m_in_objectivec_method) { object_name.SetCString("self"); } else { error_stream.Printf("Need object pointer but don't know the language\n"); return false; } Error object_ptr_error; object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error); if (!object_ptr_error.Success()) { error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString()); object_ptr = 0; } if (m_in_objectivec_method) { ConstString cmd_name("_cmd"); cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error); if (!object_ptr_error.Success()) { error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString()); cmd_ptr = 0; } } if (object_ptr) args.push_back(object_ptr); if (m_in_objectivec_method) args.push_back(cmd_ptr); } return true; }
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; }
bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager) { lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS; lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS; if (m_needs_object_ptr) { lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP(); if (!frame_sp) return true; ConstString object_name; if (m_in_cplusplus_method) { object_name.SetCString("this"); } else if (m_in_objectivec_method) { object_name.SetCString("self"); } else { diagnostic_manager.PutString( eDiagnosticSeverityError, "need object pointer but don't know the language"); return false; } Status object_ptr_error; object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error); if (!object_ptr_error.Success()) { exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf( "warning: `%s' is not accessible (substituting 0)\n", object_name.AsCString()); object_ptr = 0; } if (m_in_objectivec_method) { ConstString cmd_name("_cmd"); cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error); if (!object_ptr_error.Success()) { diagnostic_manager.Printf( eDiagnosticSeverityWarning, "couldn't get cmd pointer (substituting NULL): %s", object_ptr_error.AsCString()); cmd_ptr = 0; } } args.push_back(object_ptr); if (m_in_objectivec_method) args.push_back(cmd_ptr); args.push_back(struct_address); } else { args.push_back(struct_address); } return true; }