blob: 18c43dafd7b377453b25c23fc6a422c259ce1202 [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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +000014#include "lldb/Target/ThreadPlanRunToAddress.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Core/Log.h"
16#include "lldb/Core/Stream.h"
17#include "lldb/Target/Target.h"
18#include "lldb/Target/Process.h"
19#include "lldb/Target/Thread.h"
20#include "lldb/Target/RegisterContext.h"
21
22using namespace lldb;
23using namespace lldb_private;
24
25//----------------------------------------------------------------------
26// ThreadPlanRunToAddress: Continue plan
27//----------------------------------------------------------------------
28
29ThreadPlanRunToAddress::ThreadPlanRunToAddress
30(
31 Thread &thread,
32 Address &address,
33 bool stop_others
34) :
Jim Ingham08b87e02010-09-14 22:03:00 +000035 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036 m_stop_others (stop_others),
Jim Ingham08b87e02010-09-14 22:03:00 +000037 m_addresses (),
38 m_break_ids ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039{
Greg Clayton1ac04c32012-02-21 00:09:25 +000040 m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get()));
Jim Ingham08b87e02010-09-14 22:03:00 +000041 SetInitialBreakpoints();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042}
43
44ThreadPlanRunToAddress::ThreadPlanRunToAddress
45(
46 Thread &thread,
47 lldb::addr_t address,
48 bool stop_others
49) :
Jim Ingham08b87e02010-09-14 22:03:00 +000050 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051 m_stop_others (stop_others),
Jim Ingham08b87e02010-09-14 22:03:00 +000052 m_addresses (),
53 m_break_ids ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054{
Greg Clayton1ac04c32012-02-21 00:09:25 +000055 m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
Jim Ingham08b87e02010-09-14 22:03:00 +000056 SetInitialBreakpoints();
57}
58
59ThreadPlanRunToAddress::ThreadPlanRunToAddress
60(
61 Thread &thread,
Greg Claytonf3ef3d22011-05-22 22:46:53 +000062 const std::vector<lldb::addr_t> &addresses,
Jim Ingham08b87e02010-09-14 22:03:00 +000063 bool stop_others
64) :
65 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
66 m_stop_others (stop_others),
67 m_addresses (addresses),
68 m_break_ids ()
69{
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +000070 // Convert all addresses into opcode addresses to make sure we set
Greg Claytonf3ef3d22011-05-22 22:46:53 +000071 // breakpoints at the correct address.
Greg Clayton1ac04c32012-02-21 00:09:25 +000072 Target &target = thread.GetProcess()->GetTarget();
Greg Claytonf3ef3d22011-05-22 22:46:53 +000073 std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
74 for (pos = m_addresses.begin(); pos != end; ++pos)
75 *pos = target.GetOpcodeLoadAddress (*pos);
76
Jim Ingham08b87e02010-09-14 22:03:00 +000077 SetInitialBreakpoints();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078}
79
80void
Jim Ingham08b87e02010-09-14 22:03:00 +000081ThreadPlanRunToAddress::SetInitialBreakpoints ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082{
Jim Ingham08b87e02010-09-14 22:03:00 +000083 size_t num_addresses = m_addresses.size();
84 m_break_ids.resize(num_addresses);
85
86 for (size_t i = 0; i < num_addresses; i++)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087 {
Jim Ingham08b87e02010-09-14 22:03:00 +000088 Breakpoint *breakpoint;
Greg Claytoneb023e72013-10-11 19:48:25 +000089 breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true, false).get();
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +000090 if (breakpoint != nullptr)
Jim Ingham08b87e02010-09-14 22:03:00 +000091 {
92 m_break_ids[i] = breakpoint->GetID();
93 breakpoint->SetThreadID(m_thread.GetID());
Jim Ingham29950772013-01-26 02:19:28 +000094 breakpoint->SetBreakpointKind("run-to-address");
Jim Ingham08b87e02010-09-14 22:03:00 +000095 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096 }
97}
98
99ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
100{
Jim Ingham08b87e02010-09-14 22:03:00 +0000101 size_t num_break_ids = m_break_ids.size();
102 for (size_t i = 0; i < num_break_ids; i++)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103 {
Greg Clayton1ac04c32012-02-21 00:09:25 +0000104 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 }
106}
107
108void
109ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
110{
Jim Ingham08b87e02010-09-14 22:03:00 +0000111 size_t num_addresses = m_addresses.size();
112
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113 if (level == lldb::eDescriptionLevelBrief)
114 {
Jim Ingham08b87e02010-09-14 22:03:00 +0000115 if (num_addresses == 0)
116 {
117 s->Printf ("run to address with no addresses given.");
118 return;
119 }
120 else if (num_addresses == 1)
121 s->Printf ("run to address: ");
122 else
123 s->Printf ("run to addresses: ");
124
125 for (size_t i = 0; i < num_addresses; i++)
126 {
127 s->Address (m_addresses[i], sizeof (addr_t));
128 s->Printf(" ");
129 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130 }
131 else
132 {
Jim Ingham08b87e02010-09-14 22:03:00 +0000133 if (num_addresses == 0)
134 {
135 s->Printf ("run to address with no addresses given.");
136 return;
137 }
138 else if (num_addresses == 1)
139 s->Printf ("Run to address: ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140 else
Jim Ingham08b87e02010-09-14 22:03:00 +0000141 {
142 s->Printf ("Run to addresses: ");
143 }
144
145 for (size_t i = 0; i < num_addresses; i++)
146 {
147 if (num_addresses > 1)
148 {
149 s->Printf("\n");
150 s->Indent();
151 }
152
153 s->Address(m_addresses[i], sizeof (addr_t));
Jim Inghamf58a0482011-11-10 01:12:26 +0000154 s->Printf (" using breakpoint: %d - ", m_break_ids[i]);
Greg Clayton1ac04c32012-02-21 00:09:25 +0000155 Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get();
Jim Ingham08b87e02010-09-14 22:03:00 +0000156 if (breakpoint)
157 breakpoint->Dump (s);
158 else
159 s->Printf ("but the breakpoint has been deleted.");
160 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161 }
162}
163
164bool
165ThreadPlanRunToAddress::ValidatePlan (Stream *error)
166{
167 // If we couldn't set the breakpoint for some reason, then this won't
168 // work.
Jim Ingham08b87e02010-09-14 22:03:00 +0000169 bool all_bps_good = true;
170 size_t num_break_ids = m_break_ids.size();
171
172 for (size_t i = 0; i < num_break_ids; i++)
173 {
174 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID)
175 {
176 all_bps_good = false;
Jim Inghamf48169b2010-11-30 02:22:11 +0000177 if (error)
178 {
179 error->Printf ("Could not set breakpoint for address: ");
180 error->Address (m_addresses[i], sizeof (addr_t));
181 error->Printf ("\n");
182 }
Jim Ingham08b87e02010-09-14 22:03:00 +0000183 }
184 }
185 return all_bps_good;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186}
187
188bool
Jim Ingham221d51c2013-05-08 00:35:16 +0000189ThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000190{
191 return AtOurAddress();
192}
193
194bool
195ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
196{
Jim Ingham1fd2f082015-10-12 19:03:32 +0000197 return AtOurAddress();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000198}
199
200bool
201ThreadPlanRunToAddress::StopOthers ()
202{
203 return m_stop_others;
204}
205
206void
207ThreadPlanRunToAddress::SetStopOthers (bool new_value)
208{
209 m_stop_others = new_value;
210}
211
212StateType
Jim Ingham06e827c2010-11-11 19:26:09 +0000213ThreadPlanRunToAddress::GetPlanRunState ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214{
215 return eStateRunning;
216}
217
218bool
219ThreadPlanRunToAddress::WillStop ()
220{
221 return true;
222}
223
224bool
225ThreadPlanRunToAddress::MischiefManaged ()
226{
Greg Clayton5160ce52013-03-27 23:08:40 +0000227 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228
229 if (AtOurAddress())
230 {
231 // Remove the breakpoint
Jim Ingham08b87e02010-09-14 22:03:00 +0000232 size_t num_break_ids = m_break_ids.size();
233
234 for (size_t i = 0; i < num_break_ids; i++)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235 {
Jim Ingham08b87e02010-09-14 22:03:00 +0000236 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID)
237 {
Greg Clayton1ac04c32012-02-21 00:09:25 +0000238 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
Jim Ingham08b87e02010-09-14 22:03:00 +0000239 m_break_ids[i] = LLDB_INVALID_BREAK_ID;
240 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000241 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242 if (log)
243 log->Printf("Completed run to address plan.");
244 ThreadPlan::MischiefManaged ();
245 return true;
246 }
247 else
248 return false;
249}
250
251bool
252ThreadPlanRunToAddress::AtOurAddress ()
253{
254 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
Jim Ingham08b87e02010-09-14 22:03:00 +0000255 bool found_it = false;
Jim Ingham4bf570d2011-01-26 19:10:34 +0000256 size_t num_addresses = m_addresses.size();
257 for (size_t i = 0; i < num_addresses; i++)
Jim Ingham08b87e02010-09-14 22:03:00 +0000258 {
259 if (m_addresses[i] == current_address)
260 {
261 found_it = true;
262 break;
263 }
264 }
265 return found_it;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266}