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"
11 #include "lldb/Target/Process.h"
12 #include "lldb/Target/RegisterContext.h"
13 #include "lldb/Target/Target.h"
14 #include "lldb/Target/Thread.h"
15 #include "lldb/Utility/Log.h"
16 #include "lldb/Utility/Stream.h"
19 using namespace lldb_private;
21 //----------------------------------------------------------------------
22 // ThreadPlanRunToAddress: Continue plan
23 //----------------------------------------------------------------------
25 ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, Address &address,
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();
35 ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread,
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();
46 ThreadPlanRunToAddress::ThreadPlanRunToAddress(
47 Thread &thread, const std::vector<lldb::addr_t> &addresses,
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);
59 SetInitialBreakpoints();
62 void ThreadPlanRunToAddress::SetInitialBreakpoints() {
63 size_t num_addresses = m_addresses.size();
64 m_break_ids.resize(num_addresses);
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)
71 if (breakpoint != nullptr) {
72 if (breakpoint->IsHardware() && !breakpoint->HasResolvedLocations())
73 m_could_not_resolve_hw_bp = true;
74 m_break_ids[i] = breakpoint->GetID();
75 breakpoint->SetThreadID(m_thread.GetID());
76 breakpoint->SetBreakpointKind("run-to-address");
81 ThreadPlanRunToAddress::~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]);
86 m_could_not_resolve_hw_bp = false;
89 void ThreadPlanRunToAddress::GetDescription(Stream *s,
90 lldb::DescriptionLevel level) {
91 size_t num_addresses = m_addresses.size();
93 if (level == lldb::eDescriptionLevelBrief) {
94 if (num_addresses == 0) {
95 s->Printf("run to address with no addresses given.");
97 } else if (num_addresses == 1)
98 s->Printf("run to address: ");
100 s->Printf("run to addresses: ");
102 for (size_t i = 0; i < num_addresses; i++) {
103 s->Address(m_addresses[i], sizeof(addr_t));
107 if (num_addresses == 0) {
108 s->Printf("run to address with no addresses given.");
110 } else if (num_addresses == 1)
111 s->Printf("Run to address: ");
113 s->Printf("Run to addresses: ");
116 for (size_t i = 0; i < num_addresses; i++) {
117 if (num_addresses > 1) {
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();
129 s->Printf("but the breakpoint has been deleted.");
134 bool ThreadPlanRunToAddress::ValidatePlan(Stream *error) {
135 if (m_could_not_resolve_hw_bp) {
137 error->Printf("Could not set hardware breakpoint(s)");
141 // If we couldn't set the breakpoint for some reason, then this won't work.
142 bool all_bps_good = true;
143 size_t num_break_ids = m_break_ids.size();
144 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;
148 error->Printf("Could not set breakpoint for address: ");
149 error->Address(m_addresses[i], sizeof(addr_t));
157 bool ThreadPlanRunToAddress::DoPlanExplainsStop(Event *event_ptr) {
158 return AtOurAddress();
161 bool ThreadPlanRunToAddress::ShouldStop(Event *event_ptr) {
162 return AtOurAddress();
165 bool ThreadPlanRunToAddress::StopOthers() { return m_stop_others; }
167 void ThreadPlanRunToAddress::SetStopOthers(bool new_value) {
168 m_stop_others = new_value;
171 StateType ThreadPlanRunToAddress::GetPlanRunState() { return eStateRunning; }
173 bool ThreadPlanRunToAddress::WillStop() { return true; }
175 bool ThreadPlanRunToAddress::MischiefManaged() {
176 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
178 if (AtOurAddress()) {
179 // Remove the breakpoint
180 size_t num_break_ids = m_break_ids.size();
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;
189 log->Printf("Completed run to address plan.");
190 ThreadPlan::MischiefManaged();
196 bool 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) {