1*30fdc8d8SChris Lattner //===-- ThreadPlanStepInstruction.cpp ---------------------------*- C++ -*-===//
2*30fdc8d8SChris Lattner //
3*30fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
4*30fdc8d8SChris Lattner //
5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
7*30fdc8d8SChris Lattner //
8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
9*30fdc8d8SChris Lattner 
10*30fdc8d8SChris Lattner 
11*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
12*30fdc8d8SChris Lattner 
13*30fdc8d8SChris Lattner // C Includes
14*30fdc8d8SChris Lattner // C++ Includes
15*30fdc8d8SChris Lattner // Other libraries and framework includes
16*30fdc8d8SChris Lattner // Project includes
17*30fdc8d8SChris Lattner #include "lldb/lldb-private-log.h"
18*30fdc8d8SChris Lattner #include "lldb/Core/Log.h"
19*30fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
20*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
21*30fdc8d8SChris Lattner #include "lldb/Target/Target.h"
22*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
23*30fdc8d8SChris Lattner #include "lldb/Target/Process.h"
24*30fdc8d8SChris Lattner 
25*30fdc8d8SChris Lattner using namespace lldb;
26*30fdc8d8SChris Lattner using namespace lldb_private;
27*30fdc8d8SChris Lattner 
28*30fdc8d8SChris Lattner //----------------------------------------------------------------------
29*30fdc8d8SChris Lattner // ThreadPlanStepInstruction: Step over the current instruction
30*30fdc8d8SChris Lattner //----------------------------------------------------------------------
31*30fdc8d8SChris Lattner 
32*30fdc8d8SChris Lattner ThreadPlanStepInstruction::ThreadPlanStepInstruction
33*30fdc8d8SChris Lattner (
34*30fdc8d8SChris Lattner     Thread &thread,
35*30fdc8d8SChris Lattner     bool step_over,
36*30fdc8d8SChris Lattner     bool stop_other_threads,
37*30fdc8d8SChris Lattner     Vote stop_vote,
38*30fdc8d8SChris Lattner     Vote run_vote
39*30fdc8d8SChris Lattner ) :
40*30fdc8d8SChris Lattner     ThreadPlan ("Step over single instruction", thread, stop_vote, run_vote),
41*30fdc8d8SChris Lattner     m_instruction_addr (0),
42*30fdc8d8SChris Lattner     m_step_over (step_over),
43*30fdc8d8SChris Lattner     m_stack_depth(0),
44*30fdc8d8SChris Lattner     m_stop_other_threads (stop_other_threads)
45*30fdc8d8SChris Lattner {
46*30fdc8d8SChris Lattner     m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0);
47*30fdc8d8SChris Lattner     m_stack_depth = m_thread.GetStackFrameCount();
48*30fdc8d8SChris Lattner }
49*30fdc8d8SChris Lattner 
50*30fdc8d8SChris Lattner ThreadPlanStepInstruction::~ThreadPlanStepInstruction ()
51*30fdc8d8SChris Lattner {
52*30fdc8d8SChris Lattner }
53*30fdc8d8SChris Lattner 
54*30fdc8d8SChris Lattner void
55*30fdc8d8SChris Lattner ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level)
56*30fdc8d8SChris Lattner {
57*30fdc8d8SChris Lattner     if (level == lldb::eDescriptionLevelBrief)
58*30fdc8d8SChris Lattner     {
59*30fdc8d8SChris Lattner         if (m_step_over)
60*30fdc8d8SChris Lattner             s->Printf ("instruction step over");
61*30fdc8d8SChris Lattner         else
62*30fdc8d8SChris Lattner             s->Printf ("instruction step into");
63*30fdc8d8SChris Lattner     }
64*30fdc8d8SChris Lattner     else
65*30fdc8d8SChris Lattner     {
66*30fdc8d8SChris Lattner         s->Printf ("Stepping one instruction past ");
67*30fdc8d8SChris Lattner         s->Address(m_instruction_addr, sizeof (addr_t));
68*30fdc8d8SChris Lattner         if (m_step_over)
69*30fdc8d8SChris Lattner             s->Printf(" stepping over calls");
70*30fdc8d8SChris Lattner         else
71*30fdc8d8SChris Lattner             s->Printf(" stepping into calls");
72*30fdc8d8SChris Lattner     }
73*30fdc8d8SChris Lattner }
74*30fdc8d8SChris Lattner 
75*30fdc8d8SChris Lattner bool
76*30fdc8d8SChris Lattner ThreadPlanStepInstruction::ValidatePlan (Stream *error)
77*30fdc8d8SChris Lattner {
78*30fdc8d8SChris Lattner     // Since we read the instruction we're stepping over from the thread,
79*30fdc8d8SChris Lattner     // this plan will always work.
80*30fdc8d8SChris Lattner     return true;
81*30fdc8d8SChris Lattner }
82*30fdc8d8SChris Lattner 
83*30fdc8d8SChris Lattner bool
84*30fdc8d8SChris Lattner ThreadPlanStepInstruction::PlanExplainsStop ()
85*30fdc8d8SChris Lattner {
86*30fdc8d8SChris Lattner     Thread::StopInfo info;
87*30fdc8d8SChris Lattner     if (m_thread.GetStopInfo (&info))
88*30fdc8d8SChris Lattner     {
89*30fdc8d8SChris Lattner         StopReason reason = info.GetStopReason();
90*30fdc8d8SChris Lattner         if (reason == eStopReasonTrace || reason ==eStopReasonNone)
91*30fdc8d8SChris Lattner             return true;
92*30fdc8d8SChris Lattner         else
93*30fdc8d8SChris Lattner             return false;
94*30fdc8d8SChris Lattner     }
95*30fdc8d8SChris Lattner     return false;
96*30fdc8d8SChris Lattner }
97*30fdc8d8SChris Lattner 
98*30fdc8d8SChris Lattner bool
99*30fdc8d8SChris Lattner ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
100*30fdc8d8SChris Lattner {
101*30fdc8d8SChris Lattner     if (m_step_over)
102*30fdc8d8SChris Lattner     {
103*30fdc8d8SChris Lattner         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
104*30fdc8d8SChris Lattner         if (m_thread.GetStackFrameCount() <= m_stack_depth)
105*30fdc8d8SChris Lattner         {
106*30fdc8d8SChris Lattner             if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
107*30fdc8d8SChris Lattner             {
108*30fdc8d8SChris Lattner                 SetPlanComplete();
109*30fdc8d8SChris Lattner                 return true;
110*30fdc8d8SChris Lattner             }
111*30fdc8d8SChris Lattner             else
112*30fdc8d8SChris Lattner                 return false;
113*30fdc8d8SChris Lattner         }
114*30fdc8d8SChris Lattner         else
115*30fdc8d8SChris Lattner         {
116*30fdc8d8SChris Lattner             // We've stepped in, step back out again:
117*30fdc8d8SChris Lattner             StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
118*30fdc8d8SChris Lattner             if (return_frame)
119*30fdc8d8SChris Lattner             {
120*30fdc8d8SChris Lattner                 if (log)
121*30fdc8d8SChris Lattner                 {
122*30fdc8d8SChris Lattner                     StreamString s;
123*30fdc8d8SChris Lattner                     s.PutCString ("Stepped in to: ");
124*30fdc8d8SChris Lattner                     addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetPC().GetLoadAddress(&m_thread.GetProcess());
125*30fdc8d8SChris Lattner                     s.Address (stop_addr, m_thread.GetProcess().GetAddressByteSize());
126*30fdc8d8SChris Lattner                     s.PutCString (" stepping out to: ");
127*30fdc8d8SChris Lattner                     addr_t return_addr = return_frame->GetPC().GetLoadAddress(&m_thread.GetProcess());
128*30fdc8d8SChris Lattner                     s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize());
129*30fdc8d8SChris Lattner                     log->Printf("%s.", s.GetData());
130*30fdc8d8SChris Lattner                 }
131*30fdc8d8SChris Lattner                 m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion);
132*30fdc8d8SChris Lattner                 return false;
133*30fdc8d8SChris Lattner             }
134*30fdc8d8SChris Lattner             else
135*30fdc8d8SChris Lattner             {
136*30fdc8d8SChris Lattner                 if (log)
137*30fdc8d8SChris Lattner                     log->Printf("Could not find previous frame, stopping.");
138*30fdc8d8SChris Lattner                 SetPlanComplete();
139*30fdc8d8SChris Lattner                 return true;
140*30fdc8d8SChris Lattner             }
141*30fdc8d8SChris Lattner 
142*30fdc8d8SChris Lattner         }
143*30fdc8d8SChris Lattner 
144*30fdc8d8SChris Lattner     }
145*30fdc8d8SChris Lattner     else
146*30fdc8d8SChris Lattner     {
147*30fdc8d8SChris Lattner         if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
148*30fdc8d8SChris Lattner         {
149*30fdc8d8SChris Lattner             SetPlanComplete();
150*30fdc8d8SChris Lattner             return true;
151*30fdc8d8SChris Lattner         }
152*30fdc8d8SChris Lattner         else
153*30fdc8d8SChris Lattner             return false;
154*30fdc8d8SChris Lattner     }
155*30fdc8d8SChris Lattner }
156*30fdc8d8SChris Lattner 
157*30fdc8d8SChris Lattner bool
158*30fdc8d8SChris Lattner ThreadPlanStepInstruction::StopOthers ()
159*30fdc8d8SChris Lattner {
160*30fdc8d8SChris Lattner     return m_stop_other_threads;
161*30fdc8d8SChris Lattner }
162*30fdc8d8SChris Lattner 
163*30fdc8d8SChris Lattner StateType
164*30fdc8d8SChris Lattner ThreadPlanStepInstruction::RunState ()
165*30fdc8d8SChris Lattner {
166*30fdc8d8SChris Lattner     return eStateStepping;
167*30fdc8d8SChris Lattner }
168*30fdc8d8SChris Lattner 
169*30fdc8d8SChris Lattner bool
170*30fdc8d8SChris Lattner ThreadPlanStepInstruction::WillStop ()
171*30fdc8d8SChris Lattner {
172*30fdc8d8SChris Lattner     return true;
173*30fdc8d8SChris Lattner }
174*30fdc8d8SChris Lattner 
175*30fdc8d8SChris Lattner bool
176*30fdc8d8SChris Lattner ThreadPlanStepInstruction::MischiefManaged ()
177*30fdc8d8SChris Lattner {
178*30fdc8d8SChris Lattner     if (IsPlanComplete())
179*30fdc8d8SChris Lattner     {
180*30fdc8d8SChris Lattner         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
181*30fdc8d8SChris Lattner         if (log)
182*30fdc8d8SChris Lattner             log->Printf("Completed single instruction step plan.");
183*30fdc8d8SChris Lattner         ThreadPlan::MischiefManaged ();
184*30fdc8d8SChris Lattner         return true;
185*30fdc8d8SChris Lattner     }
186*30fdc8d8SChris Lattner     else
187*30fdc8d8SChris Lattner     {
188*30fdc8d8SChris Lattner         return false;
189*30fdc8d8SChris Lattner     }
190*30fdc8d8SChris Lattner }
191*30fdc8d8SChris Lattner 
192