diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp | 571 |
1 files changed, 283 insertions, 288 deletions
diff --git a/contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp b/contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp index 0b96980..c5df781 100644 --- a/contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp @@ -41,341 +41,336 @@ using namespace lldb_private; -LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope, - const char *expr, - const char *expr_prefix, - lldb::LanguageType language, - ResultType desired_type, +LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope, + llvm::StringRef expr, + llvm::StringRef prefix, + lldb::LanguageType language, + ResultType desired_type, const EvaluateExpressionOptions &options) - : UserExpression(exe_scope, expr, expr_prefix, language, desired_type, options), + : UserExpression(exe_scope, expr, prefix, language, desired_type, options), m_stack_frame_bottom(LLDB_INVALID_ADDRESS), - m_stack_frame_top(LLDB_INVALID_ADDRESS), - m_transformed_text(), - m_execution_unit_sp(), - m_materializer_ap(), - m_jit_module_wp(), - m_enforce_valid_object(true), - m_in_cplusplus_method(false), - m_in_objectivec_method(false), - m_in_static_method(false), - m_needs_object_ptr(false), - m_target(NULL), - m_can_interpret(false), - m_materialized_address(LLDB_INVALID_ADDRESS) -{ + m_stack_frame_top(LLDB_INVALID_ADDRESS), m_transformed_text(), + m_execution_unit_sp(), m_materializer_ap(), m_jit_module_wp(), + m_enforce_valid_object(true), m_in_cplusplus_method(false), + m_in_objectivec_method(false), m_in_static_method(false), + m_needs_object_ptr(false), m_target(NULL), m_can_interpret(false), + m_materialized_address(LLDB_INVALID_ADDRESS) {} + +LLVMUserExpression::~LLVMUserExpression() { + if (m_target) { + lldb::ModuleSP jit_module_sp(m_jit_module_wp.lock()); + if (jit_module_sp) + m_target->GetImages().Remove(jit_module_sp); + } } -LLVMUserExpression::~LLVMUserExpression() -{ - if (m_target) - { - lldb::ModuleSP jit_module_sp(m_jit_module_wp.lock()); - if (jit_module_sp) - m_target->GetImages().Remove(jit_module_sp); +lldb::ExpressionResults +LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, + ExecutionContext &exe_ctx, + const EvaluateExpressionOptions &options, + lldb::UserExpressionSP &shared_ptr_to_me, + lldb::ExpressionVariableSP &result) { + // The expression log is quite verbose, and if you're just tracking the + // execution of the + // expression, it's quite convenient to have these logs come out with the STEP + // log as well. + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | + LIBLLDB_LOG_STEP)); + + if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) { + lldb::addr_t struct_address = LLDB_INVALID_ADDRESS; + + if (!PrepareToExecuteJITExpression(diagnostic_manager, exe_ctx, + struct_address)) { + diagnostic_manager.Printf( + eDiagnosticSeverityError, + "errored out in %s, couldn't PrepareToExecuteJITExpression", + __FUNCTION__); + return lldb::eExpressionSetupError; } -} -lldb::ExpressionResults -LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, - const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me, - lldb::ExpressionVariableSP &result) -{ - // The expression log is quite verbose, and if you're just tracking the execution of the - // expression, it's quite convenient to have these logs come out with the STEP log as well. - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); - - if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) - { - lldb::addr_t struct_address = LLDB_INVALID_ADDRESS; - - if (!PrepareToExecuteJITExpression(diagnostic_manager, exe_ctx, struct_address)) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, - "errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__); - return lldb::eExpressionSetupError; - } + lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS; + lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS; - lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS; - lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS; + if (m_can_interpret) { + llvm::Module *module = m_execution_unit_sp->GetModule(); + llvm::Function *function = m_execution_unit_sp->GetFunction(); - if (m_can_interpret) - { - llvm::Module *module = m_execution_unit_sp->GetModule(); - llvm::Function *function = m_execution_unit_sp->GetFunction(); + if (!module || !function) { + diagnostic_manager.PutString( + eDiagnosticSeverityError, + "supposed to interpret, but nothing is there"); + return lldb::eExpressionSetupError; + } - if (!module || !function) - { - diagnostic_manager.PutCString(eDiagnosticSeverityError, "supposed to interpret, but nothing is there"); - return lldb::eExpressionSetupError; - } + Error interpreter_error; - Error interpreter_error; + std::vector<lldb::addr_t> args; - std::vector<lldb::addr_t> args; + if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "errored out in %s, couldn't AddArguments", + __FUNCTION__); + return lldb::eExpressionSetupError; + } - if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, "errored out in %s, couldn't AddArguments", - __FUNCTION__); - return lldb::eExpressionSetupError; - } + function_stack_bottom = m_stack_frame_bottom; + function_stack_top = m_stack_frame_top; - function_stack_bottom = m_stack_frame_bottom; - function_stack_top = m_stack_frame_top; + IRInterpreter::Interpret(*module, *function, args, + *m_execution_unit_sp.get(), interpreter_error, + function_stack_bottom, function_stack_top, + exe_ctx); - IRInterpreter::Interpret(*module, *function, args, *m_execution_unit_sp.get(), interpreter_error, - function_stack_bottom, function_stack_top, exe_ctx); + if (!interpreter_error.Success()) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "supposed to interpret, but failed: %s", + interpreter_error.AsCString()); + return lldb::eExpressionDiscarded; + } + } else { + if (!exe_ctx.HasThreadScope()) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "%s called with no thread selected", + __FUNCTION__); + return lldb::eExpressionSetupError; + } - if (!interpreter_error.Success()) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, "supposed to interpret, but failed: %s", - interpreter_error.AsCString()); - return lldb::eExpressionDiscarded; - } - } - else - { - if (!exe_ctx.HasThreadScope()) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, "%s called with no thread selected", __FUNCTION__); - return lldb::eExpressionSetupError; - } - - Address wrapper_address(m_jit_start_addr); - - std::vector<lldb::addr_t> args; - - if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, "errored out in %s, couldn't AddArguments", - __FUNCTION__); - return lldb::eExpressionSetupError; - } - - lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression(exe_ctx.GetThreadRef(), wrapper_address, - args, options, shared_ptr_to_me)); - - StreamString ss; - if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) - { - diagnostic_manager.PutCString(eDiagnosticSeverityError, ss.GetData()); - return lldb::eExpressionSetupError; - } - - ThreadPlanCallUserExpression *user_expression_plan = - static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get()); - - lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer(); - - function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); - function_stack_top = function_stack_pointer; - - if (log) - log->Printf("-- [UserExpression::Execute] Execution of expression begins --"); - - if (exe_ctx.GetProcessPtr()) - exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); - - lldb::ExpressionResults execution_result = - exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostic_manager); - - if (exe_ctx.GetProcessPtr()) - exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); - - if (log) - log->Printf("-- [UserExpression::Execute] Execution of expression completed --"); - - if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint) - { - const char *error_desc = NULL; - - if (call_plan_sp) - { - lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo(); - if (real_stop_info_sp) - error_desc = real_stop_info_sp->GetDescription(); - } - if (error_desc) - diagnostic_manager.Printf(eDiagnosticSeverityError, "Execution was interrupted, reason: %s.", - error_desc); - else - diagnostic_manager.PutCString(eDiagnosticSeverityError, "Execution was interrupted."); - - if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError()) || - (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints())) - diagnostic_manager.AppendMessageToDiagnostic( - "The process has been returned to the state before expression evaluation."); - else - { - if (execution_result == lldb::eExpressionHitBreakpoint) - user_expression_plan->TransferExpressionOwnership(); - diagnostic_manager.AppendMessageToDiagnostic( - "The process has been left at the point where it was interrupted, " - "use \"thread return -x\" to return to the state before expression evaluation."); - } - - return execution_result; - } - else if (execution_result == lldb::eExpressionStoppedForDebug) - { - diagnostic_manager.PutCString( - eDiagnosticSeverityRemark, - "Execution was halted at the first instruction of the expression " - "function because \"debug\" was requested.\n" - "Use \"thread return -x\" to return to the state before expression evaluation."); - return execution_result; - } - else if (execution_result != lldb::eExpressionCompleted) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't execute function; result was %s", - Process::ExecutionResultAsCString(execution_result)); - return execution_result; - } - } + Address wrapper_address(m_jit_start_addr); + + std::vector<lldb::addr_t> args; + + if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "errored out in %s, couldn't AddArguments", + __FUNCTION__); + return lldb::eExpressionSetupError; + } + + lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression( + exe_ctx.GetThreadRef(), wrapper_address, args, options, + shared_ptr_to_me)); + + StreamString ss; + if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) { + diagnostic_manager.PutString(eDiagnosticSeverityError, ss.GetString()); + return lldb::eExpressionSetupError; + } + + ThreadPlanCallUserExpression *user_expression_plan = + static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get()); + + lldb::addr_t function_stack_pointer = + user_expression_plan->GetFunctionStackPointer(); - if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result, function_stack_bottom, function_stack_top)) - { - return lldb::eExpressionCompleted; + function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); + function_stack_top = function_stack_pointer; + + if (log) + log->Printf( + "-- [UserExpression::Execute] Execution of expression begins --"); + + if (exe_ctx.GetProcessPtr()) + exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); + + lldb::ExpressionResults execution_result = + exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, + diagnostic_manager); + + if (exe_ctx.GetProcessPtr()) + exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); + + if (log) + log->Printf("-- [UserExpression::Execute] Execution of expression " + "completed --"); + + if (execution_result == lldb::eExpressionInterrupted || + execution_result == lldb::eExpressionHitBreakpoint) { + const char *error_desc = NULL; + + if (call_plan_sp) { + lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo(); + if (real_stop_info_sp) + error_desc = real_stop_info_sp->GetDescription(); } + if (error_desc) + diagnostic_manager.Printf(eDiagnosticSeverityError, + "Execution was interrupted, reason: %s.", + error_desc); else - { - return lldb::eExpressionResultUnavailable; + diagnostic_manager.PutString(eDiagnosticSeverityError, + "Execution was interrupted."); + + if ((execution_result == lldb::eExpressionInterrupted && + options.DoesUnwindOnError()) || + (execution_result == lldb::eExpressionHitBreakpoint && + options.DoesIgnoreBreakpoints())) + diagnostic_manager.AppendMessageToDiagnostic( + "The process has been returned to the state before expression " + "evaluation."); + else { + if (execution_result == lldb::eExpressionHitBreakpoint) + user_expression_plan->TransferExpressionOwnership(); + diagnostic_manager.AppendMessageToDiagnostic( + "The process has been left at the point where it was " + "interrupted, " + "use \"thread return -x\" to return to the state before " + "expression evaluation."); } + + return execution_result; + } else if (execution_result == lldb::eExpressionStoppedForDebug) { + diagnostic_manager.PutString( + eDiagnosticSeverityRemark, + "Execution was halted at the first instruction of the expression " + "function because \"debug\" was requested.\n" + "Use \"thread return -x\" to return to the state before expression " + "evaluation."); + return execution_result; + } else if (execution_result != lldb::eExpressionCompleted) { + diagnostic_manager.Printf( + eDiagnosticSeverityError, + "Couldn't execute function; result was %s", + Process::ExecutionResultAsCString(execution_result)); + return execution_result; + } } - else - { - diagnostic_manager.PutCString(eDiagnosticSeverityError, - "Expression can't be run, because there is no JIT compiled function"); - return lldb::eExpressionSetupError; + + if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result, + function_stack_bottom, function_stack_top)) { + return lldb::eExpressionCompleted; + } else { + return lldb::eExpressionResultUnavailable; } + } else { + diagnostic_manager.PutString( + eDiagnosticSeverityError, + "Expression can't be run, because there is no JIT compiled function"); + return lldb::eExpressionSetupError; + } } -bool -LLVMUserExpression::FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, - lldb::ExpressionVariableSP &result, lldb::addr_t function_stack_bottom, - lldb::addr_t function_stack_top) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); +bool LLVMUserExpression::FinalizeJITExecution( + DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, + lldb::ExpressionVariableSP &result, lldb::addr_t function_stack_bottom, + lldb::addr_t function_stack_top) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - if (log) - log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing after execution --"); + if (log) + log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing " + "after execution --"); - if (!m_dematerializer_sp) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, - "Couldn't apply expression side effects : no dematerializer is present"); - return false; - } + if (!m_dematerializer_sp) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "Couldn't apply expression side effects : no " + "dematerializer is present"); + return false; + } - Error dematerialize_error; + Error dematerialize_error; - m_dematerializer_sp->Dematerialize(dematerialize_error, function_stack_bottom, function_stack_top); + m_dematerializer_sp->Dematerialize(dematerialize_error, function_stack_bottom, + function_stack_top); - if (!dematerialize_error.Success()) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't apply expression side effects : %s", - dematerialize_error.AsCString("unknown error")); - return false; - } + if (!dematerialize_error.Success()) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "Couldn't apply expression side effects : %s", + dematerialize_error.AsCString("unknown error")); + return false; + } - result = GetResultAfterDematerialization(exe_ctx.GetBestExecutionContextScope()); + result = + GetResultAfterDematerialization(exe_ctx.GetBestExecutionContextScope()); - if (result) - result->TransferAddress(); + if (result) + result->TransferAddress(); - m_dematerializer_sp.reset(); + m_dematerializer_sp.reset(); - return true; + return true; } -bool -LLVMUserExpression::PrepareToExecuteJITExpression(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, - lldb::addr_t &struct_address) -{ - lldb::TargetSP target; - lldb::ProcessSP process; - lldb::StackFrameSP frame; - - if (!LockAndCheckContext(exe_ctx, target, process, frame)) - { - diagnostic_manager.PutCString(eDiagnosticSeverityError, - "The context has changed before we could JIT the expression!"); +bool LLVMUserExpression::PrepareToExecuteJITExpression( + DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, + lldb::addr_t &struct_address) { + lldb::TargetSP target; + lldb::ProcessSP process; + lldb::StackFrameSP frame; + + if (!LockAndCheckContext(exe_ctx, target, process, frame)) { + diagnostic_manager.PutString( + eDiagnosticSeverityError, + "The context has changed before we could JIT the expression!"); + return false; + } + + if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) { + if (m_materialized_address == LLDB_INVALID_ADDRESS) { + Error alloc_error; + + IRMemoryMap::AllocationPolicy policy = + m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly + : IRMemoryMap::eAllocationPolicyMirror; + + const bool zero_memory = false; + + m_materialized_address = m_execution_unit_sp->Malloc( + m_materializer_ap->GetStructByteSize(), + m_materializer_ap->GetStructAlignment(), + lldb::ePermissionsReadable | lldb::ePermissionsWritable, policy, + zero_memory, alloc_error); + + if (!alloc_error.Success()) { + diagnostic_manager.Printf( + eDiagnosticSeverityError, + "Couldn't allocate space for materialized struct: %s", + alloc_error.AsCString()); return false; + } } - if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) - { - if (m_materialized_address == LLDB_INVALID_ADDRESS) - { - Error alloc_error; - - IRMemoryMap::AllocationPolicy policy = - m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror; - - const bool zero_memory = false; - - m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(), - m_materializer_ap->GetStructAlignment(), - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - policy, - zero_memory, - alloc_error); - - if (!alloc_error.Success()) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, - "Couldn't allocate space for materialized struct: %s", - alloc_error.AsCString()); - return false; - } - } - - struct_address = m_materialized_address; + struct_address = m_materialized_address; - if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) - { - Error alloc_error; + if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) { + Error alloc_error; - const size_t stack_frame_size = 512 * 1024; + const size_t stack_frame_size = 512 * 1024; - const bool zero_memory = false; + const bool zero_memory = false; - m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size, - 8, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - IRMemoryMap::eAllocationPolicyHostOnly, - zero_memory, - alloc_error); + m_stack_frame_bottom = m_execution_unit_sp->Malloc( + stack_frame_size, 8, + lldb::ePermissionsReadable | lldb::ePermissionsWritable, + IRMemoryMap::eAllocationPolicyHostOnly, zero_memory, alloc_error); - m_stack_frame_top = m_stack_frame_bottom + stack_frame_size; + m_stack_frame_top = m_stack_frame_bottom + stack_frame_size; - if (!alloc_error.Success()) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't allocate space for the stack frame: %s", - alloc_error.AsCString()); - return false; - } - } + if (!alloc_error.Success()) { + diagnostic_manager.Printf( + eDiagnosticSeverityError, + "Couldn't allocate space for the stack frame: %s", + alloc_error.AsCString()); + return false; + } + } - Error materialize_error; + Error materialize_error; - m_dematerializer_sp = - m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error); + m_dematerializer_sp = m_materializer_ap->Materialize( + frame, *m_execution_unit_sp, struct_address, materialize_error); - if (!materialize_error.Success()) - { - diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't materialize: %s", - materialize_error.AsCString()); - return false; - } + if (!materialize_error.Success()) { + diagnostic_manager.Printf(eDiagnosticSeverityError, + "Couldn't materialize: %s", + materialize_error.AsCString()); + return false; } - return true; + } + return true; } -lldb::ModuleSP -LLVMUserExpression::GetJITModule() -{ - if (m_execution_unit_sp) - return m_execution_unit_sp->GetJITModule(); - return lldb::ModuleSP(); +lldb::ModuleSP LLVMUserExpression::GetJITModule() { + if (m_execution_unit_sp) + return m_execution_unit_sp->GetJITModule(); + return lldb::ModuleSP(); } |