[Lldb-commits] [lldb] [lldb][AArch64] Fix arm64 hardware breakpoint/watchpoint to arm32 process. (PR #147198)

via lldb-commits lldb-commits at lists.llvm.org
Sun Jul 6 09:13:19 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: None (b10902118)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/147198.diff


2 Files Affected:

- (modified) lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp (+73-2) 
- (modified) lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h (+1-1) 


``````````diff
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, &regset,
+                                            &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, &regset,
+                                            &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(),
+                                           &regset, &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;
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/147198


More information about the lldb-commits mailing list