
The repository is being switched from the personal account github.com/derekparker/delve to the organization account github.com/go-delve/delve. This patch updates imports and docs, while preserving things which should not be changed such as my name in the CHANGELOG and in TODO comments.
85 lines
2.8 KiB
Go
85 lines
2.8 KiB
Go
package native
|
||
|
||
import (
|
||
"syscall"
|
||
"unsafe"
|
||
|
||
sys "golang.org/x/sys/unix"
|
||
|
||
"github.com/go-delve/delve/pkg/proc/linutil"
|
||
)
|
||
|
||
// PtraceAttach executes the sys.PtraceAttach call.
|
||
func PtraceAttach(pid int) error {
|
||
return sys.PtraceAttach(pid)
|
||
}
|
||
|
||
// PtraceDetach calls ptrace(PTRACE_DETACH).
|
||
func PtraceDetach(tid, sig int) error {
|
||
_, _, err := sys.Syscall6(sys.SYS_PTRACE, sys.PTRACE_DETACH, uintptr(tid), 1, uintptr(sig), 0, 0)
|
||
if err != syscall.Errno(0) {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// PtraceCont executes ptrace PTRACE_CONT
|
||
func PtraceCont(tid, sig int) error {
|
||
return sys.PtraceCont(tid, sig)
|
||
}
|
||
|
||
// PtraceSingleStep executes ptrace PTRACE_SINGLE_STEP.
|
||
func PtraceSingleStep(tid int) error {
|
||
return sys.PtraceSingleStep(tid)
|
||
}
|
||
|
||
// PtracePokeUser execute ptrace PTRACE_POKE_USER.
|
||
func PtracePokeUser(tid int, off, addr uintptr) error {
|
||
_, _, err := sys.Syscall6(sys.SYS_PTRACE, sys.PTRACE_POKEUSR, uintptr(tid), uintptr(off), uintptr(addr), 0, 0)
|
||
if err != syscall.Errno(0) {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// PtracePeekUser execute ptrace PTRACE_PEEK_USER.
|
||
func PtracePeekUser(tid int, off uintptr) (uintptr, error) {
|
||
var val uintptr
|
||
_, _, err := syscall.Syscall6(syscall.SYS_PTRACE, syscall.PTRACE_PEEKUSR, uintptr(tid), uintptr(off), uintptr(unsafe.Pointer(&val)), 0, 0)
|
||
if err != syscall.Errno(0) {
|
||
return 0, err
|
||
}
|
||
return val, nil
|
||
}
|
||
|
||
// PtraceGetRegset returns floating point registers of the specified thread
|
||
// using PTRACE.
|
||
// See amd64_linux_fetch_inferior_registers in gdb/amd64-linux-nat.c.html
|
||
// and amd64_supply_xsave in gdb/amd64-tdep.c.html
|
||
// and Section 13.1 (and following) of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1: Basic Architecture
|
||
func PtraceGetRegset(tid int) (regset linutil.AMD64Xstate, err error) {
|
||
_, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GETFPREGS, uintptr(tid), uintptr(0), uintptr(unsafe.Pointer(®set.AMD64PtraceFpRegs)), 0, 0)
|
||
if err == syscall.Errno(0) || err == syscall.ENODEV {
|
||
// ignore ENODEV, it just means this CPU doesn't have X87 registers (??)
|
||
err = nil
|
||
}
|
||
|
||
var xstateargs [_X86_XSTATE_MAX_SIZE]byte
|
||
iov := sys.Iovec{Base: &xstateargs[0], Len: _X86_XSTATE_MAX_SIZE}
|
||
_, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GETREGSET, uintptr(tid), _NT_X86_XSTATE, uintptr(unsafe.Pointer(&iov)), 0, 0)
|
||
if err != syscall.Errno(0) {
|
||
if err == syscall.ENODEV || err == syscall.EIO {
|
||
// ignore ENODEV, it just means this CPU or kernel doesn't support XSTATE, see https://github.com/go-delve/delve/issues/1022
|
||
// also ignore EIO, it means that we are running on an old kernel (pre 2.6.34) and PTRACE_GETREGSET is not implemented
|
||
err = nil
|
||
}
|
||
return
|
||
} else {
|
||
err = nil
|
||
}
|
||
|
||
regset.Xsave = xstateargs[:iov.Len]
|
||
err = linutil.AMD64XstateRead(regset.Xsave, false, ®set)
|
||
return regset, err
|
||
}
|