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