1 | //===-- ThreadPlanCallFunction.h --------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_TARGET_THREADPLANCALLFUNCTION_H |
10 | #define LLDB_TARGET_THREADPLANCALLFUNCTION_H |
11 | |
12 | #include "lldb/Target/Thread.h" |
13 | #include "lldb/Target/ThreadPlan.h" |
14 | #include "lldb/lldb-private.h" |
15 | |
16 | #include "llvm/ADT/ArrayRef.h" |
17 | |
18 | namespace lldb_private { |
19 | |
20 | class ThreadPlanCallFunction : public ThreadPlan { |
21 | // Create a thread plan to call a function at the address passed in the |
22 | // "function" argument. If you plan to call GetReturnValueObject, then pass |
23 | // in the return type, otherwise just pass in an invalid CompilerType. |
24 | public: |
25 | ThreadPlanCallFunction(Thread &thread, const Address &function, |
26 | const CompilerType &return_type, |
27 | llvm::ArrayRef<lldb::addr_t> args, |
28 | const EvaluateExpressionOptions &options); |
29 | |
30 | ThreadPlanCallFunction(Thread &thread, const Address &function, |
31 | const EvaluateExpressionOptions &options); |
32 | |
33 | ~ThreadPlanCallFunction() override; |
34 | |
35 | void GetDescription(Stream *s, lldb::DescriptionLevel level) override; |
36 | |
37 | bool ValidatePlan(Stream *error) override; |
38 | |
39 | bool ShouldStop(Event *event_ptr) override; |
40 | |
41 | Vote ShouldReportStop(Event *event_ptr) override; |
42 | |
43 | bool StopOthers() override; |
44 | |
45 | lldb::StateType GetPlanRunState() override; |
46 | |
47 | void DidPush() override; |
48 | |
49 | bool WillStop() override; |
50 | |
51 | bool MischiefManaged() override; |
52 | |
53 | // To get the return value from a function call you must create a |
54 | // lldb::ValueSP that contains a valid clang type in its context and call |
55 | // RequestReturnValue. The ValueSP will be stored and when the function is |
56 | // done executing, the object will check if there is a requested return |
57 | // value. If there is, the return value will be retrieved using the |
58 | // ABI::GetReturnValue() for the ABI in the process. Then after the thread |
59 | // plan is complete, you can call "GetReturnValue()" to retrieve the value |
60 | // that was extracted. |
61 | |
62 | lldb::ValueObjectSP GetReturnValueObject() override { |
63 | return m_return_valobj_sp; |
64 | } |
65 | |
66 | // Return the stack pointer that the function received on entry. Any stack |
67 | // address below this should be considered invalid after the function has |
68 | // been cleaned up. |
69 | lldb::addr_t GetFunctionStackPointer() { return m_function_sp; } |
70 | |
71 | // Classes that derive from FunctionCaller, and implement their own DidPop |
72 | // methods should call this so that the thread state gets restored if the |
73 | // plan gets discarded. |
74 | void DidPop() override; |
75 | |
76 | // If the thread plan stops mid-course, this will be the stop reason that |
77 | // interrupted us. Once DoTakedown is called, this will be the real stop |
78 | // reason at the end of the function call. If it hasn't been set for one or |
79 | // the other of these reasons, we'll return the PrivateStopReason. This is |
80 | // needed because we want the CallFunction thread plans not to show up as the |
81 | // stop reason. But if something bad goes wrong, it is nice to be able to |
82 | // tell the user what really happened. |
83 | |
84 | virtual lldb::StopInfoSP GetRealStopInfo() { |
85 | if (m_real_stop_info_sp) |
86 | return m_real_stop_info_sp; |
87 | else |
88 | return GetPrivateStopInfo(); |
89 | } |
90 | |
91 | lldb::addr_t GetStopAddress() { return m_stop_address; } |
92 | |
93 | void RestoreThreadState() override; |
94 | |
95 | void ThreadDestroyed() override { m_takedown_done = true; } |
96 | |
97 | void SetStopOthers(bool new_value) override; |
98 | |
99 | protected: |
100 | void ReportRegisterState(const char *message); |
101 | |
102 | bool DoPlanExplainsStop(Event *event_ptr) override; |
103 | |
104 | virtual void SetReturnValue(); |
105 | |
106 | bool ConstructorSetup(Thread &thread, ABI *&abi, |
107 | lldb::addr_t &start_load_addr, |
108 | lldb::addr_t &function_load_addr); |
109 | |
110 | virtual void DoTakedown(bool success); |
111 | |
112 | void SetBreakpoints(); |
113 | |
114 | void ClearBreakpoints(); |
115 | |
116 | bool BreakpointsExplainStop(); |
117 | |
118 | bool m_valid; |
119 | bool m_stop_other_threads; |
120 | bool m_unwind_on_error; |
121 | bool m_ignore_breakpoints; |
122 | bool m_debug_execution; |
123 | bool m_trap_exceptions; |
124 | Address m_function_addr; |
125 | Address m_start_addr; |
126 | lldb::addr_t m_function_sp; |
127 | lldb::ThreadPlanSP m_subplan_sp; |
128 | LanguageRuntime *m_cxx_language_runtime; |
129 | LanguageRuntime *m_objc_language_runtime; |
130 | Thread::ThreadStateCheckpoint m_stored_thread_state; |
131 | lldb::StopInfoSP |
132 | m_real_stop_info_sp; // In general we want to hide call function |
133 | // thread plans, but for reporting purposes, it's |
134 | // nice to know the real stop reason. This gets set |
135 | // in DoTakedown. |
136 | StreamString m_constructor_errors; |
137 | lldb::ValueObjectSP m_return_valobj_sp; // If this contains a valid pointer, |
138 | // use the ABI to extract values when |
139 | // complete |
140 | bool m_takedown_done; // We want to ensure we only do the takedown once. This |
141 | // ensures that. |
142 | bool m_should_clear_objc_exception_bp; |
143 | bool m_should_clear_cxx_exception_bp; |
144 | lldb::addr_t m_stop_address; // This is the address we stopped at. Also set |
145 | // in DoTakedown; |
146 | |
147 | private: |
148 | CompilerType m_return_type; |
149 | ThreadPlanCallFunction(const ThreadPlanCallFunction &) = delete; |
150 | const ThreadPlanCallFunction & |
151 | operator=(const ThreadPlanCallFunction &) = delete; |
152 | }; |
153 | |
154 | } // namespace lldb_private |
155 | |
156 | #endif // LLDB_TARGET_THREADPLANCALLFUNCTION_H |
157 | |