1*b9c1b51eSKate Stone //===-- ThreadPlanCallUserExpression.cpp ------------------------------*- C++ 2*b9c1b51eSKate Stone //-*-===// 3f48169bbSJim Ingham // 4f48169bbSJim Ingham // The LLVM Compiler Infrastructure 5f48169bbSJim Ingham // 6f48169bbSJim Ingham // This file is distributed under the University of Illinois Open Source 7f48169bbSJim Ingham // License. See LICENSE.TXT for details. 8f48169bbSJim Ingham // 9f48169bbSJim Ingham //===----------------------------------------------------------------------===// 10f48169bbSJim Ingham 11f48169bbSJim Ingham #include "lldb/Target/ThreadPlanCallUserExpression.h" 12f48169bbSJim Ingham 13f48169bbSJim Ingham // C Includes 14f48169bbSJim Ingham // C++ Includes 15f48169bbSJim Ingham // Other libraries and framework includes 1646d005dbSJim Ingham 17f48169bbSJim Ingham // Project includes 18f48169bbSJim Ingham #include "lldb/Breakpoint/Breakpoint.h" 19f48169bbSJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h" 20f48169bbSJim Ingham #include "lldb/Core/Address.h" 21f48169bbSJim Ingham #include "lldb/Core/Log.h" 22f48169bbSJim Ingham #include "lldb/Core/Stream.h" 23579e70c9SSean Callanan #include "lldb/Expression/DiagnosticManager.h" 2493749ab3SZachary Turner #include "lldb/Expression/IRDynamicChecks.h" 25579e70c9SSean Callanan #include "lldb/Expression/UserExpression.h" 2697a14e60SZachary Turner #include "lldb/Host/HostInfo.h" 27f48169bbSJim Ingham #include "lldb/Target/LanguageRuntime.h" 28f48169bbSJim Ingham #include "lldb/Target/Process.h" 29f48169bbSJim Ingham #include "lldb/Target/RegisterContext.h" 30f48169bbSJim Ingham #include "lldb/Target/StopInfo.h" 31f48169bbSJim Ingham #include "lldb/Target/Target.h" 32f48169bbSJim Ingham #include "lldb/Target/Thread.h" 33f48169bbSJim Ingham #include "lldb/Target/ThreadPlanRunToAddress.h" 34f48169bbSJim Ingham 35f48169bbSJim Ingham using namespace lldb; 36f48169bbSJim Ingham using namespace lldb_private; 37f48169bbSJim Ingham 38f48169bbSJim Ingham //---------------------------------------------------------------------- 39f48169bbSJim Ingham // ThreadPlanCallUserExpression: Plan to call a single function 40f48169bbSJim Ingham //---------------------------------------------------------------------- 41f48169bbSJim Ingham 42*b9c1b51eSKate Stone ThreadPlanCallUserExpression::ThreadPlanCallUserExpression( 43*b9c1b51eSKate Stone Thread &thread, Address &function, llvm::ArrayRef<lldb::addr_t> args, 446fbc48bcSJim Ingham const EvaluateExpressionOptions &options, 45*b9c1b51eSKate Stone lldb::UserExpressionSP &user_expression_sp) 46*b9c1b51eSKate Stone : ThreadPlanCallFunction(thread, function, CompilerType(), args, options), 47*b9c1b51eSKate Stone m_user_expression_sp(user_expression_sp) { 48*b9c1b51eSKate Stone // User expressions are generally "User generated" so we should set them up to 49*b9c1b51eSKate Stone // stop when done. 50923886ceSJim Ingham SetIsMasterPlan(true); 51923886ceSJim Ingham SetOkayToDiscard(false); 52f48169bbSJim Ingham } 53f48169bbSJim Ingham 54*b9c1b51eSKate Stone ThreadPlanCallUserExpression::~ThreadPlanCallUserExpression() {} 55f48169bbSJim Ingham 56*b9c1b51eSKate Stone void ThreadPlanCallUserExpression::GetDescription( 57*b9c1b51eSKate Stone Stream *s, lldb::DescriptionLevel level) { 5830fadafeSJim Ingham if (level == eDescriptionLevelBrief) 5930fadafeSJim Ingham s->Printf("User Expression thread plan"); 6030fadafeSJim Ingham else 61f48169bbSJim Ingham ThreadPlanCallFunction::GetDescription(s, level); 62ce553d88SJim Ingham } 63ce553d88SJim Ingham 64*b9c1b51eSKate Stone void ThreadPlanCallUserExpression::WillPop() { 6530fadafeSJim Ingham ThreadPlanCallFunction::WillPop(); 6630fadafeSJim Ingham if (m_user_expression_sp) 6730fadafeSJim Ingham m_user_expression_sp.reset(); 6830fadafeSJim Ingham } 6930fadafeSJim Ingham 70*b9c1b51eSKate Stone bool ThreadPlanCallUserExpression::MischiefManaged() { 7130fadafeSJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); 7230fadafeSJim Ingham 73*b9c1b51eSKate Stone if (IsPlanComplete()) { 7430fadafeSJim Ingham if (log) 7530fadafeSJim Ingham log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", 7630fadafeSJim Ingham static_cast<void *>(this)); 7730fadafeSJim Ingham 78*b9c1b51eSKate Stone if (m_manage_materialization && PlanSucceeded() && m_user_expression_sp) { 7930fadafeSJim Ingham lldb::addr_t function_stack_top; 8030fadafeSJim Ingham lldb::addr_t function_stack_bottom; 8130fadafeSJim Ingham lldb::addr_t function_stack_pointer = GetFunctionStackPointer(); 8230fadafeSJim Ingham 8397a14e60SZachary Turner function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); 8430fadafeSJim Ingham function_stack_top = function_stack_pointer; 8530fadafeSJim Ingham 86579e70c9SSean Callanan DiagnosticManager diagnostics; 8730fadafeSJim Ingham 8830fadafeSJim Ingham ExecutionContext exe_ctx(GetThread()); 8930fadafeSJim Ingham 90*b9c1b51eSKate Stone m_user_expression_sp->FinalizeJITExecution( 91*b9c1b51eSKate Stone diagnostics, exe_ctx, m_result_var_sp, function_stack_bottom, 92579e70c9SSean Callanan function_stack_top); 9330fadafeSJim Ingham } 9430fadafeSJim Ingham 9530fadafeSJim Ingham ThreadPlan::MischiefManaged(); 9630fadafeSJim Ingham return true; 97*b9c1b51eSKate Stone } else { 9830fadafeSJim Ingham return false; 9930fadafeSJim Ingham } 10030fadafeSJim Ingham } 10130fadafeSJim Ingham 102*b9c1b51eSKate Stone StopInfoSP ThreadPlanCallUserExpression::GetRealStopInfo() { 103ce553d88SJim Ingham StopInfoSP stop_info_sp = ThreadPlanCallFunction::GetRealStopInfo(); 10460c4118cSJim Ingham 105*b9c1b51eSKate Stone if (stop_info_sp) { 106ce553d88SJim Ingham lldb::addr_t addr = GetStopAddress(); 107*b9c1b51eSKate Stone DynamicCheckerFunctions *checkers = 108*b9c1b51eSKate Stone m_thread.GetProcess()->GetDynamicCheckers(); 109ce553d88SJim Ingham StreamString s; 110ce553d88SJim Ingham 111ce553d88SJim Ingham if (checkers && checkers->DoCheckersExplainStop(addr, s)) 112ce553d88SJim Ingham stop_info_sp->SetDescription(s.GetData()); 11360c4118cSJim Ingham } 114ce553d88SJim Ingham 115ce553d88SJim Ingham return stop_info_sp; 116f48169bbSJim Ingham } 117