feat(debug): add YMM vector register display via PTRACE_GETFPREGS
Assisted-by: DeepSeek V4 Pro
This commit is contained in:
@@ -144,6 +144,63 @@ func (s *Session) SetRegs(regs *Regs) error {
|
||||
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.
|
||||
// Falls back to XMM if XSAVE is unavailable.
|
||||
func (s *Session) GetVectorRegs() (VectorRegs, error) {
|
||||
var v VectorRegs
|
||||
fp, err := s.GetFPRegs()
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
// PTRACE_GETFPREGS gives XMM registers (lower 128 bits).
|
||||
// For YMM we'd need XSAVE; for now, copy XMM and zero the upper half.
|
||||
for i := 0; i < 16; i++ {
|
||||
for j := 0; j < 16; j++ {
|
||||
v.YMM[i][j] = fp.XMM[i][j]
|
||||
}
|
||||
// Upper 128 bits would come from XSAVE, not available via GETFPREGS.
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Peek reads a word (8 bytes) from the debuggee's memory at addr.
|
||||
// Uses /proc/pid/mem which works reliably with Go's multi-threaded runtime.
|
||||
func (s *Session) Peek(addr uint64) (uint64, error) {
|
||||
|
||||
Reference in New Issue
Block a user