[lldb][Process] Introduce LoongArch64 hw break/watchpoint support · llvm/llvm-project@6c4e70f (original) (raw)
`@@ -11,6 +11,7 @@
`
11
11
`#include "NativeRegisterContextLinux_loongarch64.h"
`
12
12
``
13
13
`#include "lldb/Host/HostInfo.h"
`
``
14
`+
#include "lldb/Host/linux/Ptrace.h"
`
14
15
`#include "lldb/Utility/DataBufferHeap.h"
`
15
16
`#include "lldb/Utility/Log.h"
`
16
17
`#include "lldb/Utility/RegisterValue.h"
`
`@@ -62,6 +63,16 @@ NativeRegisterContextLinux_loongarch64::NativeRegisterContextLinux_loongarch64(
`
62
63
`::memset(&m_fpr, 0, sizeof(m_fpr));
`
63
64
`::memset(&m_gpr, 0, sizeof(m_gpr));
`
64
65
``
``
66
`+
::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
`
``
67
`+
::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs));
`
``
68
+
``
69
`+
// Refer to:
`
``
70
`+
`
``
71
`+
// 14 is just a maximum value, query hardware for actual watchpoint count.
`
``
72
`+
m_max_hwp_supported = 14;
`
``
73
`+
m_max_hbp_supported = 14;
`
``
74
`+
m_refresh_hwdebug_info = true;
`
``
75
+
65
76
` m_gpr_is_valid = false;
`
66
77
` m_fpu_is_valid = false;
`
67
78
`}
`
`@@ -337,4 +348,73 @@ NativeRegisterContextLinux_loongarch64::GetExpeditedRegisters(
`
337
348
`return expedited_reg_nums;
`
338
349
`}
`
339
350
``
``
351
`+
llvm::Error NativeRegisterContextLinux_loongarch64::ReadHardwareDebugInfo() {
`
``
352
`+
if (!m_refresh_hwdebug_info)
`
``
353
`+
return llvm::Error::success();
`
``
354
+
``
355
`+
::pid_t tid = m_thread.GetID();
`
``
356
+
``
357
`+
int regset = NT_LOONGARCH_HW_WATCH;
`
``
358
`+
struct iovec ioVec;
`
``
359
`+
struct user_watch_state dreg_state;
`
``
360
`+
Status error;
`
``
361
+
``
362
`+
ioVec.iov_base = &dreg_state;
`
``
363
`+
ioVec.iov_len = sizeof(dreg_state);
`
``
364
`+
error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set,
`
``
365
`+
&ioVec, ioVec.iov_len);
`
``
366
`+
if (error.Fail())
`
``
367
`+
return error.ToError();
`
``
368
+
``
369
`+
m_max_hwp_supported = dreg_state.dbg_info & 0x3f;
`
``
370
+
``
371
`+
regset = NT_LOONGARCH_HW_BREAK;
`
``
372
`+
error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set,
`
``
373
`+
&ioVec, ioVec.iov_len);
`
``
374
`+
if (error.Fail())
`
``
375
`+
return error.ToError();
`
``
376
+
``
377
`+
m_max_hbp_supported = dreg_state.dbg_info & 0x3f;
`
``
378
+
``
379
`+
m_refresh_hwdebug_info = false;
`
``
380
+
``
381
`+
return llvm::Error::success();
`
``
382
`+
}
`
``
383
+
``
384
`+
llvm::Error NativeRegisterContextLinux_loongarch64::WriteHardwareDebugRegs(
`
``
385
`+
DREGType hwbType) {
`
``
386
`+
struct iovec ioVec;
`
``
387
`+
struct user_watch_state dreg_state;
`
``
388
`+
int regset;
`
``
389
+
``
390
`+
memset(&dreg_state, 0, sizeof(dreg_state));
`
``
391
`+
ioVec.iov_base = &dreg_state;
`
``
392
+
``
393
`+
switch (hwbType) {
`
``
394
`+
case eDREGTypeWATCH:
`
``
395
`+
regset = NT_LOONGARCH_HW_WATCH;
`
``
396
`+
ioVec.iov_len = sizeof(dreg_state.dbg_info) +
`
``
397
`+
(sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported);
`
``
398
+
``
399
`+
for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
`
``
400
`+
dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
`
``
401
`+
dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
`
``
402
`+
}
`
``
403
`+
break;
`
``
404
`+
case eDREGTypeBREAK:
`
``
405
`+
regset = NT_LOONGARCH_HW_BREAK;
`
``
406
`+
ioVec.iov_len = sizeof(dreg_state.dbg_info) +
`
``
407
`+
(sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported);
`
``
408
+
``
409
`+
for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
`
``
410
`+
dreg_state.dbg_regs[i].addr = m_hbp_regs[i].address;
`
``
411
`+
dreg_state.dbg_regs[i].ctrl = m_hbp_regs[i].control;
`
``
412
`+
}
`
``
413
`+
break;
`
``
414
`+
}
`
``
415
+
``
416
`+
return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
`
``
417
`+
®set, &ioVec, ioVec.iov_len)
`
``
418
`+
.ToError();
`
``
419
`+
}
`
340
420
`#endif // defined(loongarch) && __loongarch_grlen == 64
`