776 lines · cpp
1//===-- NativeProcessProtocol.cpp -----------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Host/common/NativeProcessProtocol.h"10#include "lldb/Host/Host.h"11#include "lldb/Host/common/NativeBreakpointList.h"12#include "lldb/Host/common/NativeRegisterContext.h"13#include "lldb/Host/common/NativeThreadProtocol.h"14#include "lldb/Utility/LLDBAssert.h"15#include "lldb/Utility/LLDBLog.h"16#include "lldb/Utility/Log.h"17#include "lldb/Utility/State.h"18#include "lldb/lldb-enumerations.h"19 20#include "llvm/Support/Process.h"21#include <optional>22 23using namespace lldb;24using namespace lldb_private;25 26// NativeProcessProtocol Members27 28NativeProcessProtocol::NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,29 NativeDelegate &delegate)30 : m_pid(pid), m_delegate(delegate), m_terminal_fd(terminal_fd) {31 delegate.InitializeDelegate(this);32}33 34lldb_private::Status NativeProcessProtocol::Interrupt() {35 Status error;36#if !defined(SIGSTOP)37 error = Status::FromErrorString("local host does not support signaling");38 return error;39#else40 return Signal(SIGSTOP);41#endif42}43 44Status NativeProcessProtocol::IgnoreSignals(llvm::ArrayRef<int> signals) {45 m_signals_to_ignore.clear();46 m_signals_to_ignore.insert_range(signals);47 return Status();48}49 50lldb_private::Status51NativeProcessProtocol::GetMemoryRegionInfo(lldb::addr_t load_addr,52 MemoryRegionInfo &range_info) {53 // Default: not implemented.54 return Status::FromErrorString("not implemented");55}56 57lldb_private::Status58NativeProcessProtocol::ReadMemoryTags(int32_t type, lldb::addr_t addr,59 size_t len, std::vector<uint8_t> &tags) {60 return Status::FromErrorString("not implemented");61}62 63lldb_private::Status64NativeProcessProtocol::WriteMemoryTags(int32_t type, lldb::addr_t addr,65 size_t len,66 const std::vector<uint8_t> &tags) {67 return Status::FromErrorString("not implemented");68}69 70std::optional<WaitStatus> NativeProcessProtocol::GetExitStatus() {71 if (m_state == lldb::eStateExited)72 return m_exit_status;73 74 return std::nullopt;75}76 77bool NativeProcessProtocol::SetExitStatus(WaitStatus status,78 bool bNotifyStateChange) {79 Log *log = GetLog(LLDBLog::Process);80 LLDB_LOG(log, "status = {0}, notify = {1}", status, bNotifyStateChange);81 82 // Exit status already set83 if (m_state == lldb::eStateExited) {84 if (m_exit_status)85 LLDB_LOG(log, "exit status already set to {0}", *m_exit_status);86 else87 LLDB_LOG(log, "state is exited, but status not set");88 return false;89 }90 91 m_state = lldb::eStateExited;92 m_exit_status = status;93 94 if (bNotifyStateChange)95 SynchronouslyNotifyProcessStateChanged(lldb::eStateExited);96 97 return true;98}99 100NativeThreadProtocol *NativeProcessProtocol::GetThreadAtIndex(uint32_t idx) {101 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);102 if (idx < m_threads.size())103 return m_threads[idx].get();104 return nullptr;105}106 107NativeThreadProtocol *108NativeProcessProtocol::GetThreadByIDUnlocked(lldb::tid_t tid) {109 for (const auto &thread : m_threads) {110 if (thread->GetID() == tid)111 return thread.get();112 }113 return nullptr;114}115 116NativeThreadProtocol *NativeProcessProtocol::GetThreadByID(lldb::tid_t tid) {117 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);118 return GetThreadByIDUnlocked(tid);119}120 121bool NativeProcessProtocol::IsAlive() const {122 return m_state != eStateDetached && m_state != eStateExited &&123 m_state != eStateInvalid && m_state != eStateUnloaded;124}125 126const NativeWatchpointList::WatchpointMap &127NativeProcessProtocol::GetWatchpointMap() const {128 return m_watchpoint_list.GetWatchpointMap();129}130 131std::optional<std::pair<uint32_t, uint32_t>>132NativeProcessProtocol::GetHardwareDebugSupportInfo() const {133 Log *log = GetLog(LLDBLog::Process);134 135 // get any thread136 NativeThreadProtocol *thread(137 const_cast<NativeProcessProtocol *>(this)->GetThreadAtIndex(0));138 if (!thread) {139 LLDB_LOG(log, "failed to find a thread to grab a NativeRegisterContext!");140 return std::nullopt;141 }142 143 NativeRegisterContext ®_ctx = thread->GetRegisterContext();144 return std::make_pair(reg_ctx.NumSupportedHardwareBreakpoints(),145 reg_ctx.NumSupportedHardwareWatchpoints());146}147 148Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,149 uint32_t watch_flags,150 bool hardware) {151 // This default implementation assumes setting the watchpoint for the process152 // will require setting the watchpoint for each of the threads. Furthermore,153 // it will track watchpoints set for the process and will add them to each154 // thread that is attached to via the (FIXME implement) OnThreadAttached ()155 // method.156 157 Log *log = GetLog(LLDBLog::Process);158 159 // Update the thread list160 UpdateThreads();161 162 // Keep track of the threads we successfully set the watchpoint for. If one163 // of the thread watchpoint setting operations fails, back off and remove the164 // watchpoint for all the threads that were successfully set so we get back165 // to a consistent state.166 std::vector<NativeThreadProtocol *> watchpoint_established_threads;167 168 // Tell each thread to set a watchpoint. In the event that hardware169 // watchpoints are requested but the SetWatchpoint fails, try to set a170 // software watchpoint as a fallback. It's conceivable that if there are171 // more threads than hardware watchpoints available, some of the threads will172 // fail to set hardware watchpoints while software ones may be available.173 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);174 for (const auto &thread : m_threads) {175 assert(thread && "thread list should not have a NULL thread!");176 177 Status thread_error =178 thread->SetWatchpoint(addr, size, watch_flags, hardware);179 if (thread_error.Fail() && hardware) {180 // Try software watchpoints since we failed on hardware watchpoint181 // setting and we may have just run out of hardware watchpoints.182 thread_error = thread->SetWatchpoint(addr, size, watch_flags, false);183 if (thread_error.Success())184 LLDB_LOG(log,185 "hardware watchpoint requested but software watchpoint set");186 }187 188 if (thread_error.Success()) {189 // Remember that we set this watchpoint successfully in case we need to190 // clear it later.191 watchpoint_established_threads.push_back(thread.get());192 } else {193 // Unset the watchpoint for each thread we successfully set so that we194 // get back to a consistent state of "not set" for the watchpoint.195 for (auto unwatch_thread_sp : watchpoint_established_threads) {196 Status remove_error = unwatch_thread_sp->RemoveWatchpoint(addr);197 if (remove_error.Fail())198 LLDB_LOG(log, "RemoveWatchpoint failed for pid={0}, tid={1}: {2}",199 GetID(), unwatch_thread_sp->GetID(), remove_error);200 }201 202 return thread_error;203 }204 }205 return m_watchpoint_list.Add(addr, size, watch_flags, hardware);206}207 208Status NativeProcessProtocol::RemoveWatchpoint(lldb::addr_t addr) {209 // Update the thread list210 UpdateThreads();211 212 Status overall_error;213 214 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);215 for (const auto &thread : m_threads) {216 assert(thread && "thread list should not have a NULL thread!");217 218 Status thread_error = thread->RemoveWatchpoint(addr);219 if (thread_error.Fail()) {220 // Keep track of the first thread error if any threads fail. We want to221 // try to remove the watchpoint from every thread, though, even if one or222 // more have errors.223 if (!overall_error.Fail())224 overall_error = std::move(thread_error);225 }226 }227 Status error = m_watchpoint_list.Remove(addr);228 return overall_error.Fail() ? std::move(overall_error) : std::move(error);229}230 231const HardwareBreakpointMap &232NativeProcessProtocol::GetHardwareBreakpointMap() const {233 return m_hw_breakpoints_map;234}235 236Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,237 size_t size) {238 // This default implementation assumes setting a hardware breakpoint for this239 // process will require setting same hardware breakpoint for each of its240 // existing threads. New thread will do the same once created.241 Log *log = GetLog(LLDBLog::Process);242 243 // Update the thread list244 UpdateThreads();245 246 // Exit here if target does not have required hardware breakpoint capability.247 auto hw_debug_cap = GetHardwareDebugSupportInfo();248 249 if (hw_debug_cap == std::nullopt || hw_debug_cap->first == 0 ||250 hw_debug_cap->first <= m_hw_breakpoints_map.size())251 return Status::FromErrorString(252 "Target does not have required no of hardware breakpoints");253 254 // Vector below stores all thread pointer for which we have we successfully255 // set this hardware breakpoint. If any of the current process threads fails256 // to set this hardware breakpoint then roll back and remove this breakpoint257 // for all the threads that had already set it successfully.258 std::vector<NativeThreadProtocol *> breakpoint_established_threads;259 260 // Request to set a hardware breakpoint for each of current process threads.261 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);262 for (const auto &thread : m_threads) {263 assert(thread && "thread list should not have a NULL thread!");264 265 Status thread_error = thread->SetHardwareBreakpoint(addr, size);266 if (thread_error.Success()) {267 // Remember that we set this breakpoint successfully in case we need to268 // clear it later.269 breakpoint_established_threads.push_back(thread.get());270 } else {271 // Unset the breakpoint for each thread we successfully set so that we272 // get back to a consistent state of "not set" for this hardware273 // breakpoint.274 for (auto rollback_thread_sp : breakpoint_established_threads) {275 Status remove_error =276 rollback_thread_sp->RemoveHardwareBreakpoint(addr);277 if (remove_error.Fail())278 LLDB_LOG(log,279 "RemoveHardwareBreakpoint failed for pid={0}, tid={1}: {2}",280 GetID(), rollback_thread_sp->GetID(), remove_error);281 }282 283 return thread_error;284 }285 }286 287 // Register new hardware breakpoint into hardware breakpoints map of current288 // process.289 m_hw_breakpoints_map[addr] = {addr, size};290 291 return Status();292}293 294Status NativeProcessProtocol::RemoveHardwareBreakpoint(lldb::addr_t addr) {295 // Update the thread list296 UpdateThreads();297 298 Status error;299 300 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);301 for (const auto &thread : m_threads) {302 assert(thread && "thread list should not have a NULL thread!");303 error = thread->RemoveHardwareBreakpoint(addr);304 }305 306 // Also remove from hardware breakpoint map of current process.307 m_hw_breakpoints_map.erase(addr);308 309 return error;310}311 312void NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged(313 lldb::StateType state) {314 Log *log = GetLog(LLDBLog::Process);315 316 m_delegate.ProcessStateChanged(this, state);317 318 switch (state) {319 case eStateStopped:320 case eStateExited:321 case eStateCrashed:322 NotifyTracersProcessDidStop();323 break;324 default:325 break;326 }327 328 LLDB_LOG(log, "sent state notification [{0}] from process {1}", state,329 GetID());330}331 332void NativeProcessProtocol::NotifyDidExec() {333 Log *log = GetLog(LLDBLog::Process);334 LLDB_LOG(log, "process {0} exec()ed", GetID());335 336 m_software_breakpoints.clear();337 338 m_delegate.DidExec(this);339}340 341Status NativeProcessProtocol::SetSoftwareBreakpoint(lldb::addr_t addr,342 uint32_t size_hint) {343 Log *log = GetLog(LLDBLog::Breakpoints);344 LLDB_LOG(log, "addr = {0:x}, size_hint = {1}", addr, size_hint);345 346 auto it = m_software_breakpoints.find(addr);347 if (it != m_software_breakpoints.end()) {348 ++it->second.ref_count;349 return Status();350 }351 auto expected_bkpt = EnableSoftwareBreakpoint(addr, size_hint);352 if (!expected_bkpt)353 return Status::FromError(expected_bkpt.takeError());354 355 m_software_breakpoints.emplace(addr, std::move(*expected_bkpt));356 return Status();357}358 359Status NativeProcessProtocol::RemoveSoftwareBreakpoint(lldb::addr_t addr) {360 Log *log = GetLog(LLDBLog::Breakpoints);361 LLDB_LOG(log, "addr = {0:x}", addr);362 auto it = m_software_breakpoints.find(addr);363 if (it == m_software_breakpoints.end())364 return Status::FromErrorString("Breakpoint not found.");365 assert(it->second.ref_count > 0);366 if (--it->second.ref_count > 0)367 return Status();368 369 // Remove the entry from m_software_breakpoints rightaway, so that we don't370 // leave behind an entry with ref_count == 0 in case one of the following371 // conditions returns an error. The breakpoint is moved so that it can be372 // accessed below.373 SoftwareBreakpoint bkpt = std::move(it->second);374 m_software_breakpoints.erase(it);375 376 // This is the last reference. Let's remove the breakpoint.377 Status error;378 379 // Clear a software breakpoint instruction380 llvm::SmallVector<uint8_t, 4> curr_break_op(bkpt.breakpoint_opcodes.size(),381 0);382 383 // Read the breakpoint opcode384 size_t bytes_read = 0;385 error =386 ReadMemory(addr, curr_break_op.data(), curr_break_op.size(), bytes_read);387 if (error.Fail() || bytes_read < curr_break_op.size()) {388 return Status::FromErrorStringWithFormat(389 "addr=0x%" PRIx64 ": tried to read %zu bytes but only read %zu", addr,390 curr_break_op.size(), bytes_read);391 }392 const auto &saved = bkpt.saved_opcodes;393 // Make sure the breakpoint opcode exists at this address394 if (llvm::ArrayRef(curr_break_op) != bkpt.breakpoint_opcodes) {395 if (curr_break_op != bkpt.saved_opcodes)396 return Status::FromErrorString(397 "Original breakpoint trap is no longer in memory.");398 LLDB_LOG(log,399 "Saved opcodes ({0:@[x]}) have already been restored at {1:x}.",400 llvm::make_range(saved.begin(), saved.end()), addr);401 } else {402 // We found a valid breakpoint opcode at this address, now restore the403 // saved opcode.404 size_t bytes_written = 0;405 error = WriteMemory(addr, saved.data(), saved.size(), bytes_written);406 if (error.Fail() || bytes_written < saved.size()) {407 return Status::FromErrorStringWithFormat(408 "addr=0x%" PRIx64 ": tried to write %zu bytes but only wrote %zu",409 addr, saved.size(), bytes_written);410 }411 412 // Verify that our original opcode made it back to the inferior413 llvm::SmallVector<uint8_t, 4> verify_opcode(saved.size(), 0);414 size_t verify_bytes_read = 0;415 error = ReadMemory(addr, verify_opcode.data(), verify_opcode.size(),416 verify_bytes_read);417 if (error.Fail() || verify_bytes_read < verify_opcode.size()) {418 return Status::FromErrorStringWithFormat(419 "addr=0x%" PRIx64420 ": tried to read %zu verification bytes but only read %zu",421 addr, verify_opcode.size(), verify_bytes_read);422 }423 if (verify_opcode != saved)424 LLDB_LOG(log, "Restoring bytes at {0:x}: {1:@[x]}", addr,425 llvm::make_range(saved.begin(), saved.end()));426 }427 428 return Status();429}430 431llvm::Expected<NativeProcessProtocol::SoftwareBreakpoint>432NativeProcessProtocol::EnableSoftwareBreakpoint(lldb::addr_t addr,433 uint32_t size_hint) {434 Log *log = GetLog(LLDBLog::Breakpoints);435 436 auto expected_trap = GetSoftwareBreakpointTrapOpcode(size_hint);437 if (!expected_trap)438 return expected_trap.takeError();439 440 llvm::SmallVector<uint8_t, 4> saved_opcode_bytes(expected_trap->size(), 0);441 // Save the original opcodes by reading them so we can restore later.442 size_t bytes_read = 0;443 Status error = ReadMemory(addr, saved_opcode_bytes.data(),444 saved_opcode_bytes.size(), bytes_read);445 if (error.Fail())446 return error.ToError();447 448 // Ensure we read as many bytes as we expected.449 if (bytes_read != saved_opcode_bytes.size()) {450 return llvm::createStringError(451 llvm::inconvertibleErrorCode(),452 "Failed to read memory while attempting to set breakpoint: attempted "453 "to read {0} bytes but only read {1}.",454 saved_opcode_bytes.size(), bytes_read);455 }456 457 LLDB_LOG(458 log, "Overwriting bytes at {0:x}: {1:@[x]}", addr,459 llvm::make_range(saved_opcode_bytes.begin(), saved_opcode_bytes.end()));460 461 // Write a software breakpoint in place of the original opcode.462 size_t bytes_written = 0;463 error = WriteMemory(addr, expected_trap->data(), expected_trap->size(),464 bytes_written);465 if (error.Fail())466 return error.ToError();467 468 // Ensure we wrote as many bytes as we expected.469 if (bytes_written != expected_trap->size()) {470 return llvm::createStringError(471 llvm::inconvertibleErrorCode(),472 "Failed write memory while attempting to set "473 "breakpoint: attempted to write {0} bytes but only wrote {1}",474 expected_trap->size(), bytes_written);475 }476 477 llvm::SmallVector<uint8_t, 4> verify_bp_opcode_bytes(expected_trap->size(),478 0);479 size_t verify_bytes_read = 0;480 error = ReadMemory(addr, verify_bp_opcode_bytes.data(),481 verify_bp_opcode_bytes.size(), verify_bytes_read);482 if (error.Fail())483 return error.ToError();484 485 // Ensure we read as many verification bytes as we expected.486 if (verify_bytes_read != verify_bp_opcode_bytes.size()) {487 return llvm::createStringError(488 llvm::inconvertibleErrorCode(),489 "Failed to read memory while "490 "attempting to verify breakpoint: attempted to read {0} bytes "491 "but only read {1}",492 verify_bp_opcode_bytes.size(), verify_bytes_read);493 }494 495 if (llvm::ArrayRef(verify_bp_opcode_bytes.data(), verify_bytes_read) !=496 *expected_trap) {497 return llvm::createStringError(498 llvm::inconvertibleErrorCode(),499 "Verification of software breakpoint "500 "writing failed - trap opcodes not successfully read back "501 "after writing when setting breakpoint at {0:x}",502 addr);503 }504 505 LLDB_LOG(log, "addr = {0:x}: SUCCESS", addr);506 return SoftwareBreakpoint{1, saved_opcode_bytes, *expected_trap};507}508 509llvm::Expected<llvm::ArrayRef<uint8_t>>510NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {511 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};512 static const uint8_t g_i386_opcode[] = {0xCC};513 static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d};514 static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};515 static const uint8_t g_msp430_opcode[] = {0x43, 0x43};516 static const uint8_t g_s390x_opcode[] = {0x00, 0x01};517 static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; // trap518 static const uint8_t g_ppcle_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap519 static const uint8_t g_riscv_opcode[] = {0x73, 0x00, 0x10, 0x00}; // ebreak520 static const uint8_t g_riscv_opcode_c[] = {0x02, 0x90}; // c.ebreak521 static const uint8_t g_loongarch_opcode[] = {0x05, 0x00, 0x2a,522 0x00}; // break 0x5523 524 switch (GetArchitecture().GetMachine()) {525 case llvm::Triple::aarch64:526 case llvm::Triple::aarch64_32:527 return llvm::ArrayRef(g_aarch64_opcode);528 529 case llvm::Triple::x86:530 case llvm::Triple::x86_64:531 return llvm::ArrayRef(g_i386_opcode);532 533 case llvm::Triple::mips:534 case llvm::Triple::mips64:535 return llvm::ArrayRef(g_mips64_opcode);536 537 case llvm::Triple::mipsel:538 case llvm::Triple::mips64el:539 return llvm::ArrayRef(g_mips64el_opcode);540 541 case llvm::Triple::msp430:542 return llvm::ArrayRef(g_msp430_opcode);543 544 case llvm::Triple::systemz:545 return llvm::ArrayRef(g_s390x_opcode);546 547 case llvm::Triple::ppc:548 case llvm::Triple::ppc64:549 return llvm::ArrayRef(g_ppc_opcode);550 551 case llvm::Triple::ppc64le:552 return llvm::ArrayRef(g_ppcle_opcode);553 554 case llvm::Triple::riscv32:555 case llvm::Triple::riscv64: {556 return size_hint == 2 ? llvm::ArrayRef(g_riscv_opcode_c)557 : llvm::ArrayRef(g_riscv_opcode);558 }559 560 case llvm::Triple::loongarch32:561 case llvm::Triple::loongarch64:562 return llvm::ArrayRef(g_loongarch_opcode);563 564 default:565 return llvm::createStringError(llvm::inconvertibleErrorCode(),566 "CPU type not supported!");567 }568}569 570size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() {571 switch (GetArchitecture().GetMachine()) {572 case llvm::Triple::x86:573 case llvm::Triple::x86_64:574 case llvm::Triple::systemz:575 // These architectures report increment the PC after breakpoint is hit.576 return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();577 578 case llvm::Triple::arm:579 case llvm::Triple::aarch64:580 case llvm::Triple::aarch64_32:581 case llvm::Triple::mips64:582 case llvm::Triple::mips64el:583 case llvm::Triple::mips:584 case llvm::Triple::mipsel:585 case llvm::Triple::ppc:586 case llvm::Triple::ppc64:587 case llvm::Triple::ppc64le:588 case llvm::Triple::riscv32:589 case llvm::Triple::riscv64:590 case llvm::Triple::loongarch32:591 case llvm::Triple::loongarch64:592 // On these architectures the PC doesn't get updated for breakpoint hits.593 return 0;594 595 default:596 llvm_unreachable("CPU type not supported!");597 }598}599 600void NativeProcessProtocol::FixupBreakpointPCAsNeeded(601 NativeThreadProtocol &thread) {602 Log *log = GetLog(LLDBLog::Breakpoints);603 604 Status error;605 606 // Find out the size of a breakpoint (might depend on where we are in the607 // code).608 NativeRegisterContext &context = thread.GetRegisterContext();609 610 uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset();611 LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);612 if (breakpoint_size == 0)613 return;614 615 // First try probing for a breakpoint at a software breakpoint location: PC -616 // breakpoint size.617 const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation();618 lldb::addr_t breakpoint_addr = initial_pc_addr;619 // Do not allow breakpoint probe to wrap around.620 if (breakpoint_addr >= breakpoint_size)621 breakpoint_addr -= breakpoint_size;622 623 if (m_software_breakpoints.count(breakpoint_addr) == 0) {624 // We didn't find one at a software probe location. Nothing to do.625 LLDB_LOG(log,626 "pid {0} no lldb software breakpoint found at current pc with "627 "adjustment: {1}",628 GetID(), breakpoint_addr);629 return;630 }631 632 //633 // We have a software breakpoint and need to adjust the PC.634 //635 636 // Change the program counter.637 LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),638 thread.GetID(), initial_pc_addr, breakpoint_addr);639 640 error = context.SetPC(breakpoint_addr);641 if (error.Fail()) {642 // This can happen in case the process was killed between the time we read643 // the PC and when we are updating it. There's nothing better to do than to644 // swallow the error.645 LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),646 thread.GetID(), error);647 }648}649 650Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr,651 bool hardware) {652 if (hardware)653 return RemoveHardwareBreakpoint(addr);654 else655 return RemoveSoftwareBreakpoint(addr);656}657 658Status NativeProcessProtocol::ReadMemoryWithoutTrap(lldb::addr_t addr,659 void *buf, size_t size,660 size_t &bytes_read) {661 Status error = ReadMemory(addr, buf, size, bytes_read);662 if (error.Fail())663 return error;664 665 llvm::MutableArrayRef data(static_cast<uint8_t *>(buf), bytes_read);666 for (const auto &pair : m_software_breakpoints) {667 lldb::addr_t bp_addr = pair.first;668 auto saved_opcodes = llvm::ArrayRef(pair.second.saved_opcodes);669 670 if (bp_addr + saved_opcodes.size() < addr || addr + bytes_read <= bp_addr)671 continue; // Breakpoint not in range, ignore672 673 if (bp_addr < addr) {674 saved_opcodes = saved_opcodes.drop_front(addr - bp_addr);675 bp_addr = addr;676 }677 auto bp_data = data.drop_front(bp_addr - addr);678 std::copy_n(saved_opcodes.begin(),679 std::min(saved_opcodes.size(), bp_data.size()),680 bp_data.begin());681 }682 return Status();683}684 685llvm::Expected<llvm::StringRef>686NativeProcessProtocol::ReadCStringFromMemory(lldb::addr_t addr, char *buffer,687 size_t max_size,688 size_t &total_bytes_read) {689 static const size_t cache_line_size =690 llvm::sys::Process::getPageSizeEstimate();691 size_t bytes_read = 0;692 size_t bytes_left = max_size;693 addr_t curr_addr = addr;694 size_t string_size;695 char *curr_buffer = buffer;696 total_bytes_read = 0;697 Status status;698 699 while (bytes_left > 0 && status.Success()) {700 addr_t cache_line_bytes_left =701 cache_line_size - (curr_addr % cache_line_size);702 addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);703 status = ReadMemory(curr_addr, static_cast<void *>(curr_buffer),704 bytes_to_read, bytes_read);705 706 if (bytes_read == 0)707 break;708 709 void *str_end = std::memchr(curr_buffer, '\0', bytes_read);710 if (str_end != nullptr) {711 total_bytes_read =712 static_cast<size_t>((static_cast<char *>(str_end) - buffer + 1));713 status.Clear();714 break;715 }716 717 total_bytes_read += bytes_read;718 curr_buffer += bytes_read;719 curr_addr += bytes_read;720 bytes_left -= bytes_read;721 }722 723 string_size = total_bytes_read - 1;724 725 // Make sure we return a null terminated string.726 if (bytes_left == 0 && max_size > 0 && buffer[max_size - 1] != '\0') {727 buffer[max_size - 1] = '\0';728 total_bytes_read--;729 }730 731 if (!status.Success())732 return status.ToError();733 734 return llvm::StringRef(buffer, string_size);735}736 737lldb::StateType NativeProcessProtocol::GetState() const {738 std::lock_guard<std::recursive_mutex> guard(m_state_mutex);739 return m_state;740}741 742void NativeProcessProtocol::SetState(lldb::StateType state,743 bool notify_delegates) {744 std::lock_guard<std::recursive_mutex> guard(m_state_mutex);745 746 if (state == m_state)747 return;748 749 m_state = state;750 751 if (StateIsStoppedState(state, false)) {752 ++m_stop_id;753 754 // Give process a chance to do any stop id bump processing, such as755 // clearing cached data that is invalidated each time the process runs.756 // Note if/when we support some threads running, we'll end up needing to757 // manage this per thread and per process.758 DoStopIDBumped(m_stop_id);759 }760 761 // Optionally notify delegates of the state change.762 if (notify_delegates)763 SynchronouslyNotifyProcessStateChanged(state);764}765 766uint32_t NativeProcessProtocol::GetStopID() const {767 std::lock_guard<std::recursive_mutex> guard(m_state_mutex);768 return m_stop_id;769}770 771void NativeProcessProtocol::DoStopIDBumped(uint32_t /* newBumpId */) {772 // Default implementation does nothing.773}774 775NativeProcessProtocol::Manager::~Manager() = default;776