[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 20 04:03:24 PDT 2025


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

>From 102a2f59c07dfb63cc2aabae66a0afcf60388602 Mon Sep 17 00:00:00 2001
From: b10902118 <b10902118 at linux1.csie.ntu.edu.tw>
Date: Sun, 6 Jul 2025 23:50:54 +0800
Subject: [PATCH 1/2] [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;
 

>From 78f8d7167cb5d49977e881c0b2d50a5c213421ff Mon Sep 17 00:00:00 2001
From: b10902118 <b10902118 at linux1.csie.ntu.edu.tw>
Date: Sun, 20 Jul 2025 15:45:13 +0800
Subject: [PATCH 2/2] [lldb][AArch64] Fix hardware breakpoint/watchpoint to
 arm32 debugee on arm64.

When debugging arm32 process on arm64 machine, arm64 lldb-server will use `NativeRegisterContextLinux_arm`, but it should use 64-bit ptrace commands for hardware watchpoint/breakpoint.
See: https://github.com/torvalds/linux/commit/5d220ff9420f8b1689805ba2d938bedf9e0860a4

There have been many conditional compilation handling arm32 debuggees on arm64, but this one is missed out.

To reuse the 64-bit implementation, I separate the shared code from `NativeRegisterContextLinux_arm64.cpp` to `NativeRegisterContextLinuxArm64Shared.cpp`, with other adjustments to share data structures of debug registers.
---
 .../Plugins/Process/Linux/CMakeLists.txt      |  1 +
 .../NativeRegisterContextLinuxArm64Shared.cpp | 63 +++++++++++++++++
 .../NativeRegisterContextLinuxArm64Shared.h   | 23 +++++++
 .../Linux/NativeRegisterContextLinux_arm.cpp  | 68 +++----------------
 .../Linux/NativeRegisterContextLinux_arm.h    | 21 ++----
 .../NativeRegisterContextLinux_arm64.cpp      | 60 +++-------------
 .../Utility/NativeRegisterContextDBReg.h      |  2 +-
 7 files changed, 111 insertions(+), 127 deletions(-)
 create mode 100644 lldb/source/Plugins/Process/Linux/NativeRegisterContextLinuxArm64Shared.cpp
 create mode 100644 lldb/source/Plugins/Process/Linux/NativeRegisterContextLinuxArm64Shared.h

diff --git a/lldb/source/Plugins/Process/Linux/CMakeLists.txt b/lldb/source/Plugins/Process/Linux/CMakeLists.txt
index 33af2e24dedd4..f3493859467a2 100644
--- a/lldb/source/Plugins/Process/Linux/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/Linux/CMakeLists.txt
@@ -8,6 +8,7 @@ add_lldb_library(lldbPluginProcessLinux
   NativeRegisterContextLinux.cpp
   NativeRegisterContextLinux_arm.cpp
   NativeRegisterContextLinux_arm64.cpp
+  NativeRegisterContextLinuxArm64Shared.cpp
   NativeRegisterContextLinux_loongarch64.cpp
   NativeRegisterContextLinux_ppc64le.cpp
   NativeRegisterContextLinux_riscv64.cpp
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinuxArm64Shared.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinuxArm64Shared.cpp
new file mode 100644
index 0000000000000..a7dff0aed43be
--- /dev/null
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinuxArm64Shared.cpp
@@ -0,0 +1,63 @@
+#include "NativeRegisterContextLinuxArm64Shared.h"
+
+using namespace lldb_private::process_linux::arm64;
+
+namespace lldb_private {
+namespace process_linux {
+namespace arm64 {
+
+namespace {
+Status ReadHardwareDebugInfoHelper(int regset, ::pid_t tid,
+                                   uint32_t &max_supported) {
+  struct iovec ioVec;
+  struct user_hwdebug_state dreg_state;
+  Status error;
+
+  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;
+
+  max_supported = dreg_state.dbg_info & 0xff;
+  return error;
+}
+} // namespace
+
+Status ReadHardwareDebugInfo(::pid_t tid, uint32_t &max_hwp_supported,
+                             uint32_t &max_hbp_supported) {
+  Status error =
+      ReadHardwareDebugInfoHelper(NT_ARM_HW_WATCH, tid, max_hwp_supported);
+
+  if (error.Fail())
+    return error;
+
+  return ReadHardwareDebugInfoHelper(NT_ARM_HW_BREAK, tid, max_hbp_supported);
+}
+
+Status WriteHardwareDebugRegs(
+    int hwbType, ::pid_t tid, uint32_t max_supported,
+    const std::array<NativeRegisterContextDBReg::DREG, 16> &regs) {
+  struct iovec ioVec;
+  struct user_hwdebug_state dreg_state;
+  int regset = hwbType == NativeRegisterContextDBReg::eDREGTypeWATCH
+                   ? NT_ARM_HW_WATCH
+                   : NT_ARM_HW_BREAK;
+  memset(&dreg_state, 0, sizeof(dreg_state));
+  ioVec.iov_base = &dreg_state;
+  ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
+                  (sizeof(dreg_state.dbg_regs[0]) * max_supported);
+  for (uint32_t i = 0; i < max_supported; i++) {
+    dreg_state.dbg_regs[i].addr = regs[i].address;
+    dreg_state.dbg_regs[i].ctrl = regs[i].control;
+  }
+
+  return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset,
+                                           &ioVec, ioVec.iov_len);
+}
+
+} // namespace arm64
+} // namespace process_linux
+} // namespace lldb_private
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinuxArm64Shared.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinuxArm64Shared.h
new file mode 100644
index 0000000000000..1e8319ca7da4c
--- /dev/null
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinuxArm64Shared.h
@@ -0,0 +1,23 @@
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg.h"
+#include "lldb/Utility/Status.h"
+#include <asm/ptrace.h>
+#include <cstdint>
+#include <elf.h>
+#include <sys/ptrace.h>
+#include <sys/uio.h>
+
+namespace lldb_private {
+namespace process_linux {
+namespace arm64 {
+
+Status ReadHardwareDebugInfo(::pid_t tid, uint32_t &max_hwp_supported,
+                             uint32_t &max_hbp_supported);
+
+Status WriteHardwareDebugRegs(
+    int hwbType, ::pid_t tid, uint32_t max_supported,
+    const std::array<NativeRegisterContextDBReg::DREG, 16> &regs);
+
+} // namespace arm64
+} // namespace process_linux
+} // namespace lldb_private
\ No newline at end of file
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index 9123a577008bd..3e92a320ae95c 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -9,6 +9,7 @@
 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
 
 #include "NativeRegisterContextLinux_arm.h"
+#include "NativeRegisterContextLinuxArm64Shared.h"
 
 #include "Plugins/Process/Linux/NativeProcessLinux.h"
 #include "Plugins/Process/Linux/Procfs.h"
@@ -744,34 +745,8 @@ Status NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() {
 
   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;
+  return arm64::ReadHardwareDebugInfo(m_thread.GetID(), m_max_hwp_supported,
+                                      m_max_hbp_supported);
 #endif // __arm__
 }
 
@@ -819,38 +794,11 @@ Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(DREGType 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);
+  uint32_t max_supported =
+      (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
+  auto &regs = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbr_regs;
+  return arm64::WriteHardwareDebugRegs(hwbType, m_thread.GetID(), max_supported,
+                                       regs);
 #endif // __arm__
 }
 
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
index 6d0ad38d7eb75..aa3e6b6aaba79 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
@@ -12,6 +12,7 @@
 #define lldb_NativeRegisterContextLinux_arm_h
 
 #include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg.h"
 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
 #include "Plugins/Process/Utility/lldb-arm-register-enums.h"
 
@@ -74,8 +75,10 @@ class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux {
 
   bool WatchpointIsEnabled(uint32_t wp_index);
 
-  // Debug register type select
-  enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
+  using DREGType = NativeRegisterContextDBReg::DREGType;
+  static const DREGType eDREGTypeBREAK = DREGType::eDREGTypeBREAK;
+  static const DREGType eDREGTypeWATCH = DREGType::eDREGTypeWATCH;
+  using DREG = NativeRegisterContextDBReg::DREG;
 
 protected:
   Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
@@ -102,18 +105,8 @@ class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux {
   uint32_t m_gpr_arm[k_num_gpr_registers_arm];
   RegisterInfoPOSIX_arm::FPU m_fpr;
 
-  // Debug register info for hardware breakpoints and watchpoints management.
-  struct DREG {
-    lldb::addr_t address;  // Breakpoint/watchpoint address value.
-    lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
-                           // occurred.
-    lldb::addr_t real_addr; // Address value that should cause target to stop.
-    uint32_t control;       // Breakpoint/watchpoint control value.
-    uint32_t refcount;      // Serves as enable/disable and reference counter.
-  };
-
-  struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
-  struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
+  std::array<DREG, 16> m_hbr_regs; // Arm native linux hardware breakpoints
+  std::array<DREG, 16> m_hwp_regs; // Arm native linux hardware watchpoints
 
   uint32_t m_max_hwp_supported;
   uint32_t m_max_hbp_supported;
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 884c7d4b9e359..9d869a8975821 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "NativeRegisterContextLinuxArm64Shared.h"
 #if defined(__arm64__) || defined(__aarch64__)
 
 #include "NativeRegisterContextLinux_arm.h"
@@ -1143,29 +1144,11 @@ llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
 
   ::pid_t tid = m_thread.GetID();
 
-  int regset = NT_ARM_HW_WATCH;
-  struct iovec ioVec;
-  struct user_hwdebug_state dreg_state;
-  Status error;
-
-  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.ToError();
-
-  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);
-
+  Status error = arm64::ReadHardwareDebugInfo(tid, m_max_hwp_supported,
+                                              m_max_hbp_supported);
   if (error.Fail())
     return error.ToError();
 
-  m_max_hbp_supported = dreg_state.dbg_info & 0xff;
   m_refresh_hwdebug_info = false;
 
   return llvm::Error::success();
@@ -1173,38 +1156,11 @@ llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
 
 llvm::Error
 NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
-  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_hbp_regs[i].address;
-      dreg_state.dbg_regs[i].ctrl = m_hbp_regs[i].control;
-    }
-    break;
-  }
-
-  return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
-                                           &regset, &ioVec, ioVec.iov_len)
+  uint32_t max_supported =
+      (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
+  auto &regs = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
+  return arm64::WriteHardwareDebugRegs(hwbType, m_thread.GetID(), max_supported,
+                                       regs)
       .ToError();
 }
 
diff --git a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg.h b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg.h
index e17a700f7dad7..9b6ecd382c3f3 100644
--- a/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg.h
+++ b/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg.h
@@ -51,7 +51,6 @@ class NativeRegisterContextDBReg
 
   lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
 
-protected:
   // Debug register type select
   enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
 
@@ -64,6 +63,7 @@ class NativeRegisterContextDBReg
     uint32_t control;       // Breakpoint/watchpoint control value.
   };
 
+protected:
   std::array<struct DREG, 16> m_hbp_regs; // hardware breakpoints
   std::array<struct DREG, 16> m_hwp_regs; // hardware watchpoints
 



More information about the lldb-commits mailing list