blob: bd11f8b82f7805d5b826f1aee768ede82a5e3556 [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
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +000010#include "lldb/Target/ThreadPlanRunToAddress.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011#include "lldb/Target/Process.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/Target/RegisterContext.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000013#include "lldb/Target/Target.h"
14#include "lldb/Target/Thread.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000015#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000016#include "lldb/Utility/Stream.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017
18using namespace lldb;
19using namespace lldb_private;
20
21//----------------------------------------------------------------------
22// ThreadPlanRunToAddress: Continue plan
23//----------------------------------------------------------------------
24
Kate Stoneb9c1b512016-09-06 20:57:50 +000025ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, Address &address,
26 bool stop_others)
27 : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
28 eVoteNoOpinion, eVoteNoOpinion),
29 m_stop_others(stop_others), m_addresses(), m_break_ids() {
30 m_addresses.push_back(
31 address.GetOpcodeLoadAddress(m_thread.CalculateTarget().get()));
32 SetInitialBreakpoints();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033}
34
Kate Stoneb9c1b512016-09-06 20:57:50 +000035ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread,
36 lldb::addr_t address,
37 bool stop_others)
38 : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
39 eVoteNoOpinion, eVoteNoOpinion),
40 m_stop_others(stop_others), m_addresses(), m_break_ids() {
41 m_addresses.push_back(
42 m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
43 SetInitialBreakpoints();
Jim Ingham08b87e02010-09-14 22:03:00 +000044}
45
Kate Stoneb9c1b512016-09-06 20:57:50 +000046ThreadPlanRunToAddress::ThreadPlanRunToAddress(
47 Thread &thread, const std::vector<lldb::addr_t> &addresses,
48 bool stop_others)
49 : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
50 eVoteNoOpinion, eVoteNoOpinion),
51 m_stop_others(stop_others), m_addresses(addresses), m_break_ids() {
52 // Convert all addresses into opcode addresses to make sure we set
53 // breakpoints at the correct address.
54 Target &target = thread.GetProcess()->GetTarget();
55 std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
56 for (pos = m_addresses.begin(); pos != end; ++pos)
57 *pos = target.GetOpcodeLoadAddress(*pos);
Greg Claytonf3ef3d22011-05-22 22:46:53 +000058
Kate Stoneb9c1b512016-09-06 20:57:50 +000059 SetInitialBreakpoints();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060}
61
Kate Stoneb9c1b512016-09-06 20:57:50 +000062void ThreadPlanRunToAddress::SetInitialBreakpoints() {
63 size_t num_addresses = m_addresses.size();
64 m_break_ids.resize(num_addresses);
65
66 for (size_t i = 0; i < num_addresses; i++) {
67 Breakpoint *breakpoint;
68 breakpoint = m_thread.CalculateTarget()
69 ->CreateBreakpoint(m_addresses[i], true, false)
70 .get();
71 if (breakpoint != nullptr) {
Jonas Devliegheree103ae92018-11-15 01:18:15 +000072 if (breakpoint->IsHardware() && !breakpoint->HasResolvedLocations())
73 m_could_not_resolve_hw_bp = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 m_break_ids[i] = breakpoint->GetID();
75 breakpoint->SetThreadID(m_thread.GetID());
76 breakpoint->SetBreakpointKind("run-to-address");
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079}
80
Kate Stoneb9c1b512016-09-06 20:57:50 +000081ThreadPlanRunToAddress::~ThreadPlanRunToAddress() {
82 size_t num_break_ids = m_break_ids.size();
83 for (size_t i = 0; i < num_break_ids; i++) {
84 m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]);
85 }
Jonas Devliegheree103ae92018-11-15 01:18:15 +000086 m_could_not_resolve_hw_bp = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087}
88
Kate Stoneb9c1b512016-09-06 20:57:50 +000089void ThreadPlanRunToAddress::GetDescription(Stream *s,
90 lldb::DescriptionLevel level) {
91 size_t num_addresses = m_addresses.size();
92
93 if (level == lldb::eDescriptionLevelBrief) {
94 if (num_addresses == 0) {
95 s->Printf("run to address with no addresses given.");
96 return;
97 } else if (num_addresses == 1)
98 s->Printf("run to address: ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100 s->Printf("run to addresses: ");
101
102 for (size_t i = 0; i < num_addresses; i++) {
103 s->Address(m_addresses[i], sizeof(addr_t));
104 s->Printf(" ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106 } else {
107 if (num_addresses == 0) {
108 s->Printf("run to address with no addresses given.");
109 return;
110 } else if (num_addresses == 1)
111 s->Printf("Run to address: ");
112 else {
113 s->Printf("Run to addresses: ");
114 }
115
116 for (size_t i = 0; i < num_addresses; i++) {
117 if (num_addresses > 1) {
118 s->Printf("\n");
119 s->Indent();
120 }
121
122 s->Address(m_addresses[i], sizeof(addr_t));
123 s->Printf(" using breakpoint: %d - ", m_break_ids[i]);
124 Breakpoint *breakpoint =
125 m_thread.CalculateTarget()->GetBreakpointByID(m_break_ids[i]).get();
126 if (breakpoint)
127 breakpoint->Dump(s);
128 else
129 s->Printf("but the breakpoint has been deleted.");
130 }
131 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132}
133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134bool ThreadPlanRunToAddress::ValidatePlan(Stream *error) {
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000135 if (m_could_not_resolve_hw_bp) {
136 if (error)
137 error->Printf("Could not set hardware breakpoint(s)");
138 return false;
139 }
140
Adrian Prantl05097242018-04-30 16:49:04 +0000141 // If we couldn't set the breakpoint for some reason, then this won't work.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142 bool all_bps_good = true;
143 size_t num_break_ids = m_break_ids.size();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 for (size_t i = 0; i < num_break_ids; i++) {
145 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) {
146 all_bps_good = false;
147 if (error) {
148 error->Printf("Could not set breakpoint for address: ");
149 error->Address(m_addresses[i], sizeof(addr_t));
150 error->Printf("\n");
151 }
152 }
153 }
154 return all_bps_good;
155}
156
157bool ThreadPlanRunToAddress::DoPlanExplainsStop(Event *event_ptr) {
158 return AtOurAddress();
159}
160
161bool ThreadPlanRunToAddress::ShouldStop(Event *event_ptr) {
162 return AtOurAddress();
163}
164
165bool ThreadPlanRunToAddress::StopOthers() { return m_stop_others; }
166
167void ThreadPlanRunToAddress::SetStopOthers(bool new_value) {
168 m_stop_others = new_value;
169}
170
171StateType ThreadPlanRunToAddress::GetPlanRunState() { return eStateRunning; }
172
173bool ThreadPlanRunToAddress::WillStop() { return true; }
174
175bool ThreadPlanRunToAddress::MischiefManaged() {
176 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
177
178 if (AtOurAddress()) {
179 // Remove the breakpoint
Jim Ingham08b87e02010-09-14 22:03:00 +0000180 size_t num_break_ids = m_break_ids.size();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181
182 for (size_t i = 0; i < num_break_ids; i++) {
183 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) {
184 m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]);
185 m_break_ids[i] = LLDB_INVALID_BREAK_ID;
186 }
Jim Ingham08b87e02010-09-14 22:03:00 +0000187 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 if (log)
189 log->Printf("Completed run to address plan.");
190 ThreadPlan::MischiefManaged();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 } else
193 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000194}
195
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196bool ThreadPlanRunToAddress::AtOurAddress() {
197 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
198 bool found_it = false;
199 size_t num_addresses = m_addresses.size();
200 for (size_t i = 0; i < num_addresses; i++) {
201 if (m_addresses[i] == current_address) {
202 found_it = true;
203 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205 }
206 return found_it;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207}