diff options
5 files changed, 34 insertions, 65 deletions
diff --git a/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/lldb/include/lldb/Host/common/NativeProcessProtocol.h index 06de44d079e..7577524e06c 100644 --- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -451,6 +451,12 @@ protected: virtual llvm::Expected<llvm::ArrayRef<uint8_t>> GetSoftwareBreakpointTrapOpcode(size_t size_hint); + /// Return the offset of the PC relative to the software breakpoint that was hit. If an + /// architecture (e.g. arm) reports breakpoint hits before incrementing the PC, this offset + /// will be 0. If an architecture (e.g. intel) reports breakpoints hits after incrementing the + /// PC, this offset will be the size of the breakpoint opcode. + virtual size_t GetSoftwareBreakpointPCOffset(); + // ----------------------------------------------------------- /// Notify the delegate that an exec occurred. /// diff --git a/lldb/source/Host/common/NativeProcessProtocol.cpp b/lldb/source/Host/common/NativeProcessProtocol.cpp index 17098fd596e..ef063d5276d 100644 --- a/lldb/source/Host/common/NativeProcessProtocol.cpp +++ b/lldb/source/Host/common/NativeProcessProtocol.cpp @@ -409,6 +409,29 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) { } } +size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() { + switch (GetArchitecture().GetMachine()) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + case llvm::Triple::systemz: + // These architectures report increment the PC after breakpoint is hit. + return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size(); + + case llvm::Triple::arm: + case llvm::Triple::aarch64: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::ppc64le: + // On these architectures the PC doesn't get updated for breakpoint hits. + return 0; + + default: + llvm_unreachable("CPU type not supported!"); + } +} + Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { if (hardware) diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 085956ad95d..f1d3becb0a4 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1502,40 +1502,6 @@ size_t NativeProcessLinux::UpdateThreads() { return m_threads.size(); } -Status NativeProcessLinux::GetSoftwareBreakpointPCOffset( - uint32_t &actual_opcode_size) { - // FIXME put this behind a breakpoint protocol class that can be - // set per architecture. Need ARM, MIPS support here. - static const uint8_t g_i386_opcode[] = {0xCC}; - static const uint8_t g_s390x_opcode[] = {0x00, 0x01}; - - switch (m_arch.GetMachine()) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - actual_opcode_size = static_cast<uint32_t>(sizeof(g_i386_opcode)); - return Status(); - - case llvm::Triple::systemz: - actual_opcode_size = static_cast<uint32_t>(sizeof(g_s390x_opcode)); - return Status(); - - case llvm::Triple::arm: - case llvm::Triple::aarch64: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::ppc64le: - // On these architectures the PC don't get updated for breakpoint hits - actual_opcode_size = 0; - return Status(); - - default: - assert(false && "CPU type not supported!"); - return Status("CPU type not supported"); - } -} - Status NativeProcessLinux::SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) { if (hardware) @@ -1763,13 +1729,8 @@ NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) { // code). NativeRegisterContext &context = thread.GetRegisterContext(); - uint32_t breakpoint_size = 0; - error = GetSoftwareBreakpointPCOffset(breakpoint_size); - if (error.Fail()) { - LLDB_LOG(log, "GetBreakpointSize() failed: {0}", error); - return error; - } else - LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); + uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset(); + LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); // First try probing for a breakpoint at a software breakpoint location: PC - // breakpoint size. diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h index 33f94b002c0..5147c361b11 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -182,8 +182,6 @@ private: NativeThreadLinux &AddThread(lldb::tid_t thread_id); - Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size); - Status FixupBreakpointPCAsNeeded(NativeThreadLinux &thread); /// Writes a siginfo_t structure corresponding to the given thread ID to the diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 145d4d881b6..6326691ca87 100644 --- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -322,21 +322,6 @@ Status NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr, return error; } -Status NativeProcessNetBSD::GetSoftwareBreakpointPCOffset( - uint32_t &actual_opcode_size) { - // FIXME put this behind a breakpoint protocol class that can be - // set per architecture. Need ARM, MIPS support here. - static const uint8_t g_i386_opcode[] = {0xCC}; - switch (m_arch.GetMachine()) { - case llvm::Triple::x86_64: - actual_opcode_size = static_cast<uint32_t>(sizeof(g_i386_opcode)); - return Status(); - default: - assert(false && "CPU type not supported!"); - return Status("CPU type not supported"); - } -} - Status NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS)); @@ -344,13 +329,9 @@ NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) { // Find out the size of a breakpoint (might depend on where we are in the // code). NativeRegisterContext& context = thread.GetRegisterContext(); - uint32_t breakpoint_size = 0; - error = GetSoftwareBreakpointPCOffset(breakpoint_size); - if (error.Fail()) { - LLDB_LOG(log, "GetBreakpointSize() failed: {0}", error); - return error; - } else - LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); + uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset(); + LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); + // First try probing for a breakpoint at a software breakpoint location: PC - // breakpoint size. const lldb::addr_t initial_pc_addr = |