xref: /openbsd-src/gnu/llvm/lldb/source/Host/common/NativeProcessProtocol.cpp (revision be691f3bb6417f04a68938fadbcaee2d5795e764)
1dda28197Spatrick //===-- NativeProcessProtocol.cpp -----------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "lldb/Host/common/NativeProcessProtocol.h"
10061da546Spatrick #include "lldb/Host/Host.h"
11061da546Spatrick #include "lldb/Host/common/NativeBreakpointList.h"
12061da546Spatrick #include "lldb/Host/common/NativeRegisterContext.h"
13061da546Spatrick #include "lldb/Host/common/NativeThreadProtocol.h"
14061da546Spatrick #include "lldb/Utility/LLDBAssert.h"
15061da546Spatrick #include "lldb/Utility/Log.h"
16061da546Spatrick #include "lldb/Utility/State.h"
17061da546Spatrick #include "lldb/lldb-enumerations.h"
18061da546Spatrick 
19061da546Spatrick #include "llvm/Support/Process.h"
20061da546Spatrick 
21061da546Spatrick using namespace lldb;
22061da546Spatrick using namespace lldb_private;
23061da546Spatrick 
24061da546Spatrick // NativeProcessProtocol Members
25061da546Spatrick 
26061da546Spatrick NativeProcessProtocol::NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
27061da546Spatrick                                              NativeDelegate &delegate)
28*be691f3bSpatrick     : m_pid(pid), m_delegate(delegate), m_terminal_fd(terminal_fd) {
29*be691f3bSpatrick   delegate.InitializeDelegate(this);
30061da546Spatrick }
31061da546Spatrick 
32061da546Spatrick lldb_private::Status NativeProcessProtocol::Interrupt() {
33061da546Spatrick   Status error;
34061da546Spatrick #if !defined(SIGSTOP)
35061da546Spatrick   error.SetErrorString("local host does not support signaling");
36061da546Spatrick   return error;
37061da546Spatrick #else
38061da546Spatrick   return Signal(SIGSTOP);
39061da546Spatrick #endif
40061da546Spatrick }
41061da546Spatrick 
42061da546Spatrick Status NativeProcessProtocol::IgnoreSignals(llvm::ArrayRef<int> signals) {
43061da546Spatrick   m_signals_to_ignore.clear();
44061da546Spatrick   m_signals_to_ignore.insert(signals.begin(), signals.end());
45061da546Spatrick   return Status();
46061da546Spatrick }
47061da546Spatrick 
48061da546Spatrick lldb_private::Status
49061da546Spatrick NativeProcessProtocol::GetMemoryRegionInfo(lldb::addr_t load_addr,
50061da546Spatrick                                            MemoryRegionInfo &range_info) {
51061da546Spatrick   // Default: not implemented.
52061da546Spatrick   return Status("not implemented");
53061da546Spatrick }
54061da546Spatrick 
55*be691f3bSpatrick lldb_private::Status
56*be691f3bSpatrick NativeProcessProtocol::ReadMemoryTags(int32_t type, lldb::addr_t addr,
57*be691f3bSpatrick                                       size_t len, std::vector<uint8_t> &tags) {
58*be691f3bSpatrick   return Status("not implemented");
59*be691f3bSpatrick }
60*be691f3bSpatrick 
61*be691f3bSpatrick lldb_private::Status
62*be691f3bSpatrick NativeProcessProtocol::WriteMemoryTags(int32_t type, lldb::addr_t addr,
63*be691f3bSpatrick                                        size_t len,
64*be691f3bSpatrick                                        const std::vector<uint8_t> &tags) {
65*be691f3bSpatrick   return Status("not implemented");
66*be691f3bSpatrick }
67*be691f3bSpatrick 
68061da546Spatrick llvm::Optional<WaitStatus> NativeProcessProtocol::GetExitStatus() {
69061da546Spatrick   if (m_state == lldb::eStateExited)
70061da546Spatrick     return m_exit_status;
71061da546Spatrick 
72061da546Spatrick   return llvm::None;
73061da546Spatrick }
74061da546Spatrick 
75061da546Spatrick bool NativeProcessProtocol::SetExitStatus(WaitStatus status,
76061da546Spatrick                                           bool bNotifyStateChange) {
77061da546Spatrick   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
78061da546Spatrick   LLDB_LOG(log, "status = {0}, notify = {1}", status, bNotifyStateChange);
79061da546Spatrick 
80061da546Spatrick   // Exit status already set
81061da546Spatrick   if (m_state == lldb::eStateExited) {
82061da546Spatrick     if (m_exit_status)
83061da546Spatrick       LLDB_LOG(log, "exit status already set to {0}", *m_exit_status);
84061da546Spatrick     else
85061da546Spatrick       LLDB_LOG(log, "state is exited, but status not set");
86061da546Spatrick     return false;
87061da546Spatrick   }
88061da546Spatrick 
89061da546Spatrick   m_state = lldb::eStateExited;
90061da546Spatrick   m_exit_status = status;
91061da546Spatrick 
92061da546Spatrick   if (bNotifyStateChange)
93061da546Spatrick     SynchronouslyNotifyProcessStateChanged(lldb::eStateExited);
94061da546Spatrick 
95061da546Spatrick   return true;
96061da546Spatrick }
97061da546Spatrick 
98061da546Spatrick NativeThreadProtocol *NativeProcessProtocol::GetThreadAtIndex(uint32_t idx) {
99061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
100061da546Spatrick   if (idx < m_threads.size())
101061da546Spatrick     return m_threads[idx].get();
102061da546Spatrick   return nullptr;
103061da546Spatrick }
104061da546Spatrick 
105061da546Spatrick NativeThreadProtocol *
106061da546Spatrick NativeProcessProtocol::GetThreadByIDUnlocked(lldb::tid_t tid) {
107061da546Spatrick   for (const auto &thread : m_threads) {
108061da546Spatrick     if (thread->GetID() == tid)
109061da546Spatrick       return thread.get();
110061da546Spatrick   }
111061da546Spatrick   return nullptr;
112061da546Spatrick }
113061da546Spatrick 
114061da546Spatrick NativeThreadProtocol *NativeProcessProtocol::GetThreadByID(lldb::tid_t tid) {
115061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
116061da546Spatrick   return GetThreadByIDUnlocked(tid);
117061da546Spatrick }
118061da546Spatrick 
119061da546Spatrick bool NativeProcessProtocol::IsAlive() const {
120061da546Spatrick   return m_state != eStateDetached && m_state != eStateExited &&
121061da546Spatrick          m_state != eStateInvalid && m_state != eStateUnloaded;
122061da546Spatrick }
123061da546Spatrick 
124061da546Spatrick const NativeWatchpointList::WatchpointMap &
125061da546Spatrick NativeProcessProtocol::GetWatchpointMap() const {
126061da546Spatrick   return m_watchpoint_list.GetWatchpointMap();
127061da546Spatrick }
128061da546Spatrick 
129061da546Spatrick llvm::Optional<std::pair<uint32_t, uint32_t>>
130061da546Spatrick NativeProcessProtocol::GetHardwareDebugSupportInfo() const {
131061da546Spatrick   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
132061da546Spatrick 
133061da546Spatrick   // get any thread
134061da546Spatrick   NativeThreadProtocol *thread(
135061da546Spatrick       const_cast<NativeProcessProtocol *>(this)->GetThreadAtIndex(0));
136061da546Spatrick   if (!thread) {
137061da546Spatrick     LLDB_LOG(log, "failed to find a thread to grab a NativeRegisterContext!");
138061da546Spatrick     return llvm::None;
139061da546Spatrick   }
140061da546Spatrick 
141061da546Spatrick   NativeRegisterContext &reg_ctx = thread->GetRegisterContext();
142061da546Spatrick   return std::make_pair(reg_ctx.NumSupportedHardwareBreakpoints(),
143061da546Spatrick                         reg_ctx.NumSupportedHardwareWatchpoints());
144061da546Spatrick }
145061da546Spatrick 
146061da546Spatrick Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
147061da546Spatrick                                             uint32_t watch_flags,
148061da546Spatrick                                             bool hardware) {
149061da546Spatrick   // This default implementation assumes setting the watchpoint for the process
150061da546Spatrick   // will require setting the watchpoint for each of the threads.  Furthermore,
151061da546Spatrick   // it will track watchpoints set for the process and will add them to each
152061da546Spatrick   // thread that is attached to via the (FIXME implement) OnThreadAttached ()
153061da546Spatrick   // method.
154061da546Spatrick 
155061da546Spatrick   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
156061da546Spatrick 
157061da546Spatrick   // Update the thread list
158061da546Spatrick   UpdateThreads();
159061da546Spatrick 
160061da546Spatrick   // Keep track of the threads we successfully set the watchpoint for.  If one
161061da546Spatrick   // of the thread watchpoint setting operations fails, back off and remove the
162061da546Spatrick   // watchpoint for all the threads that were successfully set so we get back
163061da546Spatrick   // to a consistent state.
164061da546Spatrick   std::vector<NativeThreadProtocol *> watchpoint_established_threads;
165061da546Spatrick 
166061da546Spatrick   // Tell each thread to set a watchpoint.  In the event that hardware
167061da546Spatrick   // watchpoints are requested but the SetWatchpoint fails, try to set a
168061da546Spatrick   // software watchpoint as a fallback.  It's conceivable that if there are
169061da546Spatrick   // more threads than hardware watchpoints available, some of the threads will
170061da546Spatrick   // fail to set hardware watchpoints while software ones may be available.
171061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
172061da546Spatrick   for (const auto &thread : m_threads) {
173061da546Spatrick     assert(thread && "thread list should not have a NULL thread!");
174061da546Spatrick 
175061da546Spatrick     Status thread_error =
176061da546Spatrick         thread->SetWatchpoint(addr, size, watch_flags, hardware);
177061da546Spatrick     if (thread_error.Fail() && hardware) {
178061da546Spatrick       // Try software watchpoints since we failed on hardware watchpoint
179061da546Spatrick       // setting and we may have just run out of hardware watchpoints.
180061da546Spatrick       thread_error = thread->SetWatchpoint(addr, size, watch_flags, false);
181061da546Spatrick       if (thread_error.Success())
182061da546Spatrick         LLDB_LOG(log,
183061da546Spatrick                  "hardware watchpoint requested but software watchpoint set");
184061da546Spatrick     }
185061da546Spatrick 
186061da546Spatrick     if (thread_error.Success()) {
187061da546Spatrick       // Remember that we set this watchpoint successfully in case we need to
188061da546Spatrick       // clear it later.
189061da546Spatrick       watchpoint_established_threads.push_back(thread.get());
190061da546Spatrick     } else {
191061da546Spatrick       // Unset the watchpoint for each thread we successfully set so that we
192061da546Spatrick       // get back to a consistent state of "not set" for the watchpoint.
193061da546Spatrick       for (auto unwatch_thread_sp : watchpoint_established_threads) {
194061da546Spatrick         Status remove_error = unwatch_thread_sp->RemoveWatchpoint(addr);
195061da546Spatrick         if (remove_error.Fail())
196061da546Spatrick           LLDB_LOG(log, "RemoveWatchpoint failed for pid={0}, tid={1}: {2}",
197061da546Spatrick                    GetID(), unwatch_thread_sp->GetID(), remove_error);
198061da546Spatrick       }
199061da546Spatrick 
200061da546Spatrick       return thread_error;
201061da546Spatrick     }
202061da546Spatrick   }
203061da546Spatrick   return m_watchpoint_list.Add(addr, size, watch_flags, hardware);
204061da546Spatrick }
205061da546Spatrick 
206061da546Spatrick Status NativeProcessProtocol::RemoveWatchpoint(lldb::addr_t addr) {
207061da546Spatrick   // Update the thread list
208061da546Spatrick   UpdateThreads();
209061da546Spatrick 
210061da546Spatrick   Status overall_error;
211061da546Spatrick 
212061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
213061da546Spatrick   for (const auto &thread : m_threads) {
214061da546Spatrick     assert(thread && "thread list should not have a NULL thread!");
215061da546Spatrick 
216061da546Spatrick     const Status thread_error = thread->RemoveWatchpoint(addr);
217061da546Spatrick     if (thread_error.Fail()) {
218061da546Spatrick       // Keep track of the first thread error if any threads fail. We want to
219061da546Spatrick       // try to remove the watchpoint from every thread, though, even if one or
220061da546Spatrick       // more have errors.
221061da546Spatrick       if (!overall_error.Fail())
222061da546Spatrick         overall_error = thread_error;
223061da546Spatrick     }
224061da546Spatrick   }
225061da546Spatrick   const Status error = m_watchpoint_list.Remove(addr);
226061da546Spatrick   return overall_error.Fail() ? overall_error : error;
227061da546Spatrick }
228061da546Spatrick 
229061da546Spatrick const HardwareBreakpointMap &
230061da546Spatrick NativeProcessProtocol::GetHardwareBreakpointMap() const {
231061da546Spatrick   return m_hw_breakpoints_map;
232061da546Spatrick }
233061da546Spatrick 
234061da546Spatrick Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,
235061da546Spatrick                                                     size_t size) {
236061da546Spatrick   // This default implementation assumes setting a hardware breakpoint for this
237061da546Spatrick   // process will require setting same hardware breakpoint for each of its
238061da546Spatrick   // existing threads. New thread will do the same once created.
239061da546Spatrick   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
240061da546Spatrick 
241061da546Spatrick   // Update the thread list
242061da546Spatrick   UpdateThreads();
243061da546Spatrick 
244061da546Spatrick   // Exit here if target does not have required hardware breakpoint capability.
245061da546Spatrick   auto hw_debug_cap = GetHardwareDebugSupportInfo();
246061da546Spatrick 
247061da546Spatrick   if (hw_debug_cap == llvm::None || hw_debug_cap->first == 0 ||
248061da546Spatrick       hw_debug_cap->first <= m_hw_breakpoints_map.size())
249061da546Spatrick     return Status("Target does not have required no of hardware breakpoints");
250061da546Spatrick 
251061da546Spatrick   // Vector below stores all thread pointer for which we have we successfully
252061da546Spatrick   // set this hardware breakpoint. If any of the current process threads fails
253061da546Spatrick   // to set this hardware breakpoint then roll back and remove this breakpoint
254061da546Spatrick   // for all the threads that had already set it successfully.
255061da546Spatrick   std::vector<NativeThreadProtocol *> breakpoint_established_threads;
256061da546Spatrick 
257061da546Spatrick   // Request to set a hardware breakpoint for each of current process threads.
258061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
259061da546Spatrick   for (const auto &thread : m_threads) {
260061da546Spatrick     assert(thread && "thread list should not have a NULL thread!");
261061da546Spatrick 
262061da546Spatrick     Status thread_error = thread->SetHardwareBreakpoint(addr, size);
263061da546Spatrick     if (thread_error.Success()) {
264061da546Spatrick       // Remember that we set this breakpoint successfully in case we need to
265061da546Spatrick       // clear it later.
266061da546Spatrick       breakpoint_established_threads.push_back(thread.get());
267061da546Spatrick     } else {
268061da546Spatrick       // Unset the breakpoint for each thread we successfully set so that we
269061da546Spatrick       // get back to a consistent state of "not set" for this hardware
270061da546Spatrick       // breakpoint.
271061da546Spatrick       for (auto rollback_thread_sp : breakpoint_established_threads) {
272061da546Spatrick         Status remove_error =
273061da546Spatrick             rollback_thread_sp->RemoveHardwareBreakpoint(addr);
274061da546Spatrick         if (remove_error.Fail())
275061da546Spatrick           LLDB_LOG(log,
276061da546Spatrick                    "RemoveHardwareBreakpoint failed for pid={0}, tid={1}: {2}",
277061da546Spatrick                    GetID(), rollback_thread_sp->GetID(), remove_error);
278061da546Spatrick       }
279061da546Spatrick 
280061da546Spatrick       return thread_error;
281061da546Spatrick     }
282061da546Spatrick   }
283061da546Spatrick 
284061da546Spatrick   // Register new hardware breakpoint into hardware breakpoints map of current
285061da546Spatrick   // process.
286061da546Spatrick   m_hw_breakpoints_map[addr] = {addr, size};
287061da546Spatrick 
288061da546Spatrick   return Status();
289061da546Spatrick }
290061da546Spatrick 
291061da546Spatrick Status NativeProcessProtocol::RemoveHardwareBreakpoint(lldb::addr_t addr) {
292061da546Spatrick   // Update the thread list
293061da546Spatrick   UpdateThreads();
294061da546Spatrick 
295061da546Spatrick   Status error;
296061da546Spatrick 
297061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
298061da546Spatrick   for (const auto &thread : m_threads) {
299061da546Spatrick     assert(thread && "thread list should not have a NULL thread!");
300061da546Spatrick     error = thread->RemoveHardwareBreakpoint(addr);
301061da546Spatrick   }
302061da546Spatrick 
303061da546Spatrick   // Also remove from hardware breakpoint map of current process.
304061da546Spatrick   m_hw_breakpoints_map.erase(addr);
305061da546Spatrick 
306061da546Spatrick   return error;
307061da546Spatrick }
308061da546Spatrick 
309061da546Spatrick void NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged(
310061da546Spatrick     lldb::StateType state) {
311061da546Spatrick   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
312061da546Spatrick 
313*be691f3bSpatrick   m_delegate.ProcessStateChanged(this, state);
314061da546Spatrick 
315*be691f3bSpatrick   LLDB_LOG(log, "sent state notification [{0}] from process {1}", state,
316*be691f3bSpatrick            GetID());
317061da546Spatrick }
318061da546Spatrick 
319061da546Spatrick void NativeProcessProtocol::NotifyDidExec() {
320061da546Spatrick   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
321*be691f3bSpatrick   LLDB_LOG(log, "process {0} exec()ed", GetID());
322061da546Spatrick 
323*be691f3bSpatrick   m_delegate.DidExec(this);
324061da546Spatrick }
325061da546Spatrick 
326061da546Spatrick Status NativeProcessProtocol::SetSoftwareBreakpoint(lldb::addr_t addr,
327061da546Spatrick                                                     uint32_t size_hint) {
328061da546Spatrick   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
329061da546Spatrick   LLDB_LOG(log, "addr = {0:x}, size_hint = {1}", addr, size_hint);
330061da546Spatrick 
331061da546Spatrick   auto it = m_software_breakpoints.find(addr);
332061da546Spatrick   if (it != m_software_breakpoints.end()) {
333061da546Spatrick     ++it->second.ref_count;
334061da546Spatrick     return Status();
335061da546Spatrick   }
336061da546Spatrick   auto expected_bkpt = EnableSoftwareBreakpoint(addr, size_hint);
337061da546Spatrick   if (!expected_bkpt)
338061da546Spatrick     return Status(expected_bkpt.takeError());
339061da546Spatrick 
340061da546Spatrick   m_software_breakpoints.emplace(addr, std::move(*expected_bkpt));
341061da546Spatrick   return Status();
342061da546Spatrick }
343061da546Spatrick 
344061da546Spatrick Status NativeProcessProtocol::RemoveSoftwareBreakpoint(lldb::addr_t addr) {
345061da546Spatrick   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
346061da546Spatrick   LLDB_LOG(log, "addr = {0:x}", addr);
347061da546Spatrick   auto it = m_software_breakpoints.find(addr);
348061da546Spatrick   if (it == m_software_breakpoints.end())
349061da546Spatrick     return Status("Breakpoint not found.");
350061da546Spatrick   assert(it->second.ref_count > 0);
351061da546Spatrick   if (--it->second.ref_count > 0)
352061da546Spatrick     return Status();
353061da546Spatrick 
354061da546Spatrick   // This is the last reference. Let's remove the breakpoint.
355061da546Spatrick   Status error;
356061da546Spatrick 
357061da546Spatrick   // Clear a software breakpoint instruction
358061da546Spatrick   llvm::SmallVector<uint8_t, 4> curr_break_op(
359061da546Spatrick       it->second.breakpoint_opcodes.size(), 0);
360061da546Spatrick 
361061da546Spatrick   // Read the breakpoint opcode
362061da546Spatrick   size_t bytes_read = 0;
363061da546Spatrick   error =
364061da546Spatrick       ReadMemory(addr, curr_break_op.data(), curr_break_op.size(), bytes_read);
365061da546Spatrick   if (error.Fail() || bytes_read < curr_break_op.size()) {
366061da546Spatrick     return Status("addr=0x%" PRIx64
367061da546Spatrick                   ": tried to read %zu bytes but only read %zu",
368061da546Spatrick                   addr, curr_break_op.size(), bytes_read);
369061da546Spatrick   }
370061da546Spatrick   const auto &saved = it->second.saved_opcodes;
371061da546Spatrick   // Make sure the breakpoint opcode exists at this address
372061da546Spatrick   if (makeArrayRef(curr_break_op) != it->second.breakpoint_opcodes) {
373061da546Spatrick     if (curr_break_op != it->second.saved_opcodes)
374061da546Spatrick       return Status("Original breakpoint trap is no longer in memory.");
375061da546Spatrick     LLDB_LOG(log,
376061da546Spatrick              "Saved opcodes ({0:@[x]}) have already been restored at {1:x}.",
377061da546Spatrick              llvm::make_range(saved.begin(), saved.end()), addr);
378061da546Spatrick   } else {
379061da546Spatrick     // We found a valid breakpoint opcode at this address, now restore the
380061da546Spatrick     // saved opcode.
381061da546Spatrick     size_t bytes_written = 0;
382061da546Spatrick     error = WriteMemory(addr, saved.data(), saved.size(), bytes_written);
383061da546Spatrick     if (error.Fail() || bytes_written < saved.size()) {
384061da546Spatrick       return Status("addr=0x%" PRIx64
385061da546Spatrick                     ": tried to write %zu bytes but only wrote %zu",
386061da546Spatrick                     addr, saved.size(), bytes_written);
387061da546Spatrick     }
388061da546Spatrick 
389061da546Spatrick     // Verify that our original opcode made it back to the inferior
390061da546Spatrick     llvm::SmallVector<uint8_t, 4> verify_opcode(saved.size(), 0);
391061da546Spatrick     size_t verify_bytes_read = 0;
392061da546Spatrick     error = ReadMemory(addr, verify_opcode.data(), verify_opcode.size(),
393061da546Spatrick                        verify_bytes_read);
394061da546Spatrick     if (error.Fail() || verify_bytes_read < verify_opcode.size()) {
395061da546Spatrick       return Status("addr=0x%" PRIx64
396061da546Spatrick                     ": tried to read %zu verification bytes but only read %zu",
397061da546Spatrick                     addr, verify_opcode.size(), verify_bytes_read);
398061da546Spatrick     }
399061da546Spatrick     if (verify_opcode != saved)
400061da546Spatrick       LLDB_LOG(log, "Restoring bytes at {0:x}: {1:@[x]}", addr,
401061da546Spatrick                llvm::make_range(saved.begin(), saved.end()));
402061da546Spatrick   }
403061da546Spatrick 
404061da546Spatrick   m_software_breakpoints.erase(it);
405061da546Spatrick   return Status();
406061da546Spatrick }
407061da546Spatrick 
408061da546Spatrick llvm::Expected<NativeProcessProtocol::SoftwareBreakpoint>
409061da546Spatrick NativeProcessProtocol::EnableSoftwareBreakpoint(lldb::addr_t addr,
410061da546Spatrick                                                 uint32_t size_hint) {
411061da546Spatrick   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
412061da546Spatrick 
413061da546Spatrick   auto expected_trap = GetSoftwareBreakpointTrapOpcode(size_hint);
414061da546Spatrick   if (!expected_trap)
415061da546Spatrick     return expected_trap.takeError();
416061da546Spatrick 
417061da546Spatrick   llvm::SmallVector<uint8_t, 4> saved_opcode_bytes(expected_trap->size(), 0);
418061da546Spatrick   // Save the original opcodes by reading them so we can restore later.
419061da546Spatrick   size_t bytes_read = 0;
420061da546Spatrick   Status error = ReadMemory(addr, saved_opcode_bytes.data(),
421061da546Spatrick                             saved_opcode_bytes.size(), bytes_read);
422061da546Spatrick   if (error.Fail())
423061da546Spatrick     return error.ToError();
424061da546Spatrick 
425061da546Spatrick   // Ensure we read as many bytes as we expected.
426061da546Spatrick   if (bytes_read != saved_opcode_bytes.size()) {
427061da546Spatrick     return llvm::createStringError(
428061da546Spatrick         llvm::inconvertibleErrorCode(),
429061da546Spatrick         "Failed to read memory while attempting to set breakpoint: attempted "
430061da546Spatrick         "to read {0} bytes but only read {1}.",
431061da546Spatrick         saved_opcode_bytes.size(), bytes_read);
432061da546Spatrick   }
433061da546Spatrick 
434061da546Spatrick   LLDB_LOG(
435061da546Spatrick       log, "Overwriting bytes at {0:x}: {1:@[x]}", addr,
436061da546Spatrick       llvm::make_range(saved_opcode_bytes.begin(), saved_opcode_bytes.end()));
437061da546Spatrick 
438061da546Spatrick   // Write a software breakpoint in place of the original opcode.
439061da546Spatrick   size_t bytes_written = 0;
440061da546Spatrick   error = WriteMemory(addr, expected_trap->data(), expected_trap->size(),
441061da546Spatrick                       bytes_written);
442061da546Spatrick   if (error.Fail())
443061da546Spatrick     return error.ToError();
444061da546Spatrick 
445061da546Spatrick   // Ensure we wrote as many bytes as we expected.
446061da546Spatrick   if (bytes_written != expected_trap->size()) {
447061da546Spatrick     return llvm::createStringError(
448061da546Spatrick         llvm::inconvertibleErrorCode(),
449061da546Spatrick         "Failed write memory while attempting to set "
450061da546Spatrick         "breakpoint: attempted to write {0} bytes but only wrote {1}",
451061da546Spatrick         expected_trap->size(), bytes_written);
452061da546Spatrick   }
453061da546Spatrick 
454061da546Spatrick   llvm::SmallVector<uint8_t, 4> verify_bp_opcode_bytes(expected_trap->size(),
455061da546Spatrick                                                        0);
456061da546Spatrick   size_t verify_bytes_read = 0;
457061da546Spatrick   error = ReadMemory(addr, verify_bp_opcode_bytes.data(),
458061da546Spatrick                      verify_bp_opcode_bytes.size(), verify_bytes_read);
459061da546Spatrick   if (error.Fail())
460061da546Spatrick     return error.ToError();
461061da546Spatrick 
462061da546Spatrick   // Ensure we read as many verification bytes as we expected.
463061da546Spatrick   if (verify_bytes_read != verify_bp_opcode_bytes.size()) {
464061da546Spatrick     return llvm::createStringError(
465061da546Spatrick         llvm::inconvertibleErrorCode(),
466061da546Spatrick         "Failed to read memory while "
467061da546Spatrick         "attempting to verify breakpoint: attempted to read {0} bytes "
468061da546Spatrick         "but only read {1}",
469061da546Spatrick         verify_bp_opcode_bytes.size(), verify_bytes_read);
470061da546Spatrick   }
471061da546Spatrick 
472061da546Spatrick   if (llvm::makeArrayRef(verify_bp_opcode_bytes.data(), verify_bytes_read) !=
473061da546Spatrick       *expected_trap) {
474061da546Spatrick     return llvm::createStringError(
475061da546Spatrick         llvm::inconvertibleErrorCode(),
476061da546Spatrick         "Verification of software breakpoint "
477061da546Spatrick         "writing failed - trap opcodes not successfully read back "
478061da546Spatrick         "after writing when setting breakpoint at {0:x}",
479061da546Spatrick         addr);
480061da546Spatrick   }
481061da546Spatrick 
482061da546Spatrick   LLDB_LOG(log, "addr = {0:x}: SUCCESS", addr);
483061da546Spatrick   return SoftwareBreakpoint{1, saved_opcode_bytes, *expected_trap};
484061da546Spatrick }
485061da546Spatrick 
486061da546Spatrick llvm::Expected<llvm::ArrayRef<uint8_t>>
487061da546Spatrick NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
488061da546Spatrick   static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
489061da546Spatrick   static const uint8_t g_i386_opcode[] = {0xCC};
490061da546Spatrick   static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d};
491061da546Spatrick   static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
492061da546Spatrick   static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
493*be691f3bSpatrick   static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; // trap
494*be691f3bSpatrick   static const uint8_t g_ppcle_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
495061da546Spatrick 
496061da546Spatrick   switch (GetArchitecture().GetMachine()) {
497061da546Spatrick   case llvm::Triple::aarch64:
498061da546Spatrick   case llvm::Triple::aarch64_32:
499061da546Spatrick     return llvm::makeArrayRef(g_aarch64_opcode);
500061da546Spatrick 
501061da546Spatrick   case llvm::Triple::x86:
502061da546Spatrick   case llvm::Triple::x86_64:
503061da546Spatrick     return llvm::makeArrayRef(g_i386_opcode);
504061da546Spatrick 
505061da546Spatrick   case llvm::Triple::mips:
506061da546Spatrick   case llvm::Triple::mips64:
507061da546Spatrick     return llvm::makeArrayRef(g_mips64_opcode);
508061da546Spatrick 
509061da546Spatrick   case llvm::Triple::mipsel:
510061da546Spatrick   case llvm::Triple::mips64el:
511061da546Spatrick     return llvm::makeArrayRef(g_mips64el_opcode);
512061da546Spatrick 
513061da546Spatrick   case llvm::Triple::systemz:
514061da546Spatrick     return llvm::makeArrayRef(g_s390x_opcode);
515061da546Spatrick 
516*be691f3bSpatrick   case llvm::Triple::ppc:
517*be691f3bSpatrick   case llvm::Triple::ppc64:
518*be691f3bSpatrick     return llvm::makeArrayRef(g_ppc_opcode);
519*be691f3bSpatrick 
520061da546Spatrick   case llvm::Triple::ppc64le:
521*be691f3bSpatrick     return llvm::makeArrayRef(g_ppcle_opcode);
522061da546Spatrick 
523061da546Spatrick   default:
524061da546Spatrick     return llvm::createStringError(llvm::inconvertibleErrorCode(),
525061da546Spatrick                                    "CPU type not supported!");
526061da546Spatrick   }
527061da546Spatrick }
528061da546Spatrick 
529061da546Spatrick size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() {
530061da546Spatrick   switch (GetArchitecture().GetMachine()) {
531061da546Spatrick   case llvm::Triple::x86:
532061da546Spatrick   case llvm::Triple::x86_64:
533061da546Spatrick   case llvm::Triple::systemz:
534061da546Spatrick     // These architectures report increment the PC after breakpoint is hit.
535061da546Spatrick     return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();
536061da546Spatrick 
537061da546Spatrick   case llvm::Triple::arm:
538061da546Spatrick   case llvm::Triple::aarch64:
539061da546Spatrick   case llvm::Triple::aarch64_32:
540061da546Spatrick   case llvm::Triple::mips64:
541061da546Spatrick   case llvm::Triple::mips64el:
542061da546Spatrick   case llvm::Triple::mips:
543061da546Spatrick   case llvm::Triple::mipsel:
544*be691f3bSpatrick   case llvm::Triple::ppc:
545*be691f3bSpatrick   case llvm::Triple::ppc64:
546061da546Spatrick   case llvm::Triple::ppc64le:
547061da546Spatrick     // On these architectures the PC doesn't get updated for breakpoint hits.
548061da546Spatrick     return 0;
549061da546Spatrick 
550061da546Spatrick   default:
551061da546Spatrick     llvm_unreachable("CPU type not supported!");
552061da546Spatrick   }
553061da546Spatrick }
554061da546Spatrick 
555061da546Spatrick void NativeProcessProtocol::FixupBreakpointPCAsNeeded(
556061da546Spatrick     NativeThreadProtocol &thread) {
557061da546Spatrick   Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
558061da546Spatrick 
559061da546Spatrick   Status error;
560061da546Spatrick 
561061da546Spatrick   // Find out the size of a breakpoint (might depend on where we are in the
562061da546Spatrick   // code).
563061da546Spatrick   NativeRegisterContext &context = thread.GetRegisterContext();
564061da546Spatrick 
565061da546Spatrick   uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset();
566061da546Spatrick   LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
567061da546Spatrick   if (breakpoint_size == 0)
568061da546Spatrick     return;
569061da546Spatrick 
570061da546Spatrick   // First try probing for a breakpoint at a software breakpoint location: PC -
571061da546Spatrick   // breakpoint size.
572061da546Spatrick   const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation();
573061da546Spatrick   lldb::addr_t breakpoint_addr = initial_pc_addr;
574061da546Spatrick   // Do not allow breakpoint probe to wrap around.
575061da546Spatrick   if (breakpoint_addr >= breakpoint_size)
576061da546Spatrick     breakpoint_addr -= breakpoint_size;
577061da546Spatrick 
578061da546Spatrick   if (m_software_breakpoints.count(breakpoint_addr) == 0) {
579061da546Spatrick     // We didn't find one at a software probe location.  Nothing to do.
580061da546Spatrick     LLDB_LOG(log,
581061da546Spatrick              "pid {0} no lldb software breakpoint found at current pc with "
582061da546Spatrick              "adjustment: {1}",
583061da546Spatrick              GetID(), breakpoint_addr);
584061da546Spatrick     return;
585061da546Spatrick   }
586061da546Spatrick 
587061da546Spatrick   //
588061da546Spatrick   // We have a software breakpoint and need to adjust the PC.
589061da546Spatrick   //
590061da546Spatrick 
591061da546Spatrick   // Change the program counter.
592061da546Spatrick   LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
593061da546Spatrick            thread.GetID(), initial_pc_addr, breakpoint_addr);
594061da546Spatrick 
595061da546Spatrick   error = context.SetPC(breakpoint_addr);
596061da546Spatrick   if (error.Fail()) {
597061da546Spatrick     // This can happen in case the process was killed between the time we read
598061da546Spatrick     // the PC and when we are updating it. There's nothing better to do than to
599061da546Spatrick     // swallow the error.
600061da546Spatrick     LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
601061da546Spatrick              thread.GetID(), error);
602061da546Spatrick   }
603061da546Spatrick }
604061da546Spatrick 
605061da546Spatrick Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr,
606061da546Spatrick                                                bool hardware) {
607061da546Spatrick   if (hardware)
608061da546Spatrick     return RemoveHardwareBreakpoint(addr);
609061da546Spatrick   else
610061da546Spatrick     return RemoveSoftwareBreakpoint(addr);
611061da546Spatrick }
612061da546Spatrick 
613061da546Spatrick Status NativeProcessProtocol::ReadMemoryWithoutTrap(lldb::addr_t addr,
614061da546Spatrick                                                     void *buf, size_t size,
615061da546Spatrick                                                     size_t &bytes_read) {
616061da546Spatrick   Status error = ReadMemory(addr, buf, size, bytes_read);
617061da546Spatrick   if (error.Fail())
618061da546Spatrick     return error;
619061da546Spatrick 
620061da546Spatrick   auto data =
621061da546Spatrick       llvm::makeMutableArrayRef(static_cast<uint8_t *>(buf), bytes_read);
622061da546Spatrick   for (const auto &pair : m_software_breakpoints) {
623061da546Spatrick     lldb::addr_t bp_addr = pair.first;
624061da546Spatrick     auto saved_opcodes = makeArrayRef(pair.second.saved_opcodes);
625061da546Spatrick 
626061da546Spatrick     if (bp_addr + saved_opcodes.size() < addr || addr + bytes_read <= bp_addr)
627dda28197Spatrick       continue; // Breakpoint not in range, ignore
628061da546Spatrick 
629061da546Spatrick     if (bp_addr < addr) {
630061da546Spatrick       saved_opcodes = saved_opcodes.drop_front(addr - bp_addr);
631061da546Spatrick       bp_addr = addr;
632061da546Spatrick     }
633061da546Spatrick     auto bp_data = data.drop_front(bp_addr - addr);
634061da546Spatrick     std::copy_n(saved_opcodes.begin(),
635061da546Spatrick                 std::min(saved_opcodes.size(), bp_data.size()),
636061da546Spatrick                 bp_data.begin());
637061da546Spatrick   }
638061da546Spatrick   return Status();
639061da546Spatrick }
640061da546Spatrick 
641061da546Spatrick llvm::Expected<llvm::StringRef>
642061da546Spatrick NativeProcessProtocol::ReadCStringFromMemory(lldb::addr_t addr, char *buffer,
643061da546Spatrick                                              size_t max_size,
644061da546Spatrick                                              size_t &total_bytes_read) {
645061da546Spatrick   static const size_t cache_line_size =
646061da546Spatrick       llvm::sys::Process::getPageSizeEstimate();
647061da546Spatrick   size_t bytes_read = 0;
648061da546Spatrick   size_t bytes_left = max_size;
649061da546Spatrick   addr_t curr_addr = addr;
650061da546Spatrick   size_t string_size;
651061da546Spatrick   char *curr_buffer = buffer;
652061da546Spatrick   total_bytes_read = 0;
653061da546Spatrick   Status status;
654061da546Spatrick 
655061da546Spatrick   while (bytes_left > 0 && status.Success()) {
656061da546Spatrick     addr_t cache_line_bytes_left =
657061da546Spatrick         cache_line_size - (curr_addr % cache_line_size);
658061da546Spatrick     addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
659061da546Spatrick     status = ReadMemory(curr_addr, static_cast<void *>(curr_buffer),
660061da546Spatrick                         bytes_to_read, bytes_read);
661061da546Spatrick 
662061da546Spatrick     if (bytes_read == 0)
663061da546Spatrick       break;
664061da546Spatrick 
665061da546Spatrick     void *str_end = std::memchr(curr_buffer, '\0', bytes_read);
666061da546Spatrick     if (str_end != nullptr) {
667061da546Spatrick       total_bytes_read =
668061da546Spatrick           static_cast<size_t>((static_cast<char *>(str_end) - buffer + 1));
669061da546Spatrick       status.Clear();
670061da546Spatrick       break;
671061da546Spatrick     }
672061da546Spatrick 
673061da546Spatrick     total_bytes_read += bytes_read;
674061da546Spatrick     curr_buffer += bytes_read;
675061da546Spatrick     curr_addr += bytes_read;
676061da546Spatrick     bytes_left -= bytes_read;
677061da546Spatrick   }
678061da546Spatrick 
679061da546Spatrick   string_size = total_bytes_read - 1;
680061da546Spatrick 
681061da546Spatrick   // Make sure we return a null terminated string.
682061da546Spatrick   if (bytes_left == 0 && max_size > 0 && buffer[max_size - 1] != '\0') {
683061da546Spatrick     buffer[max_size - 1] = '\0';
684061da546Spatrick     total_bytes_read--;
685061da546Spatrick   }
686061da546Spatrick 
687061da546Spatrick   if (!status.Success())
688061da546Spatrick     return status.ToError();
689061da546Spatrick 
690061da546Spatrick   return llvm::StringRef(buffer, string_size);
691061da546Spatrick }
692061da546Spatrick 
693061da546Spatrick lldb::StateType NativeProcessProtocol::GetState() const {
694061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
695061da546Spatrick   return m_state;
696061da546Spatrick }
697061da546Spatrick 
698061da546Spatrick void NativeProcessProtocol::SetState(lldb::StateType state,
699061da546Spatrick                                      bool notify_delegates) {
700061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
701061da546Spatrick 
702061da546Spatrick   if (state == m_state)
703061da546Spatrick     return;
704061da546Spatrick 
705061da546Spatrick   m_state = state;
706061da546Spatrick 
707061da546Spatrick   if (StateIsStoppedState(state, false)) {
708061da546Spatrick     ++m_stop_id;
709061da546Spatrick 
710061da546Spatrick     // Give process a chance to do any stop id bump processing, such as
711061da546Spatrick     // clearing cached data that is invalidated each time the process runs.
712061da546Spatrick     // Note if/when we support some threads running, we'll end up needing to
713061da546Spatrick     // manage this per thread and per process.
714061da546Spatrick     DoStopIDBumped(m_stop_id);
715061da546Spatrick   }
716061da546Spatrick 
717061da546Spatrick   // Optionally notify delegates of the state change.
718061da546Spatrick   if (notify_delegates)
719061da546Spatrick     SynchronouslyNotifyProcessStateChanged(state);
720061da546Spatrick }
721061da546Spatrick 
722061da546Spatrick uint32_t NativeProcessProtocol::GetStopID() const {
723061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
724061da546Spatrick   return m_stop_id;
725061da546Spatrick }
726061da546Spatrick 
727061da546Spatrick void NativeProcessProtocol::DoStopIDBumped(uint32_t /* newBumpId */) {
728061da546Spatrick   // Default implementation does nothing.
729061da546Spatrick }
730061da546Spatrick 
731061da546Spatrick NativeProcessProtocol::Factory::~Factory() = default;
732