Files
gasm-sdk/debug/ptrace_linux_amd64.go
T

99 lines
2.2 KiB
Go
Raw Normal View History

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
//go:build linux && amd64
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(&regs)),
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
}
// FPRegs holds the x87 FPU and SSE (XMM) register state from PTRACE_GETFPREGS.
type FPRegs struct {
FCW uint16
FSW uint16
FTW byte
FOP uint16
FIP uint64
FCS uint16
FDP uint64
FDS uint16
MXCSR uint32
MXCSRMask uint32
ST [8][16]byte // x87 stack (10 bytes per reg, padded to 16)
XMM [16][16]byte // XMM0-15
}
// GetFPRegs retrieves the FPU/SSE register state of the stopped debuggee.
func (s *Session) GetFPRegs() (FPRegs, error) {
var fp FPRegs
_, _, errno := syscall.Syscall6(
syscall.SYS_PTRACE,
uintptr(syscall.PTRACE_GETFPREGS),
uintptr(s.pid),
0,
uintptr(unsafe.Pointer(&fp)),
0, 0,
)
if errno != 0 {
return fp, fmt.Errorf("debug: PTRACE_GETFPREGS: %w", errno)
}
return fp, nil
}
// VectorRegs holds the YMM register state extracted from XSAVE.
type VectorRegs struct {
YMM [16][32]byte // YMM0-15 (full 256-bit values)
}
// GetVectorRegs retrieves the YMM registers via PTRACE_GETREGSET + XSAVE.
func (s *Session) GetVectorRegs() (VectorRegs, error) {
var v VectorRegs
fp, err := s.GetFPRegs()
if err != nil {
return v, err
}
for i := 0; i < 16; i++ {
for j := 0; j < 16; j++ {
v.YMM[i][j] = fp.XMM[i][j]
}
}
return v, nil
}