blob: 23945453f00feaa66705bb9fe2b9899bdd49c4b8 [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 Claytoneea26402010-09-14 23:36:40 +000042 m_addresses.push_back (address.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
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{
Jim Ingham17454cf2010-09-14 22:03:00 +000057 m_addresses.push_back(address);
58 SetInitialBreakpoints();
59}
60
61ThreadPlanRunToAddress::ThreadPlanRunToAddress
62(
63 Thread &thread,
64 std::vector<lldb::addr_t> &addresses,
65 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{
72 SetInitialBreakpoints();
Chris Lattner24943d22010-06-08 16:52:24 +000073}
74
75void
Jim Ingham17454cf2010-09-14 22:03:00 +000076ThreadPlanRunToAddress::SetInitialBreakpoints ()
Chris Lattner24943d22010-06-08 16:52:24 +000077{
Jim Ingham17454cf2010-09-14 22:03:00 +000078 size_t num_addresses = m_addresses.size();
79 m_break_ids.resize(num_addresses);
80
81 for (size_t i = 0; i < num_addresses; i++)
Chris Lattner24943d22010-06-08 16:52:24 +000082 {
Jim Ingham17454cf2010-09-14 22:03:00 +000083 Breakpoint *breakpoint;
84 breakpoint = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_addresses[i], true).get();
85 if (breakpoint != NULL)
86 {
87 m_break_ids[i] = breakpoint->GetID();
88 breakpoint->SetThreadID(m_thread.GetID());
89 }
Chris Lattner24943d22010-06-08 16:52:24 +000090 }
91}
92
93ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
94{
Jim Ingham17454cf2010-09-14 22:03:00 +000095 size_t num_break_ids = m_break_ids.size();
96 for (size_t i = 0; i < num_break_ids; i++)
Chris Lattner24943d22010-06-08 16:52:24 +000097 {
Jim Ingham17454cf2010-09-14 22:03:00 +000098 m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_ids[i]);
Chris Lattner24943d22010-06-08 16:52:24 +000099 }
100}
101
102void
103ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
104{
Jim Ingham17454cf2010-09-14 22:03:00 +0000105 size_t num_addresses = m_addresses.size();
106
Chris Lattner24943d22010-06-08 16:52:24 +0000107 if (level == lldb::eDescriptionLevelBrief)
108 {
Jim Ingham17454cf2010-09-14 22:03:00 +0000109 if (num_addresses == 0)
110 {
111 s->Printf ("run to address with no addresses given.");
112 return;
113 }
114 else if (num_addresses == 1)
115 s->Printf ("run to address: ");
116 else
117 s->Printf ("run to addresses: ");
118
119 for (size_t i = 0; i < num_addresses; i++)
120 {
121 s->Address (m_addresses[i], sizeof (addr_t));
122 s->Printf(" ");
123 }
Chris Lattner24943d22010-06-08 16:52:24 +0000124 }
125 else
126 {
Jim Ingham17454cf2010-09-14 22:03:00 +0000127 if (num_addresses == 0)
128 {
129 s->Printf ("run to address with no addresses given.");
130 return;
131 }
132 else if (num_addresses == 1)
133 s->Printf ("Run to address: ");
Chris Lattner24943d22010-06-08 16:52:24 +0000134 else
Jim Ingham17454cf2010-09-14 22:03:00 +0000135 {
136 s->Printf ("Run to addresses: ");
137 }
138
139 for (size_t i = 0; i < num_addresses; i++)
140 {
141 if (num_addresses > 1)
142 {
143 s->Printf("\n");
144 s->Indent();
145 }
146
147 s->Address(m_addresses[i], sizeof (addr_t));
148 s->Printf (" using breakpoint: %d - ", m_break_ids[i]);
149 Breakpoint *breakpoint = m_thread.GetProcess().GetTarget().GetBreakpointByID (m_break_ids[i]).get();
150 if (breakpoint)
151 breakpoint->Dump (s);
152 else
153 s->Printf ("but the breakpoint has been deleted.");
154 }
Chris Lattner24943d22010-06-08 16:52:24 +0000155 }
156}
157
158bool
159ThreadPlanRunToAddress::ValidatePlan (Stream *error)
160{
161 // If we couldn't set the breakpoint for some reason, then this won't
162 // work.
Jim Ingham17454cf2010-09-14 22:03:00 +0000163 bool all_bps_good = true;
164 size_t num_break_ids = m_break_ids.size();
165
166 for (size_t i = 0; i < num_break_ids; i++)
167 {
168 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID)
169 {
170 all_bps_good = false;
Jim Ingham360f53f2010-11-30 02:22:11 +0000171 if (error)
172 {
173 error->Printf ("Could not set breakpoint for address: ");
174 error->Address (m_addresses[i], sizeof (addr_t));
175 error->Printf ("\n");
176 }
Jim Ingham17454cf2010-09-14 22:03:00 +0000177 }
178 }
179 return all_bps_good;
Chris Lattner24943d22010-06-08 16:52:24 +0000180}
181
182bool
183ThreadPlanRunToAddress::PlanExplainsStop ()
184{
185 return AtOurAddress();
186}
187
188bool
189ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
190{
191 return false;
192}
193
194bool
195ThreadPlanRunToAddress::StopOthers ()
196{
197 return m_stop_others;
198}
199
200void
201ThreadPlanRunToAddress::SetStopOthers (bool new_value)
202{
203 m_stop_others = new_value;
204}
205
206StateType
Jim Ingham745ac7a2010-11-11 19:26:09 +0000207ThreadPlanRunToAddress::GetPlanRunState ()
Chris Lattner24943d22010-06-08 16:52:24 +0000208{
209 return eStateRunning;
210}
211
212bool
213ThreadPlanRunToAddress::WillStop ()
214{
215 return true;
216}
217
218bool
219ThreadPlanRunToAddress::MischiefManaged ()
220{
Greg Claytone005f2c2010-11-06 01:53:30 +0000221 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +0000222
223 if (AtOurAddress())
224 {
225 // Remove the breakpoint
Jim Ingham17454cf2010-09-14 22:03:00 +0000226 size_t num_break_ids = m_break_ids.size();
227
228 for (size_t i = 0; i < num_break_ids; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000229 {
Jim Ingham17454cf2010-09-14 22:03:00 +0000230 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID)
231 {
232 m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_ids[i]);
233 m_break_ids[i] = LLDB_INVALID_BREAK_ID;
234 }
Chris Lattner24943d22010-06-08 16:52:24 +0000235 }
Chris Lattner24943d22010-06-08 16:52:24 +0000236 if (log)
237 log->Printf("Completed run to address plan.");
238 ThreadPlan::MischiefManaged ();
239 return true;
240 }
241 else
242 return false;
243}
244
245bool
246ThreadPlanRunToAddress::AtOurAddress ()
247{
248 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
Jim Ingham17454cf2010-09-14 22:03:00 +0000249 bool found_it = false;
Jim Ingham33ee8922011-01-26 19:10:34 +0000250 size_t num_addresses = m_addresses.size();
251 for (size_t i = 0; i < num_addresses; i++)
Jim Ingham17454cf2010-09-14 22:03:00 +0000252 {
253 if (m_addresses[i] == current_address)
254 {
255 found_it = true;
256 break;
257 }
258 }
259 return found_it;
Chris Lattner24943d22010-06-08 16:52:24 +0000260}