https://github.com/b10902118 created https://github.com/llvm/llvm-project/pull/147198
This bug skips the test because the wrong ptrace call to detect avaliable hardware/breakpoint number that resuls in 0. After tracing linux's compat_ptrace in arch/arm64/kernel/ptrace.c, found that arm64 lldb-server should just keep using the ptrace commands for 64bit tracees. See: https://github.com/torvalds/linux/commit/5d220ff9420f8b1689805ba2d938bedf9e0860a4 So the solution is copying the implementation in NativeRegisterContextLinux_arm64.cpp. >From 102a2f59c07dfb63cc2aabae66a0afcf60388602 Mon Sep 17 00:00:00 2001 From: b10902118 <b10902...@linux1.csie.ntu.edu.tw> Date: Sun, 6 Jul 2025 23:50:54 +0800 Subject: [PATCH] [lldb][AArch64] Fix arm64 hardware breakpoint/watchpoint to arm32 process. This bug skips the test because the wrong ptrace call to detect avaliable hardware/breakpoint number that resuls in 0. After tracing linux's compat_ptrace in arch/arm64/kernel/ptrace.c, found that arm64 lldb-server should just keep using the ptrace commands for 64bit tracees. See: https://github.com/torvalds/linux/commit/5d220ff9420f8b1689805ba2d938bedf9e0860a4 So the solution is copying the implementation in NativeRegisterContextLinux_arm64.cpp. --- .../Linux/NativeRegisterContextLinux_arm.cpp | 75 ++++++++++++++++++- .../Linux/NativeRegisterContextLinux_arm.h | 2 +- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp index dc7fb103e87c0..9123a577008bd 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp @@ -23,13 +23,18 @@ #include <elf.h> #include <sys/uio.h> +#if defined(__arm64__) || defined(__aarch64__) +#include "lldb/Host/linux/Ptrace.h" +#include <asm/ptrace.h> +#endif + #define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(m_fpr)) #ifndef PTRACE_GETVFPREGS #define PTRACE_GETVFPREGS 27 #define PTRACE_SETVFPREGS 28 #endif -#ifndef PTRACE_GETHBPREGS +#if defined(__arm__) && !defined(PTRACE_GETHBPREGS) #define PTRACE_GETHBPREGS 29 #define PTRACE_SETHBPREGS 30 #endif @@ -723,6 +728,7 @@ Status NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() { return Status(); } +#ifdef __arm__ unsigned int cap_val; error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(), @@ -737,12 +743,43 @@ Status NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() { m_refresh_hwdebug_info = false; return error; +#else // __aarch64__ + ::pid_t tid = m_thread.GetID(); + + int regset = NT_ARM_HW_WATCH; + struct iovec ioVec; + struct user_hwdebug_state dreg_state; + + ioVec.iov_base = &dreg_state; + ioVec.iov_len = sizeof(dreg_state); + + error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, + &ioVec, ioVec.iov_len); + + if (error.Fail()) + return error; + + m_max_hwp_supported = dreg_state.dbg_info & 0xff; + + regset = NT_ARM_HW_BREAK; + error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, + &ioVec, ioVec.iov_len); + + if (error.Fail()) + return error; + + m_max_hbp_supported = dreg_state.dbg_info & 0xff; + m_refresh_hwdebug_info = false; + + return error; +#endif // __arm__ } -Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, +Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(DREGType hwbType, int hwb_index) { Status error; +#ifdef __arm__ lldb::addr_t *addr_buf; uint32_t *ctrl_buf; @@ -781,6 +818,40 @@ Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, } return error; +#else // __aarch64__ + struct iovec ioVec; + struct user_hwdebug_state dreg_state; + int regset; + + memset(&dreg_state, 0, sizeof(dreg_state)); + ioVec.iov_base = &dreg_state; + + switch (hwbType) { + case eDREGTypeWATCH: + regset = NT_ARM_HW_WATCH; + ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) + + (sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported); + + for (uint32_t i = 0; i < m_max_hwp_supported; i++) { + dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address; + dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control; + } + break; + case eDREGTypeBREAK: + regset = NT_ARM_HW_BREAK; + ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) + + (sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported); + + for (uint32_t i = 0; i < m_max_hbp_supported; i++) { + dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address; + dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control; + } + break; + } + + return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), + ®set, &ioVec, ioVec.iov_len); +#endif // __arm__ } uint32_t NativeRegisterContextLinux_arm::CalculateFprOffset( diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h index 15b46609c286b..6d0ad38d7eb75 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h @@ -125,7 +125,7 @@ class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux { Status ReadHardwareDebugInfo(); - Status WriteHardwareDebugRegs(int hwbType, int hwb_index); + Status WriteHardwareDebugRegs(DREGType hwbType, int hwb_index); uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits