| //===-- 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" | |
| // System includes - They have to be included after framework includes because | |
| // they define some macros which collide with variable names in other modules. | |
| #include <asm/ptrace.h> | |
| #include <elf.h> | |
| #include <sys/ptrace.h> | |
| #include <sys/uio.h> | |
| #ifndef PTRACE_GETREGSET | |
| #define PTRACE_GETREGSET 0x4204 | |
| #endif | |
| #ifndef PTRACE_SETREGSET | |
| #define PTRACE_SETREGSET 0x4205 | |
| #endif | |
| 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__) |