mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 18:57:18 +08:00 
			
		
		
		
	 25b19c77c2
			
		
	
	25b19c77c2
	
	
	
		
			
			Either the CPU or the kernel may not support the calls we do when retrieving floating point registers, this isn't an error we should propagate. Also improve the error reporint of pkg/proc/native.fpRegisters. Fixes #1022
		
			
				
	
	
		
			83 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			83 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package native
 | ||
| 
 | ||
| import (
 | ||
| 	"syscall"
 | ||
| 	"unsafe"
 | ||
| 
 | ||
| 	sys "golang.org/x/sys/unix"
 | ||
| 
 | ||
| 	"github.com/derekparker/delve/pkg/proc"
 | ||
| )
 | ||
| 
 | ||
| // 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 proc.LinuxX86Xstate, err error) {
 | ||
| 	_, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GETFPREGS, uintptr(tid), uintptr(0), uintptr(unsafe.Pointer(®set.PtraceFpRegs)), 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 {
 | ||
| 			// ignore ENODEV, it just means this CPU or kernel doesn't support XSTATE, see https://github.com/derekparker/delve/issues/1022
 | ||
| 			err = nil
 | ||
| 		}
 | ||
| 		return
 | ||
| 	} else {
 | ||
| 		err = nil
 | ||
| 	}
 | ||
| 
 | ||
| 	err = proc.LinuxX86XstateRead(xstateargs[:iov.Len], false, ®set)
 | ||
| 	return regset, err
 | ||
| }
 |