1c156427dSZachary Turner //===-- ThreadPlanCallUserExpression.cpp -------------------------*- C++-*-===// 2f48169bbSJim Ingham // 3f48169bbSJim Ingham // The LLVM Compiler Infrastructure 4f48169bbSJim Ingham // 5f48169bbSJim Ingham // This file is distributed under the University of Illinois Open Source 6f48169bbSJim Ingham // License. See LICENSE.TXT for details. 7f48169bbSJim Ingham // 8f48169bbSJim Ingham //===----------------------------------------------------------------------===// 9f48169bbSJim Ingham 10f48169bbSJim Ingham #include "lldb/Target/ThreadPlanCallUserExpression.h" 11f48169bbSJim Ingham 12f48169bbSJim Ingham // C Includes 13f48169bbSJim Ingham // C++ Includes 14f48169bbSJim Ingham // Other libraries and framework includes 1546d005dbSJim Ingham 16f48169bbSJim Ingham // Project includes 17f48169bbSJim Ingham #include "lldb/Breakpoint/Breakpoint.h" 18f48169bbSJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h" 19f48169bbSJim Ingham #include "lldb/Core/Address.h" 20f48169bbSJim Ingham #include "lldb/Core/Log.h" 21579e70c9SSean Callanan #include "lldb/Expression/DiagnosticManager.h" 2293749ab3SZachary Turner #include "lldb/Expression/IRDynamicChecks.h" 23579e70c9SSean Callanan #include "lldb/Expression/UserExpression.h" 2497a14e60SZachary Turner #include "lldb/Host/HostInfo.h" 25f48169bbSJim Ingham #include "lldb/Target/LanguageRuntime.h" 26f48169bbSJim Ingham #include "lldb/Target/Process.h" 27f48169bbSJim Ingham #include "lldb/Target/RegisterContext.h" 28f48169bbSJim Ingham #include "lldb/Target/StopInfo.h" 29f48169bbSJim Ingham #include "lldb/Target/Target.h" 30f48169bbSJim Ingham #include "lldb/Target/Thread.h" 31f48169bbSJim Ingham #include "lldb/Target/ThreadPlanRunToAddress.h" 32*bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 33f48169bbSJim Ingham 34f48169bbSJim Ingham using namespace lldb; 35f48169bbSJim Ingham using namespace lldb_private; 36f48169bbSJim Ingham 37f48169bbSJim Ingham //---------------------------------------------------------------------- 38f48169bbSJim Ingham // ThreadPlanCallUserExpression: Plan to call a single function 39f48169bbSJim Ingham //---------------------------------------------------------------------- 40f48169bbSJim Ingham 41b9c1b51eSKate Stone ThreadPlanCallUserExpression::ThreadPlanCallUserExpression( 42b9c1b51eSKate Stone Thread &thread, Address &function, llvm::ArrayRef<lldb::addr_t> args, 436fbc48bcSJim Ingham const EvaluateExpressionOptions &options, 44b9c1b51eSKate Stone lldb::UserExpressionSP &user_expression_sp) 45b9c1b51eSKate Stone : ThreadPlanCallFunction(thread, function, CompilerType(), args, options), 46b9c1b51eSKate Stone m_user_expression_sp(user_expression_sp) { 47b9c1b51eSKate Stone // User expressions are generally "User generated" so we should set them up to 48b9c1b51eSKate Stone // stop when done. 49923886ceSJim Ingham SetIsMasterPlan(true); 50923886ceSJim Ingham SetOkayToDiscard(false); 51f48169bbSJim Ingham } 52f48169bbSJim Ingham 53b9c1b51eSKate Stone ThreadPlanCallUserExpression::~ThreadPlanCallUserExpression() {} 54f48169bbSJim Ingham 55b9c1b51eSKate Stone void ThreadPlanCallUserExpression::GetDescription( 56b9c1b51eSKate Stone Stream *s, lldb::DescriptionLevel level) { 5730fadafeSJim Ingham if (level == eDescriptionLevelBrief) 5830fadafeSJim Ingham s->Printf("User Expression thread plan"); 5930fadafeSJim Ingham else 60f48169bbSJim Ingham ThreadPlanCallFunction::GetDescription(s, level); 61ce553d88SJim Ingham } 62ce553d88SJim Ingham 63b9c1b51eSKate Stone void ThreadPlanCallUserExpression::WillPop() { 6430fadafeSJim Ingham ThreadPlanCallFunction::WillPop(); 6530fadafeSJim Ingham if (m_user_expression_sp) 6630fadafeSJim Ingham m_user_expression_sp.reset(); 6730fadafeSJim Ingham } 6830fadafeSJim Ingham 69b9c1b51eSKate Stone bool ThreadPlanCallUserExpression::MischiefManaged() { 7030fadafeSJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); 7130fadafeSJim Ingham 72b9c1b51eSKate Stone if (IsPlanComplete()) { 7330fadafeSJim Ingham if (log) 7430fadafeSJim Ingham log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", 7530fadafeSJim Ingham static_cast<void *>(this)); 7630fadafeSJim Ingham 77b9c1b51eSKate Stone if (m_manage_materialization && PlanSucceeded() && m_user_expression_sp) { 7830fadafeSJim Ingham lldb::addr_t function_stack_top; 7930fadafeSJim Ingham lldb::addr_t function_stack_bottom; 8030fadafeSJim Ingham lldb::addr_t function_stack_pointer = GetFunctionStackPointer(); 8130fadafeSJim Ingham 8297a14e60SZachary Turner function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); 8330fadafeSJim Ingham function_stack_top = function_stack_pointer; 8430fadafeSJim Ingham 85579e70c9SSean Callanan DiagnosticManager diagnostics; 8630fadafeSJim Ingham 8730fadafeSJim Ingham ExecutionContext exe_ctx(GetThread()); 8830fadafeSJim Ingham 89b9c1b51eSKate Stone m_user_expression_sp->FinalizeJITExecution( 90b9c1b51eSKate Stone diagnostics, exe_ctx, m_result_var_sp, function_stack_bottom, 91579e70c9SSean Callanan function_stack_top); 9230fadafeSJim Ingham } 9330fadafeSJim Ingham 9430fadafeSJim Ingham ThreadPlan::MischiefManaged(); 9530fadafeSJim Ingham return true; 96b9c1b51eSKate Stone } else { 9730fadafeSJim Ingham return false; 9830fadafeSJim Ingham } 9930fadafeSJim Ingham } 10030fadafeSJim Ingham 101b9c1b51eSKate Stone StopInfoSP ThreadPlanCallUserExpression::GetRealStopInfo() { 102ce553d88SJim Ingham StopInfoSP stop_info_sp = ThreadPlanCallFunction::GetRealStopInfo(); 10360c4118cSJim Ingham 104b9c1b51eSKate Stone if (stop_info_sp) { 105ce553d88SJim Ingham lldb::addr_t addr = GetStopAddress(); 106b9c1b51eSKate Stone DynamicCheckerFunctions *checkers = 107b9c1b51eSKate Stone m_thread.GetProcess()->GetDynamicCheckers(); 108ce553d88SJim Ingham StreamString s; 109ce553d88SJim Ingham 110ce553d88SJim Ingham if (checkers && checkers->DoCheckersExplainStop(addr, s)) 111ce553d88SJim Ingham stop_info_sp->SetDescription(s.GetData()); 11260c4118cSJim Ingham } 113ce553d88SJim Ingham 114ce553d88SJim Ingham return stop_info_sp; 115f48169bbSJim Ingham } 116