88 lines
2.2 KiB
Go
88 lines
2.2 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
//go:build linux && loong64
|
|
|
|
package debug
|
|
|
|
import (
|
|
"fmt"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
// GetRegs reads the general-purpose registers of the stopped debuggee.
|
|
func (s *Session) GetRegs() (Regs, error) {
|
|
var regs Regs
|
|
_, _, errno := syscall.Syscall6(
|
|
syscall.SYS_PTRACE,
|
|
uintptr(syscall.PTRACE_GETREGS),
|
|
uintptr(s.pid),
|
|
0,
|
|
uintptr(unsafe.Pointer(®s)),
|
|
0, 0,
|
|
)
|
|
if errno != 0 {
|
|
return regs, fmt.Errorf("debug: PTRACE_GETREGS: %w", errno)
|
|
}
|
|
return regs, nil
|
|
}
|
|
|
|
// SetRegs writes the general-purpose registers of the stopped debuggee.
|
|
func (s *Session) SetRegs(regs *Regs) error {
|
|
_, _, errno := syscall.Syscall6(
|
|
syscall.SYS_PTRACE,
|
|
uintptr(syscall.PTRACE_SETREGS),
|
|
uintptr(s.pid),
|
|
0,
|
|
uintptr(unsafe.Pointer(regs)),
|
|
0, 0,
|
|
)
|
|
if errno != 0 {
|
|
return fmt.Errorf("debug: PTRACE_SETREGS: %w", errno)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ntPrFPREG is the NT_PRFPREG note type (ELF NT ver): the FP register set.
|
|
const ntPrFPREG = 0x2
|
|
|
|
// FPRegs holds the LoongArch FP register state, matching the kernel's
|
|
// user_fp_struct layout (32 64-bit FP registers, the fcc condition flags,
|
|
// and fcsr).
|
|
type FPRegs struct {
|
|
F [32]uint64 // F0-F31 (64-bit FP registers)
|
|
FCC uint64 // eight per-register condition flags, packed
|
|
FCSR uint32
|
|
}
|
|
|
|
// GetFPRegs retrieves the FP register state via PTRACE_GETREGSET with
|
|
// NT_PRFPREG (this architecture has no PTRACE_GETFPREGS request).
|
|
func (s *Session) GetFPRegs() (FPRegs, error) {
|
|
var fp FPRegs
|
|
iovec := syscall.Iovec{
|
|
Base: (*byte)(unsafe.Pointer(&fp)),
|
|
Len: uint64(unsafe.Sizeof(fp)),
|
|
}
|
|
_, _, errno := syscall.Syscall6(
|
|
syscall.SYS_PTRACE,
|
|
uintptr(syscall.PTRACE_GETREGSET),
|
|
uintptr(s.pid),
|
|
uintptr(ntPrFPREG),
|
|
uintptr(unsafe.Pointer(&iovec)),
|
|
0, 0,
|
|
)
|
|
if errno != 0 {
|
|
return fp, fmt.Errorf("debug: PTRACE_GETREGSET (NT_PRFPREG): %w", errno)
|
|
}
|
|
return fp, nil
|
|
}
|
|
|
|
// VectorRegs holds the LSX/LASX vector register state (placeholder).
|
|
type VectorRegs struct{}
|
|
|
|
// GetVectorRegs retrieves the vector registers (not yet implemented for loong64).
|
|
func (s *Session) GetVectorRegs() (VectorRegs, error) {
|
|
return VectorRegs{}, nil
|
|
}
|