runtime,syscall: move SyscallX implementations from runtime to syscall

There is no need for syscall.Syscall{3,6,9,12,15,18} to be implemented
in the runtime and linknamed from syscall. All of them can be
implemented using the single runtime.syscall_syscalln function.

While here, improve the documentation of syscall.SyscallN.

Change-Id: I0e09d42e855d6baf900354c9b7992a4329c4ffc7
Reviewed-on: https://go-review.googlesource.com/c/go/+/690515
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
qmuntal 2025-07-25 15:25:37 +02:00 committed by Quim Muntal
parent c7ed3a1c5a
commit 98f301cf68
2 changed files with 62 additions and 53 deletions

View file

@ -416,7 +416,7 @@ const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
//go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary
func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) {
handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) handle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_LoadLibraryExW)), 3, uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32)
KeepAlive(filename) KeepAlive(filename)
if handle != 0 { if handle != 0 {
err = 0 err = 0
@ -430,7 +430,7 @@ func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) {
// //
//go:linkname syscall_loadlibrary syscall.loadlibrary //go:linkname syscall_loadlibrary syscall.loadlibrary
func syscall_loadlibrary(filename *uint16) (handle, err uintptr) { func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryW)), uintptr(unsafe.Pointer(filename))) handle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_LoadLibraryW)), 1, uintptr(unsafe.Pointer(filename)))
KeepAlive(filename) KeepAlive(filename)
if handle != 0 { if handle != 0 {
err = 0 err = 0
@ -444,7 +444,7 @@ func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
// //
//go:linkname syscall_getprocaddress syscall.getprocaddress //go:linkname syscall_getprocaddress syscall.getprocaddress
func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) { func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
outhandle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_GetProcAddress)), handle, uintptr(unsafe.Pointer(procname))) outhandle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_GetProcAddress)), 2, handle, uintptr(unsafe.Pointer(procname)))
KeepAlive(procname) KeepAlive(procname)
if outhandle != 0 { if outhandle != 0 {
err = 0 err = 0
@ -452,48 +452,7 @@ func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uint
return return
} }
//go:linkname syscall_Syscall syscall.Syscall //go:linkname syscall_syscalln syscall.syscalln
//go:nosplit
func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
return syscall_syscalln(fn, nargs, a1, a2, a3)
}
//go:linkname syscall_Syscall6 syscall.Syscall6
//go:nosplit
func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
return syscall_syscalln(fn, nargs, a1, a2, a3, a4, a5, a6)
}
//go:linkname syscall_Syscall9 syscall.Syscall9
//go:nosplit
func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
return syscall_syscalln(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9)
}
//go:linkname syscall_Syscall12 syscall.Syscall12
//go:nosplit
func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
return syscall_syscalln(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
}
//go:linkname syscall_Syscall15 syscall.Syscall15
//go:nosplit
func syscall_Syscall15(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) {
return syscall_syscalln(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
}
//go:linkname syscall_Syscall18 syscall.Syscall18
//go:nosplit
func syscall_Syscall18(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2, err uintptr) {
return syscall_syscalln(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18)
}
//go:linkname syscall_SyscallN syscall.SyscallN
//go:nosplit
func syscall_SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) {
return syscall_syscalln(fn, uintptr(len(args)), args...)
}
//go:nosplit //go:nosplit
func syscall_syscalln(fn, n uintptr, args ...uintptr) (r1, r2, err uintptr) { func syscall_syscalln(fn, n uintptr, args ...uintptr) (r1, r2, err uintptr) {
if n > uintptr(len(args)) { if n > uintptr(len(args)) {

View file

@ -22,28 +22,78 @@ func (e *DLLError) Error() string { return e.Msg }
func (e *DLLError) Unwrap() error { return e.Err } func (e *DLLError) Unwrap() error { return e.Err }
// Implemented in ../runtime/syscall_windows.go. // N.B. For the Syscall functions below:
//
// //go:uintptrkeepalive because the uintptr argument may be converted pointers
// that need to be kept alive in the caller.
//
// //go:nosplit because stack copying does not account for uintptrkeepalive, so
// the stack must not grow. Stack copying cannot blindly assume that all
// uintptr arguments are pointers, because some values may look like pointers,
// but not really be pointers, and adjusting their value would break the call.
// Deprecated: Use [SyscallN] instead. // Deprecated: Use [SyscallN] instead.
func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) //
//go:nosplit
//go:uintptrkeepalive
func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
return syscalln(trap, nargs, a1, a2, a3)
}
// Deprecated: Use [SyscallN] instead. // Deprecated: Use [SyscallN] instead.
func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) //
//go:nosplit
//go:uintptrkeepalive
func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
return syscalln(trap, nargs, a1, a2, a3, a4, a5, a6)
}
// Deprecated: Use [SyscallN] instead. // Deprecated: Use [SyscallN] instead.
func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) //
//go:nosplit
//go:uintptrkeepalive
func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
return syscalln(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9)
}
// Deprecated: Use [SyscallN] instead. // Deprecated: Use [SyscallN] instead.
func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno) //
//go:nosplit
//go:uintptrkeepalive
func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno) {
return syscalln(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
}
// Deprecated: Use [SyscallN] instead. // Deprecated: Use [SyscallN] instead.
func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno) //
//go:nosplit
//go:uintptrkeepalive
func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno) {
return syscalln(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
}
// Deprecated: Use [SyscallN] instead. // Deprecated: Use [SyscallN] instead.
func Syscall18(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2 uintptr, err Errno) //
//go:nosplit
//go:uintptrkeepalive
func Syscall18(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2 uintptr, err Errno) {
return syscalln(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18)
}
// SyscallN executes procedure p with arguments args.
//
// See [Proc.Call] for more information.
//
//go:nosplit
//go:uintptrkeepalive
func SyscallN(p uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) {
return syscalln(p, uintptr(len(args)), args...)
}
// syscalln is implemented in runtime/syscall_windows.go.
//
//go:noescape //go:noescape
func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) func syscalln(fn, n uintptr, args ...uintptr) (r1, r2 uintptr, err Errno)
func loadlibrary(filename *uint16) (handle uintptr, err Errno) func loadlibrary(filename *uint16) (handle uintptr, err Errno)
func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno)
func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno)