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 ®_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