-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pkg/proc: fix and improve freebsd register handling (#3019)
* pkg/proc: convert freebsd ptrace code to cgo There is little point in having cgo call a custom C function, when the same can be done directly from cgo (with less code and effort). Split the amd64 specific code into ptrace_freebsd_amd64.go. Also avoid mixing C.ptrace() with syscall.SYS_PTRACE. This will make further changes easier - no functional change intended. * pkg/proc: check return values of ptrace calls on freebsd The return values of the PT_GETNUMLWPS and PT_GETLWPLIST ptrace calls were previously unchecked. While these should not fail, panic instead of using -1 with slice allocation/handling. * pkg/proc: return *amd64util.AMD64Xstate from freebsd ptraceGetRegset Return a pointer to a struct, rather than a struct - this simplifies the code in both the caller and the ptraceGetRegset function, while also avoiding struct copying. * pkg/proc: fix floating point register setting on freebsd The original code could never work - PT_SETREGS on freebsd does not take an iovec, nor does it set FP registers. Furthermore, the xsave bytes were not stored in the amd64util.AMD64Xstate struct. Updates #3001 * pkg/proc: re-enable function call injection on freebsd Floating point registers can now be set and restored correctly. This is a partial revert of 51090f0. Fixes #3001 * pkg/proc: deduplicate register setting code on freebsd
- Loading branch information
Showing
9 changed files
with
194 additions
and
175 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
This file was deleted.
Oops, something went wrong.
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,89 @@ | ||
package native | ||
|
||
/* | ||
#include <sys/types.h> | ||
#include <sys/ptrace.h> | ||
*/ | ||
import "C" | ||
|
||
import ( | ||
"fmt" | ||
"unsafe" | ||
|
||
"github.com/go-delve/delve/pkg/proc/amd64util" | ||
) | ||
|
||
var ( | ||
xsaveLen int | ||
xsaveErr error | ||
) | ||
|
||
func ptraceGetXsaveLen(tid int) (int, error) { | ||
var info C.struct_ptrace_xstate_info | ||
ret, err := C.ptrace(C.PT_GETXSTATE_INFO, C.pid_t(tid), C.caddr_t(unsafe.Pointer(&info)), C.int(unsafe.Sizeof(info))) | ||
if ret == 0 { | ||
xsaveLen = int(info.xsave_len) | ||
} else { | ||
xsaveLen, xsaveErr = -1, err | ||
return xsaveLen, fmt.Errorf("failed to get xstate info: %v", err) | ||
} | ||
return xsaveLen, nil | ||
} | ||
|
||
func ptraceXsaveLen(tid int) (int, error) { | ||
if xsaveLen > 0 { | ||
return xsaveLen, nil | ||
} | ||
if xsaveLen < 0 { | ||
return xsaveLen, fmt.Errorf("failed to get xstate info: %v", xsaveErr) | ||
} | ||
return ptraceGetXsaveLen(tid) | ||
} | ||
|
||
// ptraceGetXsave gets the X86 XSAVE data for the given tid. | ||
func ptraceGetXsave(tid int) ([]byte, error) { | ||
len, err := ptraceXsaveLen(tid) | ||
if err != nil { | ||
return nil, err | ||
} | ||
xsaveBuf := make([]byte, len) | ||
ret, err := C.ptrace(C.PT_GETXSTATE, C.pid_t(tid), C.caddr_t(unsafe.Pointer(&xsaveBuf[0])), C.int(len)) | ||
if ret != 0 { | ||
return nil, fmt.Errorf("failed to get xstate: %v", err) | ||
} | ||
return xsaveBuf, nil | ||
} | ||
|
||
// ptraceSetXsave sets the X86 XSAVE data for the given tid. | ||
func ptraceSetXsave(tid int, xsaveBuf []byte) error { | ||
ret, err := C.ptrace(C.PT_SETXSTATE, C.pid_t(tid), C.caddr_t(unsafe.Pointer(&xsaveBuf[0])), C.int(len(xsaveBuf))) | ||
if ret != 0 { | ||
return fmt.Errorf("failed to set xstate: %v", err) | ||
} | ||
return nil | ||
} | ||
|
||
func ptraceGetRegset(id int) (*amd64util.AMD64Xstate, error) { | ||
var regset amd64util.AMD64Xstate | ||
ret, err := C.ptrace(C.PT_GETFPREGS, C.pid_t(id), C.caddr_t(unsafe.Pointer(®set.AMD64PtraceFpRegs)), C.int(0)) | ||
if ret != 0 { | ||
return nil, fmt.Errorf("failed to get FP registers: %v", err) | ||
} | ||
regset.Xsave, err = ptraceGetXsave(id) | ||
if err != nil { | ||
return nil, err | ||
} | ||
err = amd64util.AMD64XstateRead(regset.Xsave, false, ®set) | ||
return ®set, err | ||
} | ||
|
||
func ptraceSetRegset(id int, regset *amd64util.AMD64Xstate) error { | ||
ret, err := C.ptrace(C.PT_SETFPREGS, C.pid_t(id), C.caddr_t(unsafe.Pointer(®set.AMD64PtraceFpRegs)), C.int(0)) | ||
if ret != 0 { | ||
return fmt.Errorf("failed to set FP registers: %v", err) | ||
} | ||
if regset.Xsave != nil { | ||
return ptraceSetXsave(id, regset.Xsave) | ||
} | ||
return nil | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.