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 //===----------------------------------------------------------------------===//
12 // Other libraries and framework includes
14 #include "lldb/Target/ThreadPlanRunToAddress.h"
15 #include "lldb/Core/Log.h"
16 #include "lldb/Core/Stream.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Target/RegisterContext.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Target/Thread.h"
23 using namespace lldb_private;
25 //----------------------------------------------------------------------
26 // ThreadPlanRunToAddress: Continue plan
27 //----------------------------------------------------------------------
29 ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, Address &address,
31 : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
32 eVoteNoOpinion, eVoteNoOpinion),
33 m_stop_others(stop_others), m_addresses(), m_break_ids() {
34 m_addresses.push_back(
35 address.GetOpcodeLoadAddress(m_thread.CalculateTarget().get()));
36 SetInitialBreakpoints();
39 ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread,
42 : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
43 eVoteNoOpinion, eVoteNoOpinion),
44 m_stop_others(stop_others), m_addresses(), m_break_ids() {
45 m_addresses.push_back(
46 m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
47 SetInitialBreakpoints();
50 ThreadPlanRunToAddress::ThreadPlanRunToAddress(
51 Thread &thread, const std::vector<lldb::addr_t> &addresses,
53 : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
54 eVoteNoOpinion, eVoteNoOpinion),
55 m_stop_others(stop_others), m_addresses(addresses), m_break_ids() {
56 // Convert all addresses into opcode addresses to make sure we set
57 // breakpoints at the correct address.
58 Target &target = thread.GetProcess()->GetTarget();
59 std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
60 for (pos = m_addresses.begin(); pos != end; ++pos)
61 *pos = target.GetOpcodeLoadAddress(*pos);
63 SetInitialBreakpoints();
66 void ThreadPlanRunToAddress::SetInitialBreakpoints() {
67 size_t num_addresses = m_addresses.size();
68 m_break_ids.resize(num_addresses);
70 for (size_t i = 0; i < num_addresses; i++) {
71 Breakpoint *breakpoint;
72 breakpoint = m_thread.CalculateTarget()
73 ->CreateBreakpoint(m_addresses[i], true, false)
75 if (breakpoint != nullptr) {
76 m_break_ids[i] = breakpoint->GetID();
77 breakpoint->SetThreadID(m_thread.GetID());
78 breakpoint->SetBreakpointKind("run-to-address");
83 ThreadPlanRunToAddress::~ThreadPlanRunToAddress() {
84 size_t num_break_ids = m_break_ids.size();
85 for (size_t i = 0; i < num_break_ids; i++) {
86 m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]);
90 void ThreadPlanRunToAddress::GetDescription(Stream *s,
91 lldb::DescriptionLevel level) {
92 size_t num_addresses = m_addresses.size();
94 if (level == lldb::eDescriptionLevelBrief) {
95 if (num_addresses == 0) {
96 s->Printf("run to address with no addresses given.");
98 } else if (num_addresses == 1)
99 s->Printf("run to address: ");
101 s->Printf("run to addresses: ");
103 for (size_t i = 0; i < num_addresses; i++) {
104 s->Address(m_addresses[i], sizeof(addr_t));
108 if (num_addresses == 0) {
109 s->Printf("run to address with no addresses given.");
111 } else if (num_addresses == 1)
112 s->Printf("Run to address: ");
114 s->Printf("Run to addresses: ");
117 for (size_t i = 0; i < num_addresses; i++) {
118 if (num_addresses > 1) {
123 s->Address(m_addresses[i], sizeof(addr_t));
124 s->Printf(" using breakpoint: %d - ", m_break_ids[i]);
125 Breakpoint *breakpoint =
126 m_thread.CalculateTarget()->GetBreakpointByID(m_break_ids[i]).get();
130 s->Printf("but the breakpoint has been deleted.");
135 bool ThreadPlanRunToAddress::ValidatePlan(Stream *error) {
136 // If we couldn't set the breakpoint for some reason, then this won't
138 bool all_bps_good = true;
139 size_t num_break_ids = m_break_ids.size();
141 for (size_t i = 0; i < num_break_ids; i++) {
142 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) {
143 all_bps_good = false;
145 error->Printf("Could not set breakpoint for address: ");
146 error->Address(m_addresses[i], sizeof(addr_t));
154 bool ThreadPlanRunToAddress::DoPlanExplainsStop(Event *event_ptr) {
155 return AtOurAddress();
158 bool ThreadPlanRunToAddress::ShouldStop(Event *event_ptr) {
159 return AtOurAddress();
162 bool ThreadPlanRunToAddress::StopOthers() { return m_stop_others; }
164 void ThreadPlanRunToAddress::SetStopOthers(bool new_value) {
165 m_stop_others = new_value;
168 StateType ThreadPlanRunToAddress::GetPlanRunState() { return eStateRunning; }
170 bool ThreadPlanRunToAddress::WillStop() { return true; }
172 bool ThreadPlanRunToAddress::MischiefManaged() {
173 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
175 if (AtOurAddress()) {
176 // Remove the breakpoint
177 size_t num_break_ids = m_break_ids.size();
179 for (size_t i = 0; i < num_break_ids; i++) {
180 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) {
181 m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]);
182 m_break_ids[i] = LLDB_INVALID_BREAK_ID;
186 log->Printf("Completed run to address plan.");
187 ThreadPlan::MischiefManaged();
193 bool ThreadPlanRunToAddress::AtOurAddress() {
194 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
195 bool found_it = false;
196 size_t num_addresses = m_addresses.size();
197 for (size_t i = 0; i < num_addresses; i++) {
198 if (m_addresses[i] == current_address) {