https://github.com/b10902118 updated https://github.com/llvm/llvm-project/pull/147198
>From d2bb9308217cd072af7386b90e762704786f2b90 Mon Sep 17 00:00:00 2001 From: b10902118 <b10902...@ntu.edu.tw> Date: Mon, 28 Jul 2025 23:57:51 +0800 Subject: [PATCH] Squash commits. --- .../Plugins/Process/Linux/CMakeLists.txt | 1 + .../Linux/NativeRegisterContextLinux_arm.cpp | 49 +++++++++--- .../Linux/NativeRegisterContextLinux_arm.h | 22 ++---- .../NativeRegisterContextLinux_arm64.cpp | 62 +++------------ .../NativeRegisterContextLinux_arm64dbreg.cpp | 77 +++++++++++++++++++ .../NativeRegisterContextLinux_arm64dbreg.h | 31 ++++++++ .../Utility/NativeRegisterContextDBReg.h | 2 +- 7 files changed, 165 insertions(+), 79 deletions(-) create mode 100644 lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.cpp create mode 100644 lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.h diff --git a/lldb/source/Plugins/Process/Linux/CMakeLists.txt b/lldb/source/Plugins/Process/Linux/CMakeLists.txt index 33af2e24dedd4..bb69016702cdf 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 + NativeRegisterContextLinux_arm64dbreg.cpp NativeRegisterContextLinux_loongarch64.cpp NativeRegisterContextLinux_ppc64le.cpp NativeRegisterContextLinux_riscv64.cpp diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp index dc7fb103e87c0..fdafacf410d64 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp @@ -23,13 +23,19 @@ #include <elf.h> #include <sys/uio.h> +#if defined(__arm64__) || defined(__aarch64__) +#include "NativeRegisterContextLinux_arm64dbreg.h" +#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 @@ -342,7 +348,8 @@ NativeRegisterContextLinux_arm::SetHardwareBreakpoint(lldb::addr_t addr, m_hbr_regs[bp_index].control = control_value; // PTRACE call to set corresponding hardware breakpoint register. - error = WriteHardwareDebugRegs(eDREGTypeBREAK, bp_index); + error = WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeBREAK, + bp_index); if (error.Fail()) { m_hbr_regs[bp_index].address = 0; @@ -375,7 +382,8 @@ bool NativeRegisterContextLinux_arm::ClearHardwareBreakpoint(uint32_t hw_idx) { m_hbr_regs[hw_idx].address = 0; // PTRACE call to clear corresponding hardware breakpoint register. - error = WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx); + error = WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeBREAK, + hw_idx); if (error.Fail()) { m_hbr_regs[hw_idx].control = tempControl; @@ -435,7 +443,8 @@ Status NativeRegisterContextLinux_arm::ClearAllHardwareBreakpoints() { m_hbr_regs[i].address = 0; // Ptrace call to update hardware debug registers - error = WriteHardwareDebugRegs(eDREGTypeBREAK, i); + error = + WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeBREAK, i); if (error.Fail()) { m_hbr_regs[i].control = tempControl; @@ -555,7 +564,8 @@ uint32_t NativeRegisterContextLinux_arm::SetHardwareWatchpoint( m_hwp_regs[wp_index].control = control_value; // PTRACE call to set corresponding watchpoint register. - error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index); + error = WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeWATCH, + wp_index); if (error.Fail()) { m_hwp_regs[wp_index].address = 0; @@ -590,7 +600,8 @@ bool NativeRegisterContextLinux_arm::ClearHardwareWatchpoint( m_hwp_regs[wp_index].address = 0; // Ptrace call to update hardware debug registers - error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index); + error = WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeWATCH, + wp_index); if (error.Fail()) { m_hwp_regs[wp_index].control = tempControl; @@ -623,7 +634,8 @@ Status NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints() { m_hwp_regs[i].address = 0; // Ptrace call to update hardware debug registers - error = WriteHardwareDebugRegs(eDREGTypeWATCH, i); + error = + WriteHardwareDebugRegs(NativeRegisterContextDBReg::eDREGTypeWATCH, i); if (error.Fail()) { m_hwp_regs[i].control = tempControl; @@ -723,6 +735,7 @@ Status NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() { return Status(); } +#ifdef __arm__ unsigned int cap_val; error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(), @@ -737,16 +750,21 @@ Status NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() { m_refresh_hwdebug_info = false; return error; +#else // __aarch64__ + return arm64::ReadHardwareDebugInfo(m_thread.GetID(), m_max_hwp_supported, + m_max_hbp_supported); +#endif // ifdef __arm__ } -Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, - int hwb_index) { +Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs( + NativeRegisterContextDBReg::DREGType hwbType, int hwb_index) { Status error; +#ifdef __arm__ lldb::addr_t *addr_buf; uint32_t *ctrl_buf; - if (hwbType == eDREGTypeWATCH) { + if (hwbType == NativeRegisterContextDBReg::eDREGTypeWATCH) { addr_buf = &m_hwp_regs[hwb_index].address; ctrl_buf = &m_hwp_regs[hwb_index].control; @@ -781,6 +799,17 @@ Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, } return error; +#else // __aarch64__ + uint32_t max_supported = + (hwbType == NativeRegisterContextDBReg::eDREGTypeWATCH) + ? m_max_hwp_supported + : m_max_hbp_supported; + auto ®s = (hwbType == NativeRegisterContextDBReg::eDREGTypeWATCH) + ? m_hwp_regs + : m_hbr_regs; + return arm64::WriteHardwareDebugRegs(hwbType, m_thread.GetID(), max_supported, + regs); +#endif // ifdef __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 420e866dbd635..3a31d68d7a3c4 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,9 +75,6 @@ class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux { bool WatchpointIsEnabled(uint32_t wp_index); - // Debug register type select - enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK }; - protected: Status DoReadRegisterValue(uint32_t offset, const char *reg_name, uint32_t size, RegisterValue &value) override; @@ -102,17 +100,10 @@ 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. - }; - - struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints - struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints + std::array<NativeRegisterContextDBReg::DREG, 16> + m_hbr_regs; // Arm native linux hardware breakpoints + std::array<NativeRegisterContextDBReg::DREG, 16> + m_hwp_regs; // Arm native linux hardware watchpoints uint32_t m_max_hwp_supported; uint32_t m_max_hbp_supported; @@ -124,7 +115,8 @@ class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux { Status ReadHardwareDebugInfo(); - Status WriteHardwareDebugRegs(int hwbType, int hwb_index); + Status WriteHardwareDebugRegs(NativeRegisterContextDBReg::DREGType hwbType, + int hwb_index); uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const; diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index b1c7421bef8d5..294a446686f22 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -8,8 +8,9 @@ #if defined(__arm64__) || defined(__aarch64__) -#include "NativeRegisterContextLinux_arm.h" #include "NativeRegisterContextLinux_arm64.h" +#include "NativeRegisterContextLinux_arm.h" +#include "NativeRegisterContextLinux_arm64dbreg.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/common/NativeProcessProtocol.h" @@ -1146,29 +1147,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, ®set, - &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_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.ToError(); - - m_max_hbp_supported = dreg_state.dbg_info & 0xff; m_refresh_hwdebug_info = false; return llvm::Error::success(); @@ -1176,38 +1159,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(), - ®set, &ioVec, ioVec.iov_len) + uint32_t max_supported = + (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported; + auto ®s = (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/Linux/NativeRegisterContextLinux_arm64dbreg.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.cpp new file mode 100644 index 0000000000000..53ee8fdb2b482 --- /dev/null +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.cpp @@ -0,0 +1,77 @@ +//===-- NativeRegisterContextLinux_arm64dbreg.cpp -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#if defined(__arm64__) || defined(__aarch64__) + +#include "NativeRegisterContextLinux_arm64dbreg.h" +#include "lldb/Host/linux/Ptrace.h" + +#include <asm/ptrace.h> +// System includes - They have to be included after framework includes because +// they define some macros which collide with variable names in other modules +#include <sys/uio.h> +// NT_PRSTATUS and NT_FPREGSET definition +#include <elf.h> + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::process_linux; + +static 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, ®set, + &ioVec, ioVec.iov_len); + + if (error.Fail()) + return error; + + max_supported = dreg_state.dbg_info & 0xff; + return error; +} + +Status lldb_private::process_linux::arm64::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 lldb_private::process_linux::arm64::WriteHardwareDebugRegs( + int hwbType, ::pid_t tid, uint32_t max_supported, + const std::array<NativeRegisterContextDBReg::DREG, 16> ®s) { + int regset = hwbType == NativeRegisterContextDBReg::eDREGTypeWATCH + ? NT_ARM_HW_WATCH + : NT_ARM_HW_BREAK; + + struct user_hwdebug_state dreg_state; + memset(&dreg_state, 0, sizeof(dreg_state)); + 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; + } + + struct iovec ioVec; + 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); + + return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, ®set, + &ioVec, ioVec.iov_len); +} + +#endif // defined (__arm64__) || defined (__aarch64__) diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.h new file mode 100644 index 0000000000000..bca217851858d --- /dev/null +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64dbreg.h @@ -0,0 +1,31 @@ +//===-- NativeRegisterContextLinux_arm64dbreg.h -----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// When debugging 32-bit processes, Arm64 lldb-server should use 64-bit ptrace +// interfaces. 32-bit ptrace interfaces should only be used by 32-bit server. +// These functions are split out to be reused in both 32-bit and 64-bit register +// context for 64-bit server. + +#include "Plugins/Process/Linux/NativeProcessLinux.h" +#include "Plugins/Process/Utility/NativeRegisterContextDBReg.h" +#include "lldb/Utility/Status.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> ®s); + +} // namespace arm64 +} // namespace process_linux +} // namespace lldb_private 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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits