blob: 3755dd5eceb0ed0cc87e8f26480e6e4bf45ad5d5 [file] [log] [blame]
Chris Lattner30fdc8d2010-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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/Log.h"
17#include "lldb/Core/Stream.h"
18#include "lldb/Target/Target.h"
19#include "lldb/Target/Process.h"
20#include "lldb/Target/Thread.h"
21#include "lldb/Target/RegisterContext.h"
22
23using namespace lldb;
24using namespace lldb_private;
25
26//----------------------------------------------------------------------
27// ThreadPlanRunToAddress: Continue plan
28//----------------------------------------------------------------------
29
30ThreadPlanRunToAddress::ThreadPlanRunToAddress
31(
32 Thread &thread,
33 Address &address,
34 bool stop_others
35) :
Jim Ingham08b87e02010-09-14 22:03:00 +000036 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037 m_stop_others (stop_others),
Jim Ingham08b87e02010-09-14 22:03:00 +000038 m_addresses (),
39 m_break_ids ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040{
Greg Clayton1ac04c32012-02-21 00:09:25 +000041 m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get()));
Jim Ingham08b87e02010-09-14 22:03:00 +000042 SetInitialBreakpoints();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043}
44
45ThreadPlanRunToAddress::ThreadPlanRunToAddress
46(
47 Thread &thread,
48 lldb::addr_t address,
49 bool stop_others
50) :
Jim Ingham08b87e02010-09-14 22:03:00 +000051 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052 m_stop_others (stop_others),
Jim Ingham08b87e02010-09-14 22:03:00 +000053 m_addresses (),
54 m_break_ids ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055{
Greg Clayton1ac04c32012-02-21 00:09:25 +000056 m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
Jim Ingham08b87e02010-09-14 22:03:00 +000057 SetInitialBreakpoints();
58}
59
60ThreadPlanRunToAddress::ThreadPlanRunToAddress
61(
62 Thread &thread,
Greg Claytonf3ef3d22011-05-22 22:46:53 +000063 const std::vector<lldb::addr_t> &addresses,
Jim Ingham08b87e02010-09-14 22:03:00 +000064 bool stop_others
65) :
66 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
67 m_stop_others (stop_others),
68 m_addresses (addresses),
69 m_break_ids ()
70{
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +000071 // Convert all addresses into opcode addresses to make sure we set
Greg Claytonf3ef3d22011-05-22 22:46:53 +000072 // breakpoints at the correct address.
Greg Clayton1ac04c32012-02-21 00:09:25 +000073 Target &target = thread.GetProcess()->GetTarget();
Greg Claytonf3ef3d22011-05-22 22:46:53 +000074 std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
75 for (pos = m_addresses.begin(); pos != end; ++pos)
76 *pos = target.GetOpcodeLoadAddress (*pos);
77
Jim Ingham08b87e02010-09-14 22:03:00 +000078 SetInitialBreakpoints();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079}
80
81void
Jim Ingham08b87e02010-09-14 22:03:00 +000082ThreadPlanRunToAddress::SetInitialBreakpoints ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083{
Jim Ingham08b87e02010-09-14 22:03:00 +000084 size_t num_addresses = m_addresses.size();
85 m_break_ids.resize(num_addresses);
86
87 for (size_t i = 0; i < num_addresses; i++)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088 {
Jim Ingham08b87e02010-09-14 22:03:00 +000089 Breakpoint *breakpoint;
Greg Claytoneb023e72013-10-11 19:48:25 +000090 breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true, false).get();
Jim Ingham08b87e02010-09-14 22:03:00 +000091 if (breakpoint != NULL)
92 {
93 m_break_ids[i] = breakpoint->GetID();
94 breakpoint->SetThreadID(m_thread.GetID());
Jim Ingham29950772013-01-26 02:19:28 +000095 breakpoint->SetBreakpointKind("run-to-address");
Jim Ingham08b87e02010-09-14 22:03:00 +000096 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097 }
98}
99
100ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
101{
Jim Ingham08b87e02010-09-14 22:03:00 +0000102 size_t num_break_ids = m_break_ids.size();
103 for (size_t i = 0; i < num_break_ids; i++)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104 {
Greg Clayton1ac04c32012-02-21 00:09:25 +0000105 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106 }
107}
108
109void
110ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
111{
Jim Ingham08b87e02010-09-14 22:03:00 +0000112 size_t num_addresses = m_addresses.size();
113
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114 if (level == lldb::eDescriptionLevelBrief)
115 {
Jim Ingham08b87e02010-09-14 22:03:00 +0000116 if (num_addresses == 0)
117 {
118 s->Printf ("run to address with no addresses given.");
119 return;
120 }
121 else if (num_addresses == 1)
122 s->Printf ("run to address: ");
123 else
124 s->Printf ("run to addresses: ");
125
126 for (size_t i = 0; i < num_addresses; i++)
127 {
128 s->Address (m_addresses[i], sizeof (addr_t));
129 s->Printf(" ");
130 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131 }
132 else
133 {
Jim Ingham08b87e02010-09-14 22:03:00 +0000134 if (num_addresses == 0)
135 {
136 s->Printf ("run to address with no addresses given.");
137 return;
138 }
139 else if (num_addresses == 1)
140 s->Printf ("Run to address: ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141 else
Jim Ingham08b87e02010-09-14 22:03:00 +0000142 {
143 s->Printf ("Run to addresses: ");
144 }
145
146 for (size_t i = 0; i < num_addresses; i++)
147 {
148 if (num_addresses > 1)
149 {
150 s->Printf("\n");
151 s->Indent();
152 }
153
154 s->Address(m_addresses[i], sizeof (addr_t));
Jim Inghamf58a0482011-11-10 01:12:26 +0000155 s->Printf (" using breakpoint: %d - ", m_break_ids[i]);
Greg Clayton1ac04c32012-02-21 00:09:25 +0000156 Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get();
Jim Ingham08b87e02010-09-14 22:03:00 +0000157 if (breakpoint)
158 breakpoint->Dump (s);
159 else
160 s->Printf ("but the breakpoint has been deleted.");
161 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162 }
163}
164
165bool
166ThreadPlanRunToAddress::ValidatePlan (Stream *error)
167{
168 // If we couldn't set the breakpoint for some reason, then this won't
169 // work.
Jim Ingham08b87e02010-09-14 22:03:00 +0000170 bool all_bps_good = true;
171 size_t num_break_ids = m_break_ids.size();
172
173 for (size_t i = 0; i < num_break_ids; i++)
174 {
175 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID)
176 {
177 all_bps_good = false;
Jim Inghamf48169b2010-11-30 02:22:11 +0000178 if (error)
179 {
180 error->Printf ("Could not set breakpoint for address: ");
181 error->Address (m_addresses[i], sizeof (addr_t));
182 error->Printf ("\n");
183 }
Jim Ingham08b87e02010-09-14 22:03:00 +0000184 }
185 }
186 return all_bps_good;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187}
188
189bool
Jim Ingham221d51c2013-05-08 00:35:16 +0000190ThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191{
192 return AtOurAddress();
193}
194
195bool
196ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
197{
Jim Ingham1fd2f082015-10-12 19:03:32 +0000198 return AtOurAddress();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199}
200
201bool
202ThreadPlanRunToAddress::StopOthers ()
203{
204 return m_stop_others;
205}
206
207void
208ThreadPlanRunToAddress::SetStopOthers (bool new_value)
209{
210 m_stop_others = new_value;
211}
212
213StateType
Jim Ingham06e827c2010-11-11 19:26:09 +0000214ThreadPlanRunToAddress::GetPlanRunState ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215{
216 return eStateRunning;
217}
218
219bool
220ThreadPlanRunToAddress::WillStop ()
221{
222 return true;
223}
224
225bool
226ThreadPlanRunToAddress::MischiefManaged ()
227{
Greg Clayton5160ce52013-03-27 23:08:40 +0000228 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229
230 if (AtOurAddress())
231 {
232 // Remove the breakpoint
Jim Ingham08b87e02010-09-14 22:03:00 +0000233 size_t num_break_ids = m_break_ids.size();
234
235 for (size_t i = 0; i < num_break_ids; i++)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236 {
Jim Ingham08b87e02010-09-14 22:03:00 +0000237 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID)
238 {
Greg Clayton1ac04c32012-02-21 00:09:25 +0000239 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
Jim Ingham08b87e02010-09-14 22:03:00 +0000240 m_break_ids[i] = LLDB_INVALID_BREAK_ID;
241 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243 if (log)
244 log->Printf("Completed run to address plan.");
245 ThreadPlan::MischiefManaged ();
246 return true;
247 }
248 else
249 return false;
250}
251
252bool
253ThreadPlanRunToAddress::AtOurAddress ()
254{
255 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
Jim Ingham08b87e02010-09-14 22:03:00 +0000256 bool found_it = false;
Jim Ingham4bf570d2011-01-26 19:10:34 +0000257 size_t num_addresses = m_addresses.size();
258 for (size_t i = 0; i < num_addresses; i++)
Jim Ingham08b87e02010-09-14 22:03:00 +0000259 {
260 if (m_addresses[i] == current_address)
261 {
262 found_it = true;
263 break;
264 }
265 }
266 return found_it;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267}