blob: 56c165429674de80758bc657dcaf047db80b89e9 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ThreadPlanRunToAddress.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/Target/ThreadPlanRunToAddress.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/lldb-private-log.h"
17#include "lldb/Core/Log.h"
18#include "lldb/Core/Stream.h"
19#include "lldb/Target/Target.h"
20#include "lldb/Target/Process.h"
21#include "lldb/Target/Thread.h"
22#include "lldb/Target/RegisterContext.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
27//----------------------------------------------------------------------
28// ThreadPlanRunToAddress: Continue plan
29//----------------------------------------------------------------------
30
31ThreadPlanRunToAddress::ThreadPlanRunToAddress
32(
33 Thread &thread,
34 Address &address,
35 bool stop_others
36) :
Jim Ingham17454cf2010-09-14 22:03:00 +000037 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
Chris Lattner24943d22010-06-08 16:52:24 +000038 m_stop_others (stop_others),
Jim Ingham17454cf2010-09-14 22:03:00 +000039 m_addresses (),
40 m_break_ids ()
Chris Lattner24943d22010-06-08 16:52:24 +000041{
Greg Claytonf4124de2012-02-21 00:09:25 +000042 m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get()));
Jim Ingham17454cf2010-09-14 22:03:00 +000043 SetInitialBreakpoints();
Chris Lattner24943d22010-06-08 16:52:24 +000044}
45
46ThreadPlanRunToAddress::ThreadPlanRunToAddress
47(
48 Thread &thread,
49 lldb::addr_t address,
50 bool stop_others
51) :
Jim Ingham17454cf2010-09-14 22:03:00 +000052 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
Chris Lattner24943d22010-06-08 16:52:24 +000053 m_stop_others (stop_others),
Jim Ingham17454cf2010-09-14 22:03:00 +000054 m_addresses (),
55 m_break_ids ()
Chris Lattner24943d22010-06-08 16:52:24 +000056{
Greg Claytonf4124de2012-02-21 00:09:25 +000057 m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
Jim Ingham17454cf2010-09-14 22:03:00 +000058 SetInitialBreakpoints();
59}
60
61ThreadPlanRunToAddress::ThreadPlanRunToAddress
62(
63 Thread &thread,
Greg Claytonc0fa5332011-05-22 22:46:53 +000064 const std::vector<lldb::addr_t> &addresses,
Jim Ingham17454cf2010-09-14 22:03:00 +000065 bool stop_others
66) :
67 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
68 m_stop_others (stop_others),
69 m_addresses (addresses),
70 m_break_ids ()
71{
Greg Claytonc0fa5332011-05-22 22:46:53 +000072 // Convert all addressses into opcode addresses to make sure we set
73 // breakpoints at the correct address.
Greg Claytonf4124de2012-02-21 00:09:25 +000074 Target &target = thread.GetProcess()->GetTarget();
Greg Claytonc0fa5332011-05-22 22:46:53 +000075 std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
76 for (pos = m_addresses.begin(); pos != end; ++pos)
77 *pos = target.GetOpcodeLoadAddress (*pos);
78
Jim Ingham17454cf2010-09-14 22:03:00 +000079 SetInitialBreakpoints();
Chris Lattner24943d22010-06-08 16:52:24 +000080}
81
82void
Jim Ingham17454cf2010-09-14 22:03:00 +000083ThreadPlanRunToAddress::SetInitialBreakpoints ()
Chris Lattner24943d22010-06-08 16:52:24 +000084{
Jim Ingham17454cf2010-09-14 22:03:00 +000085 size_t num_addresses = m_addresses.size();
86 m_break_ids.resize(num_addresses);
87
88 for (size_t i = 0; i < num_addresses; i++)
Chris Lattner24943d22010-06-08 16:52:24 +000089 {
Jim Ingham17454cf2010-09-14 22:03:00 +000090 Breakpoint *breakpoint;
Greg Claytonf4124de2012-02-21 00:09:25 +000091 breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true).get();
Jim Ingham17454cf2010-09-14 22:03:00 +000092 if (breakpoint != NULL)
93 {
94 m_break_ids[i] = breakpoint->GetID();
95 breakpoint->SetThreadID(m_thread.GetID());
Jim Ingham090f8312013-01-26 02:19:28 +000096 breakpoint->SetBreakpointKind("run-to-address");
Jim Ingham17454cf2010-09-14 22:03:00 +000097 }
Chris Lattner24943d22010-06-08 16:52:24 +000098 }
99}
100
101ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
102{
Jim Ingham17454cf2010-09-14 22:03:00 +0000103 size_t num_break_ids = m_break_ids.size();
104 for (size_t i = 0; i < num_break_ids; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000105 {
Greg Claytonf4124de2012-02-21 00:09:25 +0000106 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
Chris Lattner24943d22010-06-08 16:52:24 +0000107 }
108}
109
110void
111ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
112{
Jim Ingham17454cf2010-09-14 22:03:00 +0000113 size_t num_addresses = m_addresses.size();
114
Chris Lattner24943d22010-06-08 16:52:24 +0000115 if (level == lldb::eDescriptionLevelBrief)
116 {
Jim Ingham17454cf2010-09-14 22:03:00 +0000117 if (num_addresses == 0)
118 {
119 s->Printf ("run to address with no addresses given.");
120 return;
121 }
122 else if (num_addresses == 1)
123 s->Printf ("run to address: ");
124 else
125 s->Printf ("run to addresses: ");
126
127 for (size_t i = 0; i < num_addresses; i++)
128 {
129 s->Address (m_addresses[i], sizeof (addr_t));
130 s->Printf(" ");
131 }
Chris Lattner24943d22010-06-08 16:52:24 +0000132 }
133 else
134 {
Jim Ingham17454cf2010-09-14 22:03:00 +0000135 if (num_addresses == 0)
136 {
137 s->Printf ("run to address with no addresses given.");
138 return;
139 }
140 else if (num_addresses == 1)
141 s->Printf ("Run to address: ");
Chris Lattner24943d22010-06-08 16:52:24 +0000142 else
Jim Ingham17454cf2010-09-14 22:03:00 +0000143 {
144 s->Printf ("Run to addresses: ");
145 }
146
147 for (size_t i = 0; i < num_addresses; i++)
148 {
149 if (num_addresses > 1)
150 {
151 s->Printf("\n");
152 s->Indent();
153 }
154
155 s->Address(m_addresses[i], sizeof (addr_t));
Jim Ingham6db35942011-11-10 01:12:26 +0000156 s->Printf (" using breakpoint: %d - ", m_break_ids[i]);
Greg Claytonf4124de2012-02-21 00:09:25 +0000157 Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get();
Jim Ingham17454cf2010-09-14 22:03:00 +0000158 if (breakpoint)
159 breakpoint->Dump (s);
160 else
161 s->Printf ("but the breakpoint has been deleted.");
162 }
Chris Lattner24943d22010-06-08 16:52:24 +0000163 }
164}
165
166bool
167ThreadPlanRunToAddress::ValidatePlan (Stream *error)
168{
169 // If we couldn't set the breakpoint for some reason, then this won't
170 // work.
Jim Ingham17454cf2010-09-14 22:03:00 +0000171 bool all_bps_good = true;
172 size_t num_break_ids = m_break_ids.size();
173
174 for (size_t i = 0; i < num_break_ids; i++)
175 {
176 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID)
177 {
178 all_bps_good = false;
Jim Ingham360f53f2010-11-30 02:22:11 +0000179 if (error)
180 {
181 error->Printf ("Could not set breakpoint for address: ");
182 error->Address (m_addresses[i], sizeof (addr_t));
183 error->Printf ("\n");
184 }
Jim Ingham17454cf2010-09-14 22:03:00 +0000185 }
186 }
187 return all_bps_good;
Chris Lattner24943d22010-06-08 16:52:24 +0000188}
189
190bool
Jim Ingham89e248f2013-02-09 01:29:05 +0000191ThreadPlanRunToAddress::PlanExplainsStop (Event *event_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000192{
193 return AtOurAddress();
194}
195
196bool
197ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
198{
199 return false;
200}
201
202bool
203ThreadPlanRunToAddress::StopOthers ()
204{
205 return m_stop_others;
206}
207
208void
209ThreadPlanRunToAddress::SetStopOthers (bool new_value)
210{
211 m_stop_others = new_value;
212}
213
214StateType
Jim Ingham745ac7a2010-11-11 19:26:09 +0000215ThreadPlanRunToAddress::GetPlanRunState ()
Chris Lattner24943d22010-06-08 16:52:24 +0000216{
217 return eStateRunning;
218}
219
220bool
221ThreadPlanRunToAddress::WillStop ()
222{
223 return true;
224}
225
226bool
227ThreadPlanRunToAddress::MischiefManaged ()
228{
Greg Clayton952e9dc2013-03-27 23:08:40 +0000229 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +0000230
231 if (AtOurAddress())
232 {
233 // Remove the breakpoint
Jim Ingham17454cf2010-09-14 22:03:00 +0000234 size_t num_break_ids = m_break_ids.size();
235
236 for (size_t i = 0; i < num_break_ids; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000237 {
Jim Ingham17454cf2010-09-14 22:03:00 +0000238 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID)
239 {
Greg Claytonf4124de2012-02-21 00:09:25 +0000240 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
Jim Ingham17454cf2010-09-14 22:03:00 +0000241 m_break_ids[i] = LLDB_INVALID_BREAK_ID;
242 }
Chris Lattner24943d22010-06-08 16:52:24 +0000243 }
Chris Lattner24943d22010-06-08 16:52:24 +0000244 if (log)
245 log->Printf("Completed run to address plan.");
246 ThreadPlan::MischiefManaged ();
247 return true;
248 }
249 else
250 return false;
251}
252
253bool
254ThreadPlanRunToAddress::AtOurAddress ()
255{
256 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
Jim Ingham17454cf2010-09-14 22:03:00 +0000257 bool found_it = false;
Jim Ingham33ee8922011-01-26 19:10:34 +0000258 size_t num_addresses = m_addresses.size();
259 for (size_t i = 0; i < num_addresses; i++)
Jim Ingham17454cf2010-09-14 22:03:00 +0000260 {
261 if (m_addresses[i] == current_address)
262 {
263 found_it = true;
264 break;
265 }
266 }
267 return found_it;
Chris Lattner24943d22010-06-08 16:52:24 +0000268}