• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetReturnValueObject()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.
GetFunctionStackPointer()69   lldb::addr_t GetFunctionStackPointer() { return m_function_sp; }
70 
71   // Classes that derive from FunctionCaller, and implement their own WillPop
72   // methods should call this so that the thread state gets restored if the
73   // plan gets discarded.
74   void WillPop() 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 
GetRealStopInfo()84   lldb::StopInfoSP GetRealStopInfo() override {
85     if (m_real_stop_info_sp)
86       return m_real_stop_info_sp;
87     else
88       return GetPrivateStopInfo();
89   }
90 
GetStopAddress()91   lldb::addr_t GetStopAddress() { return m_stop_address; }
92 
93   bool RestoreThreadState() override;
94 
ThreadDestroyed()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