]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Target / ThreadPlanRunToAddress.cpp
1 //===-- ThreadPlanRunToAddress.cpp ------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Target/ThreadPlanRunToAddress.h"
10 #include "lldb/Target/Process.h"
11 #include "lldb/Target/RegisterContext.h"
12 #include "lldb/Target/Target.h"
13 #include "lldb/Target/Thread.h"
14 #include "lldb/Utility/Log.h"
15 #include "lldb/Utility/Stream.h"
16
17 using namespace lldb;
18 using namespace lldb_private;
19
20 // ThreadPlanRunToAddress: Continue plan
21
22 ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread, Address &address,
23                                                bool stop_others)
24     : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
25                  eVoteNoOpinion, eVoteNoOpinion),
26       m_stop_others(stop_others), m_addresses(), m_break_ids() {
27   m_addresses.push_back(
28       address.GetOpcodeLoadAddress(m_thread.CalculateTarget().get()));
29   SetInitialBreakpoints();
30 }
31
32 ThreadPlanRunToAddress::ThreadPlanRunToAddress(Thread &thread,
33                                                lldb::addr_t address,
34                                                bool stop_others)
35     : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
36                  eVoteNoOpinion, eVoteNoOpinion),
37       m_stop_others(stop_others), m_addresses(), m_break_ids() {
38   m_addresses.push_back(
39       m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
40   SetInitialBreakpoints();
41 }
42
43 ThreadPlanRunToAddress::ThreadPlanRunToAddress(
44     Thread &thread, const std::vector<lldb::addr_t> &addresses,
45     bool stop_others)
46     : ThreadPlan(ThreadPlan::eKindRunToAddress, "Run to address plan", thread,
47                  eVoteNoOpinion, eVoteNoOpinion),
48       m_stop_others(stop_others), m_addresses(addresses), m_break_ids() {
49   // Convert all addresses into opcode addresses to make sure we set
50   // breakpoints at the correct address.
51   Target &target = thread.GetProcess()->GetTarget();
52   std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
53   for (pos = m_addresses.begin(); pos != end; ++pos)
54     *pos = target.GetOpcodeLoadAddress(*pos);
55
56   SetInitialBreakpoints();
57 }
58
59 void ThreadPlanRunToAddress::SetInitialBreakpoints() {
60   size_t num_addresses = m_addresses.size();
61   m_break_ids.resize(num_addresses);
62
63   for (size_t i = 0; i < num_addresses; i++) {
64     Breakpoint *breakpoint;
65     breakpoint = m_thread.CalculateTarget()
66                      ->CreateBreakpoint(m_addresses[i], true, false)
67                      .get();
68     if (breakpoint != nullptr) {
69       if (breakpoint->IsHardware() && !breakpoint->HasResolvedLocations())
70         m_could_not_resolve_hw_bp = true;
71       m_break_ids[i] = breakpoint->GetID();
72       breakpoint->SetThreadID(m_thread.GetID());
73       breakpoint->SetBreakpointKind("run-to-address");
74     }
75   }
76 }
77
78 ThreadPlanRunToAddress::~ThreadPlanRunToAddress() {
79   size_t num_break_ids = m_break_ids.size();
80   for (size_t i = 0; i < num_break_ids; i++) {
81     m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]);
82   }
83   m_could_not_resolve_hw_bp = false;
84 }
85
86 void ThreadPlanRunToAddress::GetDescription(Stream *s,
87                                             lldb::DescriptionLevel level) {
88   size_t num_addresses = m_addresses.size();
89
90   if (level == lldb::eDescriptionLevelBrief) {
91     if (num_addresses == 0) {
92       s->Printf("run to address with no addresses given.");
93       return;
94     } else if (num_addresses == 1)
95       s->Printf("run to address: ");
96     else
97       s->Printf("run to addresses: ");
98
99     for (size_t i = 0; i < num_addresses; i++) {
100       s->Address(m_addresses[i], sizeof(addr_t));
101       s->Printf(" ");
102     }
103   } else {
104     if (num_addresses == 0) {
105       s->Printf("run to address with no addresses given.");
106       return;
107     } else if (num_addresses == 1)
108       s->Printf("Run to address: ");
109     else {
110       s->Printf("Run to addresses: ");
111     }
112
113     for (size_t i = 0; i < num_addresses; i++) {
114       if (num_addresses > 1) {
115         s->Printf("\n");
116         s->Indent();
117       }
118
119       s->Address(m_addresses[i], sizeof(addr_t));
120       s->Printf(" using breakpoint: %d - ", m_break_ids[i]);
121       Breakpoint *breakpoint =
122           m_thread.CalculateTarget()->GetBreakpointByID(m_break_ids[i]).get();
123       if (breakpoint)
124         breakpoint->Dump(s);
125       else
126         s->Printf("but the breakpoint has been deleted.");
127     }
128   }
129 }
130
131 bool ThreadPlanRunToAddress::ValidatePlan(Stream *error) {
132   if (m_could_not_resolve_hw_bp) {
133     if (error)
134       error->Printf("Could not set hardware breakpoint(s)");
135     return false;
136   }
137
138   // If we couldn't set the breakpoint for some reason, then this won't work.
139   bool all_bps_good = true;
140   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;
144       if (error) {
145         error->Printf("Could not set breakpoint for address: ");
146         error->Address(m_addresses[i], sizeof(addr_t));
147         error->Printf("\n");
148       }
149     }
150   }
151   return all_bps_good;
152 }
153
154 bool ThreadPlanRunToAddress::DoPlanExplainsStop(Event *event_ptr) {
155   return AtOurAddress();
156 }
157
158 bool ThreadPlanRunToAddress::ShouldStop(Event *event_ptr) {
159   return AtOurAddress();
160 }
161
162 bool ThreadPlanRunToAddress::StopOthers() { return m_stop_others; }
163
164 void ThreadPlanRunToAddress::SetStopOthers(bool new_value) {
165   m_stop_others = new_value;
166 }
167
168 StateType ThreadPlanRunToAddress::GetPlanRunState() { return eStateRunning; }
169
170 bool ThreadPlanRunToAddress::WillStop() { return true; }
171
172 bool ThreadPlanRunToAddress::MischiefManaged() {
173   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
174
175   if (AtOurAddress()) {
176     // Remove the breakpoint
177     size_t num_break_ids = m_break_ids.size();
178
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;
183       }
184     }
185     if (log)
186       log->Printf("Completed run to address plan.");
187     ThreadPlan::MischiefManaged();
188     return true;
189   } else
190     return false;
191 }
192
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) {
199       found_it = true;
200       break;
201     }
202   }
203   return found_it;
204 }