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, &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;
 

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to