blob: ac337cbc8c459d1785ea934b21d199c1e532e786 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ThreadPlanStepInstruction.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
11#include "lldb/Target/ThreadPlanStepInstruction.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
17#include "lldb/lldb-private-log.h"
18#include "lldb/Core/Log.h"
19#include "lldb/Core/Stream.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Target/Process.h"
Greg Clayton643ee732010-08-04 01:40:35 +000021#include "lldb/Target/RegisterContext.h"
22#include "lldb/Target/RegisterContext.h"
23#include "lldb/Target/StopInfo.h"
24#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025
26using namespace lldb;
27using namespace lldb_private;
28
29//----------------------------------------------------------------------
30// ThreadPlanStepInstruction: Step over the current instruction
31//----------------------------------------------------------------------
32
33ThreadPlanStepInstruction::ThreadPlanStepInstruction
34(
35 Thread &thread,
36 bool step_over,
37 bool stop_other_threads,
38 Vote stop_vote,
39 Vote run_vote
40) :
Jim Ingham5a47e8b2010-06-19 04:45:32 +000041 ThreadPlan (ThreadPlan::eKindStepInstruction, "Step over single instruction", thread, stop_vote, run_vote),
Chris Lattner24943d22010-06-08 16:52:24 +000042 m_instruction_addr (0),
Benjamin Kramer36a08102010-07-16 12:32:33 +000043 m_stop_other_threads (stop_other_threads),
Chris Lattner24943d22010-06-08 16:52:24 +000044 m_step_over (step_over),
Benjamin Kramer36a08102010-07-16 12:32:33 +000045 m_stack_depth (0)
46{
Chris Lattner24943d22010-06-08 16:52:24 +000047 m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0);
48 m_stack_depth = m_thread.GetStackFrameCount();
49}
50
51ThreadPlanStepInstruction::~ThreadPlanStepInstruction ()
52{
53}
54
55void
56ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level)
57{
58 if (level == lldb::eDescriptionLevelBrief)
59 {
60 if (m_step_over)
61 s->Printf ("instruction step over");
62 else
63 s->Printf ("instruction step into");
64 }
65 else
66 {
67 s->Printf ("Stepping one instruction past ");
68 s->Address(m_instruction_addr, sizeof (addr_t));
69 if (m_step_over)
70 s->Printf(" stepping over calls");
71 else
72 s->Printf(" stepping into calls");
73 }
74}
75
76bool
77ThreadPlanStepInstruction::ValidatePlan (Stream *error)
78{
79 // Since we read the instruction we're stepping over from the thread,
80 // this plan will always work.
81 return true;
82}
83
84bool
85ThreadPlanStepInstruction::PlanExplainsStop ()
86{
Jim Ingham6297a3a2010-10-20 00:39:53 +000087 StopInfoSP stop_info_sp = GetPrivateStopReason();
88 if (stop_info_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000089 {
Jim Ingham6297a3a2010-10-20 00:39:53 +000090 StopReason reason = stop_info_sp->GetStopReason();
Greg Clayton643ee732010-08-04 01:40:35 +000091 if (reason == eStopReasonTrace || reason == eStopReasonNone)
Chris Lattner24943d22010-06-08 16:52:24 +000092 return true;
93 else
94 return false;
95 }
96 return false;
97}
98
99bool
100ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
101{
102 if (m_step_over)
103 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000104 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +0000105 if (m_thread.GetStackFrameCount() <= m_stack_depth)
106 {
107 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
108 {
109 SetPlanComplete();
110 return true;
111 }
112 else
113 return false;
114 }
115 else
116 {
117 // We've stepped in, step back out again:
118 StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
119 if (return_frame)
120 {
121 if (log)
122 {
123 StreamString s;
124 s.PutCString ("Stepped in to: ");
Greg Claytonb04e7a82010-08-24 21:05:24 +0000125 addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
Greg Claytonf4124de2012-02-21 00:09:25 +0000126 s.Address (stop_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000127 s.PutCString (" stepping out to: ");
Greg Claytonb04e7a82010-08-24 21:05:24 +0000128 addr_t return_addr = return_frame->GetRegisterContext()->GetPC();
Greg Claytonf4124de2012-02-21 00:09:25 +0000129 s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000130 log->Printf("%s.", s.GetData());
131 }
Greg Clayton1ebdcc72011-01-21 06:11:58 +0000132 m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000133 return false;
134 }
135 else
136 {
137 if (log)
138 log->Printf("Could not find previous frame, stopping.");
139 SetPlanComplete();
140 return true;
141 }
142
143 }
144
145 }
146 else
147 {
148 if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
149 {
150 SetPlanComplete();
151 return true;
152 }
153 else
154 return false;
155 }
156}
157
158bool
159ThreadPlanStepInstruction::StopOthers ()
160{
161 return m_stop_other_threads;
162}
163
164StateType
Jim Ingham745ac7a2010-11-11 19:26:09 +0000165ThreadPlanStepInstruction::GetPlanRunState ()
Chris Lattner24943d22010-06-08 16:52:24 +0000166{
167 return eStateStepping;
168}
169
170bool
171ThreadPlanStepInstruction::WillStop ()
172{
173 return true;
174}
175
176bool
177ThreadPlanStepInstruction::MischiefManaged ()
178{
179 if (IsPlanComplete())
180 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000181 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +0000182 if (log)
183 log->Printf("Completed single instruction step plan.");
184 ThreadPlan::MischiefManaged ();
185 return true;
186 }
187 else
188 {
189 return false;
190 }
191}
192