mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
syscall: add SyscallN
This CL adds a new syscall.SyscallN API. The proposal discussion also suggests the API should not only for Windows but other platforms. However, the existing API set already contain differences between platforms, hence the CL only implements the Windows platform. Moreover, although the API offers variadic parameters, the permitted parameters remains up to a limit, which is selected as 42, and arguably large enough. Fixes #46552 Change-Id: I66b49988a304d9fc178c7cd5de46d0b75e167a4f Reviewed-on: https://go-review.googlesource.com/c/go/+/336550 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Trust: Matthew Dempsky <mdempsky@google.com> Trust: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
91e2e3b903
commit
0e598e7da4
6 changed files with 115 additions and 133 deletions
|
|
@ -468,84 +468,69 @@ func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uint
|
|||
|
||||
//go:linkname syscall_Syscall syscall.Syscall
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
|
||||
lockOSThread()
|
||||
defer unlockOSThread()
|
||||
c := &getg().m.syscall
|
||||
c.fn = fn
|
||||
c.n = nargs
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
||||
cgocall(asmstdcallAddr, unsafe.Pointer(c))
|
||||
return c.r1, c.r2, c.err
|
||||
return syscall_SyscallN(fn, a1, a2, a3)
|
||||
}
|
||||
|
||||
//go:linkname syscall_Syscall6 syscall.Syscall6
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
|
||||
lockOSThread()
|
||||
defer unlockOSThread()
|
||||
c := &getg().m.syscall
|
||||
c.fn = fn
|
||||
c.n = nargs
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
||||
cgocall(asmstdcallAddr, unsafe.Pointer(c))
|
||||
return c.r1, c.r2, c.err
|
||||
return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6)
|
||||
}
|
||||
|
||||
//go:linkname syscall_Syscall9 syscall.Syscall9
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
|
||||
lockOSThread()
|
||||
c := &getg().m.syscall
|
||||
c.fn = fn
|
||||
c.n = nargs
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
||||
cgocall(asmstdcallAddr, unsafe.Pointer(c))
|
||||
unlockOSThread()
|
||||
return c.r1, c.r2, c.err
|
||||
return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
}
|
||||
|
||||
//go:linkname syscall_Syscall12 syscall.Syscall12
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
|
||||
lockOSThread()
|
||||
c := &getg().m.syscall
|
||||
c.fn = fn
|
||||
c.n = nargs
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
||||
cgocall(asmstdcallAddr, unsafe.Pointer(c))
|
||||
unlockOSThread()
|
||||
return c.r1, c.r2, c.err
|
||||
return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
|
||||
}
|
||||
|
||||
//go:linkname syscall_Syscall15 syscall.Syscall15
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
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) {
|
||||
lockOSThread()
|
||||
c := &getg().m.syscall
|
||||
c.fn = fn
|
||||
c.n = nargs
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
||||
cgocall(asmstdcallAddr, unsafe.Pointer(c))
|
||||
unlockOSThread()
|
||||
return c.r1, c.r2, c.err
|
||||
return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
|
||||
}
|
||||
|
||||
//go:linkname syscall_Syscall18 syscall.Syscall18
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
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, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18)
|
||||
}
|
||||
|
||||
// maxArgs should be divisible by 2, as Windows stack
|
||||
// must be kept 16-byte aligned on syscall entry.
|
||||
//
|
||||
// Although it only permits maximum 42 parameters, it
|
||||
// is arguably large enough.
|
||||
const maxArgs = 42
|
||||
|
||||
//go:linkname syscall_SyscallN syscall.SyscallN
|
||||
//go:nosplit
|
||||
func syscall_SyscallN(trap uintptr, args ...uintptr) (r1, r2, err uintptr) {
|
||||
nargs := len(args)
|
||||
|
||||
// asmstdcall expects it can access the first 4 arguments
|
||||
// to load them into registers.
|
||||
var tmp [4]uintptr
|
||||
switch {
|
||||
case nargs < 4:
|
||||
copy(tmp[:], args)
|
||||
args = tmp[:]
|
||||
case nargs > maxArgs:
|
||||
panic("runtime: SyscallN has too many arguments")
|
||||
}
|
||||
|
||||
lockOSThread()
|
||||
defer unlockOSThread()
|
||||
c := &getg().m.syscall
|
||||
c.fn = fn
|
||||
c.n = nargs
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&a1)))
|
||||
c.fn = trap
|
||||
c.n = uintptr(nargs)
|
||||
c.args = uintptr(noescape(unsafe.Pointer(&args[0])))
|
||||
cgocall(asmstdcallAddr, unsafe.Pointer(c))
|
||||
unlockOSThread()
|
||||
return c.r1, c.r2, c.err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue