1cfca06d7SDimitry Andric //===-- ThreadPlanCallUserExpression.cpp ----------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "lldb/Target/ThreadPlanCallUserExpression.h"
10f034231aSEd Maste
11f034231aSEd Maste #include "lldb/Breakpoint/Breakpoint.h"
12f034231aSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
13f034231aSEd Maste #include "lldb/Core/Address.h"
14f3fbd1c0SDimitry Andric #include "lldb/Expression/DiagnosticManager.h"
155f29bb8aSDimitry Andric #include "lldb/Expression/DynamicCheckerFunctions.h"
16f3fbd1c0SDimitry Andric #include "lldb/Expression/UserExpression.h"
170cac4ca3SEd Maste #include "lldb/Host/HostInfo.h"
18f034231aSEd Maste #include "lldb/Target/LanguageRuntime.h"
19f034231aSEd Maste #include "lldb/Target/Process.h"
20f034231aSEd Maste #include "lldb/Target/RegisterContext.h"
21f034231aSEd Maste #include "lldb/Target/StopInfo.h"
22f034231aSEd Maste #include "lldb/Target/Target.h"
23f034231aSEd Maste #include "lldb/Target/Thread.h"
24f034231aSEd Maste #include "lldb/Target/ThreadPlanRunToAddress.h"
25145449b1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
2674a628f7SDimitry Andric #include "lldb/Utility/Log.h"
2774a628f7SDimitry Andric #include "lldb/Utility/Stream.h"
28f034231aSEd Maste
29f034231aSEd Maste using namespace lldb;
30f034231aSEd Maste using namespace lldb_private;
31f034231aSEd Maste
32f034231aSEd Maste // ThreadPlanCallUserExpression: Plan to call a single function
33f034231aSEd Maste
ThreadPlanCallUserExpression(Thread & thread,Address & function,llvm::ArrayRef<lldb::addr_t> args,const EvaluateExpressionOptions & options,lldb::UserExpressionSP & user_expression_sp)3414f1b3e8SDimitry Andric ThreadPlanCallUserExpression::ThreadPlanCallUserExpression(
3514f1b3e8SDimitry Andric Thread &thread, Address &function, llvm::ArrayRef<lldb::addr_t> args,
3686758c71SEd Maste const EvaluateExpressionOptions &options,
3714f1b3e8SDimitry Andric lldb::UserExpressionSP &user_expression_sp)
3814f1b3e8SDimitry Andric : ThreadPlanCallFunction(thread, function, CompilerType(), args, options),
3914f1b3e8SDimitry Andric m_user_expression_sp(user_expression_sp) {
40f73363f1SDimitry Andric // User expressions are generally "User generated" so we should set them up
41f73363f1SDimitry Andric // to stop when done.
42c0981da4SDimitry Andric SetIsControllingPlan(true);
43f034231aSEd Maste SetOkayToDiscard(false);
44f034231aSEd Maste }
45f034231aSEd Maste
46344a3780SDimitry Andric ThreadPlanCallUserExpression::~ThreadPlanCallUserExpression() = default;
47f034231aSEd Maste
GetDescription(Stream * s,lldb::DescriptionLevel level)4814f1b3e8SDimitry Andric void ThreadPlanCallUserExpression::GetDescription(
4914f1b3e8SDimitry Andric Stream *s, lldb::DescriptionLevel level) {
500cac4ca3SEd Maste if (level == eDescriptionLevelBrief)
510cac4ca3SEd Maste s->Printf("User Expression thread plan");
520cac4ca3SEd Maste else
53f034231aSEd Maste ThreadPlanCallFunction::GetDescription(s, level);
54f034231aSEd Maste }
55f034231aSEd Maste
DidPush()568b4000f1SDimitry Andric void ThreadPlanCallUserExpression::DidPush() {
578b4000f1SDimitry Andric ThreadPlanCallFunction::DidPush();
588b4000f1SDimitry Andric if (m_user_expression_sp)
598b4000f1SDimitry Andric m_user_expression_sp->WillStartExecuting();
608b4000f1SDimitry Andric }
618b4000f1SDimitry Andric
DidPop()62c0981da4SDimitry Andric void ThreadPlanCallUserExpression::DidPop() {
63c0981da4SDimitry Andric ThreadPlanCallFunction::DidPop();
640cac4ca3SEd Maste if (m_user_expression_sp)
650cac4ca3SEd Maste m_user_expression_sp.reset();
660cac4ca3SEd Maste }
670cac4ca3SEd Maste
MischiefManaged()6814f1b3e8SDimitry Andric bool ThreadPlanCallUserExpression::MischiefManaged() {
69145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Step);
700cac4ca3SEd Maste
7114f1b3e8SDimitry Andric if (IsPlanComplete()) {
72ead24645SDimitry Andric LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.",
730cac4ca3SEd Maste static_cast<void *>(this));
740cac4ca3SEd Maste
7514f1b3e8SDimitry Andric if (m_manage_materialization && PlanSucceeded() && m_user_expression_sp) {
760cac4ca3SEd Maste lldb::addr_t function_stack_top;
770cac4ca3SEd Maste lldb::addr_t function_stack_bottom;
780cac4ca3SEd Maste lldb::addr_t function_stack_pointer = GetFunctionStackPointer();
790cac4ca3SEd Maste
800cac4ca3SEd Maste function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
810cac4ca3SEd Maste function_stack_top = function_stack_pointer;
820cac4ca3SEd Maste
83f3fbd1c0SDimitry Andric DiagnosticManager diagnostics;
840cac4ca3SEd Maste
850cac4ca3SEd Maste ExecutionContext exe_ctx(GetThread());
860cac4ca3SEd Maste
8714f1b3e8SDimitry Andric m_user_expression_sp->FinalizeJITExecution(
8814f1b3e8SDimitry Andric diagnostics, exe_ctx, m_result_var_sp, function_stack_bottom,
89f3fbd1c0SDimitry Andric function_stack_top);
900cac4ca3SEd Maste }
910cac4ca3SEd Maste
920cac4ca3SEd Maste ThreadPlan::MischiefManaged();
930cac4ca3SEd Maste return true;
9414f1b3e8SDimitry Andric } else {
950cac4ca3SEd Maste return false;
960cac4ca3SEd Maste }
970cac4ca3SEd Maste }
980cac4ca3SEd Maste
GetRealStopInfo()9914f1b3e8SDimitry Andric StopInfoSP ThreadPlanCallUserExpression::GetRealStopInfo() {
100f034231aSEd Maste StopInfoSP stop_info_sp = ThreadPlanCallFunction::GetRealStopInfo();
101f034231aSEd Maste
10214f1b3e8SDimitry Andric if (stop_info_sp) {
103f034231aSEd Maste lldb::addr_t addr = GetStopAddress();
104cfca06d7SDimitry Andric DynamicCheckerFunctions *checkers = m_process.GetDynamicCheckers();
105f034231aSEd Maste StreamString s;
106f034231aSEd Maste
107f034231aSEd Maste if (checkers && checkers->DoCheckersExplainStop(addr, s))
108f034231aSEd Maste stop_info_sp->SetDescription(s.GetData());
109f034231aSEd Maste }
110f034231aSEd Maste
111f034231aSEd Maste return stop_info_sp;
112f034231aSEd Maste }
1138b4000f1SDimitry Andric
DoTakedown(bool success)1148b4000f1SDimitry Andric void ThreadPlanCallUserExpression::DoTakedown(bool success) {
1158b4000f1SDimitry Andric ThreadPlanCallFunction::DoTakedown(success);
1168b4000f1SDimitry Andric m_user_expression_sp->DidFinishExecuting();
1178b4000f1SDimitry Andric }
118