forked from go-delve/delve
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
proc/native: separate amd64-arch code
As proc/native is arch related, it should move some functions to arch-relate file. And this patch can help us to separate the architecture code, make code tidy. So that the merge of arm64 code later will not cause chaos.(go-delve#118)
- Loading branch information
1 parent
b3d2cbb
commit ba29709
Showing
4 changed files
with
88 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package native | ||
|
||
import ( | ||
"syscall" | ||
"unsafe" | ||
|
||
sys "golang.org/x/sys/unix" | ||
|
||
"github.com/go-delve/delve/pkg/proc/linutil" | ||
) | ||
|
||
// 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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package native | ||
|
||
import ( | ||
"syscall" | ||
"unsafe" | ||
|
||
sys "golang.org/x/sys/unix" | ||
|
||
"github.com/go-delve/delve/pkg/proc" | ||
"github.com/go-delve/delve/pkg/proc/linutil" | ||
) | ||
|
||
func (t *Thread) restoreRegisters(savedRegs proc.Registers) error { | ||
sr := savedRegs.(*linutil.AMD64Registers) | ||
|
||
var restoreRegistersErr error | ||
t.dbp.execPtraceFunc(func() { | ||
oldRegs := (*sys.PtraceRegs)(sr.Regs) | ||
|
||
var currentRegs sys.PtraceRegs | ||
restoreRegistersErr = sys.PtraceGetRegs(t.ID, ¤tRegs) | ||
if restoreRegistersErr != nil { | ||
return | ||
} | ||
// restoreRegisters is only supposed to restore CPU registers, not FS_BASE and GS_BASE | ||
oldRegs.Fs_base = currentRegs.Fs_base | ||
oldRegs.Gs_base = currentRegs.Gs_base | ||
|
||
restoreRegistersErr = sys.PtraceSetRegs(t.ID, oldRegs) | ||
|
||
if restoreRegistersErr != nil { | ||
return | ||
} | ||
if sr.Fpregset.Xsave != nil { | ||
iov := sys.Iovec{Base: &sr.Fpregset.Xsave[0], Len: uint64(len(sr.Fpregset.Xsave))} | ||
_, _, restoreRegistersErr = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETREGSET, uintptr(t.ID), _NT_X86_XSTATE, uintptr(unsafe.Pointer(&iov)), 0, 0) | ||
return | ||
} | ||
|
||
_, _, restoreRegistersErr = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETFPREGS, uintptr(t.ID), uintptr(0), uintptr(unsafe.Pointer(&sr.Fpregset.AMD64PtraceFpRegs)), 0, 0) | ||
return | ||
}) | ||
if restoreRegistersErr == syscall.Errno(0) { | ||
restoreRegistersErr = nil | ||
} | ||
return restoreRegistersErr | ||
} |