1 //===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Target/ThreadPlanRunToAddress.h"
14 // Other libraries and framework 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"
25 using namespace lldb_private;
27 //----------------------------------------------------------------------
28 // ThreadPlanRunToAddress: Continue plan
29 //----------------------------------------------------------------------
31 ThreadPlanRunToAddress::ThreadPlanRunToAddress
37 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
38 m_stop_others (stop_others),
42 m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get()));
43 SetInitialBreakpoints();
46 ThreadPlanRunToAddress::ThreadPlanRunToAddress
52 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
53 m_stop_others (stop_others),
57 m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
58 SetInitialBreakpoints();
61 ThreadPlanRunToAddress::ThreadPlanRunToAddress
64 const std::vector<lldb::addr_t> &addresses,
67 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
68 m_stop_others (stop_others),
69 m_addresses (addresses),
72 // Convert all addressses into opcode addresses to make sure we set
73 // breakpoints at the correct address.
74 Target &target = thread.GetProcess()->GetTarget();
75 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);
79 SetInitialBreakpoints();
83 ThreadPlanRunToAddress::SetInitialBreakpoints ()
85 size_t num_addresses = m_addresses.size();
86 m_break_ids.resize(num_addresses);
88 for (size_t i = 0; i < num_addresses; i++)
90 Breakpoint *breakpoint;
91 breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true).get();
92 if (breakpoint != NULL)
94 m_break_ids[i] = breakpoint->GetID();
95 breakpoint->SetThreadID(m_thread.GetID());
96 breakpoint->SetBreakpointKind("run-to-address");
101 ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
103 size_t num_break_ids = m_break_ids.size();
104 for (size_t i = 0; i < num_break_ids; i++)
106 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
111 ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
113 size_t num_addresses = m_addresses.size();
115 if (level == lldb::eDescriptionLevelBrief)
117 if (num_addresses == 0)
119 s->Printf ("run to address with no addresses given.");
122 else if (num_addresses == 1)
123 s->Printf ("run to address: ");
125 s->Printf ("run to addresses: ");
127 for (size_t i = 0; i < num_addresses; i++)
129 s->Address (m_addresses[i], sizeof (addr_t));
135 if (num_addresses == 0)
137 s->Printf ("run to address with no addresses given.");
140 else if (num_addresses == 1)
141 s->Printf ("Run to address: ");
144 s->Printf ("Run to addresses: ");
147 for (size_t i = 0; i < num_addresses; i++)
149 if (num_addresses > 1)
155 s->Address(m_addresses[i], sizeof (addr_t));
156 s->Printf (" using breakpoint: %d - ", m_break_ids[i]);
157 Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get();
159 breakpoint->Dump (s);
161 s->Printf ("but the breakpoint has been deleted.");
167 ThreadPlanRunToAddress::ValidatePlan (Stream *error)
169 // If we couldn't set the breakpoint for some reason, then this won't
171 bool all_bps_good = true;
172 size_t num_break_ids = m_break_ids.size();
174 for (size_t i = 0; i < num_break_ids; i++)
176 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID)
178 all_bps_good = false;
181 error->Printf ("Could not set breakpoint for address: ");
182 error->Address (m_addresses[i], sizeof (addr_t));
183 error->Printf ("\n");
191 ThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr)
193 return AtOurAddress();
197 ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
203 ThreadPlanRunToAddress::StopOthers ()
205 return m_stop_others;
209 ThreadPlanRunToAddress::SetStopOthers (bool new_value)
211 m_stop_others = new_value;
215 ThreadPlanRunToAddress::GetPlanRunState ()
217 return eStateRunning;
221 ThreadPlanRunToAddress::WillStop ()
227 ThreadPlanRunToAddress::MischiefManaged ()
229 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
233 // Remove the breakpoint
234 size_t num_break_ids = m_break_ids.size();
236 for (size_t i = 0; i < num_break_ids; i++)
238 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID)
240 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
241 m_break_ids[i] = LLDB_INVALID_BREAK_ID;
245 log->Printf("Completed run to address plan.");
246 ThreadPlan::MischiefManaged ();
254 ThreadPlanRunToAddress::AtOurAddress ()
256 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
257 bool found_it = false;
258 size_t num_addresses = m_addresses.size();
259 for (size_t i = 0; i < num_addresses; i++)
261 if (m_addresses[i] == current_address)