1 //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-python.h"
11 
12 #include "lldb/API/SBThread.h"
13 
14 #include "lldb/API/SBSymbolContext.h"
15 #include "lldb/API/SBFileSpec.h"
16 #include "lldb/API/SBStream.h"
17 #include "lldb/Breakpoint/BreakpointLocation.h"
18 #include "lldb/Core/Debugger.h"
19 #include "lldb/Core/State.h"
20 #include "lldb/Core/Stream.h"
21 #include "lldb/Core/StreamFile.h"
22 #include "lldb/Core/StructuredData.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Target/SystemRuntime.h"
25 #include "lldb/Target/Thread.h"
26 #include "lldb/Target/ThreadPlan.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/Queue.h"
29 #include "lldb/Symbol/SymbolContext.h"
30 #include "lldb/Symbol/CompileUnit.h"
31 #include "lldb/Target/StopInfo.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/ThreadPlan.h"
34 #include "lldb/Target/ThreadPlanPython.h"
35 #include "lldb/Target/ThreadPlanStepInstruction.h"
36 #include "lldb/Target/ThreadPlanStepOut.h"
37 #include "lldb/Target/ThreadPlanStepRange.h"
38 #include "lldb/Target/ThreadPlanStepInRange.h"
39 
40 
41 #include "lldb/API/SBAddress.h"
42 #include "lldb/API/SBDebugger.h"
43 #include "lldb/API/SBEvent.h"
44 #include "lldb/API/SBFrame.h"
45 #include "lldb/API/SBProcess.h"
46 #include "lldb/API/SBThreadPlan.h"
47 #include "lldb/API/SBValue.h"
48 
49 using namespace lldb;
50 using namespace lldb_private;
51 
52 //----------------------------------------------------------------------
53 // Constructors
54 //----------------------------------------------------------------------
55 SBThreadPlan::SBThreadPlan ()
56 {
57 }
58 
59 SBThreadPlan::SBThreadPlan (const ThreadPlanSP& lldb_object_sp) :
60     m_opaque_sp (lldb_object_sp)
61 {
62 }
63 
64 SBThreadPlan::SBThreadPlan (const SBThreadPlan &rhs) :
65     m_opaque_sp (rhs.m_opaque_sp)
66 {
67 
68 }
69 
70 SBThreadPlan::SBThreadPlan (lldb::SBThread &sb_thread, const char *class_name)
71 {
72     Thread *thread = sb_thread.get();
73     if (thread)
74         m_opaque_sp.reset(new ThreadPlanPython(*thread, class_name));
75 }
76 
77 //----------------------------------------------------------------------
78 // Assignment operator
79 //----------------------------------------------------------------------
80 
81 const lldb::SBThreadPlan &
82 SBThreadPlan::operator = (const SBThreadPlan &rhs)
83 {
84     if (this != &rhs)
85         m_opaque_sp = rhs.m_opaque_sp;
86     return *this;
87 }
88 //----------------------------------------------------------------------
89 // Destructor
90 //----------------------------------------------------------------------
91 SBThreadPlan::~SBThreadPlan()
92 {
93 }
94 
95 lldb_private::ThreadPlan *
96 SBThreadPlan::get()
97 {
98     return m_opaque_sp.get();
99 }
100 
101 bool
102 SBThreadPlan::IsValid() const
103 {
104     return m_opaque_sp.get() != NULL;
105 }
106 
107 void
108 SBThreadPlan::Clear ()
109 {
110     m_opaque_sp.reset();
111 }
112 
113 lldb::StopReason
114 SBThreadPlan::GetStopReason()
115 {
116     return eStopReasonNone;
117 }
118 
119 size_t
120 SBThreadPlan::GetStopReasonDataCount()
121 {
122     return 0;
123 }
124 
125 uint64_t
126 SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx)
127 {
128     return 0;
129 }
130 
131 SBThread
132 SBThreadPlan::GetThread () const
133 {
134     if (m_opaque_sp)
135     {
136         return SBThread(m_opaque_sp->GetThread().shared_from_this());
137     }
138     else
139         return SBThread();
140 }
141 
142 bool
143 SBThreadPlan::GetDescription (lldb::SBStream &description) const
144 {
145     if (m_opaque_sp)
146     {
147         m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull);
148     }
149     else
150     {
151         description.Printf("Empty SBThreadPlan");
152     }
153     return true;
154 }
155 
156 void
157 SBThreadPlan::SetThreadPlan (const ThreadPlanSP& lldb_object_sp)
158 {
159     m_opaque_sp = lldb_object_sp;
160 }
161 
162 void
163 SBThreadPlan::SetPlanComplete (bool success)
164 {
165     if (m_opaque_sp)
166         m_opaque_sp->SetPlanComplete (success);
167 }
168 
169 bool
170 SBThreadPlan::IsPlanComplete()
171 {
172     if (m_opaque_sp)
173         return m_opaque_sp->IsPlanComplete();
174     else
175         return true;
176 }
177 
178 bool
179 SBThreadPlan::IsValid()
180 {
181     if (m_opaque_sp)
182         return m_opaque_sp->ValidatePlan(nullptr);
183     else
184         return false;
185 }
186 
187     // This section allows an SBThreadPlan to push another of the common types of plans...
188     //
189     // FIXME, you should only be able to queue thread plans from inside the methods of a
190     // Scripted Thread Plan.  Need a way to enforce that.
191 
192 SBThreadPlan
193 SBThreadPlan::QueueThreadPlanForStepOverRange (SBAddress &sb_start_address,
194                                                lldb::addr_t size)
195 {
196     if (m_opaque_sp)
197     {
198         Address *start_address = sb_start_address.get();
199         if (!start_address)
200         {
201             return SBThreadPlan();
202         }
203 
204         AddressRange range (*start_address, size);
205         SymbolContext sc;
206         start_address->CalculateSymbolContext(&sc);
207         return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange (false,
208                                                                                       range,
209                                                                                       sc,
210                                                                                       eAllThreads));
211     }
212     else
213     {
214         return SBThreadPlan();
215     }
216 }
217 
218 SBThreadPlan
219 SBThreadPlan::QueueThreadPlanForStepInRange (SBAddress &sb_start_address,
220                                                lldb::addr_t size)
221 {
222     if (m_opaque_sp)
223     {
224         Address *start_address = sb_start_address.get();
225         if (!start_address)
226         {
227             return SBThreadPlan();
228         }
229 
230         AddressRange range (*start_address, size);
231         SymbolContext sc;
232         start_address->CalculateSymbolContext(&sc);
233         return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepInRange (false,
234                                                                                       range,
235                                                                                       sc,
236                                                                                       NULL,
237                                                                                       eAllThreads));
238     }
239     else
240     {
241         return SBThreadPlan();
242     }
243 }
244 
245 SBThreadPlan
246 SBThreadPlan::QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn)
247 {
248     if (m_opaque_sp)
249     {
250         SymbolContext sc;
251         sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything);
252         return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOut (false,
253                                                                                  &sc,
254                                                                                  first_insn,
255                                                                                  false,
256                                                                                  eVoteYes,
257                                                                                  eVoteNoOpinion,
258                                                                                  frame_idx_to_step_to));
259     }
260     else
261     {
262         return SBThreadPlan();
263     }
264 }
265 
266 SBThreadPlan
267 SBThreadPlan::QueueThreadPlanForRunToAddress (SBAddress sb_address)
268 {
269     if (m_opaque_sp)
270     {
271         Address *address = sb_address.get();
272         if (!address)
273             return SBThreadPlan();
274 
275         return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress (false,
276                                                                                       *address,
277                                                                                       false));
278     }
279     else
280     {
281         return SBThreadPlan();
282     }
283 }
284 
285 
286