1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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__)
|