mirror of
https://github.com/golang/go.git
synced 2026-04-02 09:20:29 +09:00
syscall: remove the 42 args limit in SyscallN
SyscallN already supports more than 42 arguments on 386 and arm64. Lift that limit on amd64 as well. Change-Id: I3f5c6ebb959aa9b0d367903cac119fc27cb93064 Reviewed-on: https://go-review.googlesource.com/c/go/+/751862 Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Carlos Amedee <carlos@golang.org>
This commit is contained in:
@@ -23,19 +23,22 @@ TEXT ·asmstdcall(SB),NOSPLIT,$16
|
||||
MOVQ 0x30(GS), DI
|
||||
MOVL $0, 0x68(DI)
|
||||
|
||||
SUBQ $(const_MaxArgs*8), SP // room for args
|
||||
MOVQ SP, R12 // save frame pointer in the callee-saved R12 register to restore it before return
|
||||
SUBQ $32, SP // reserve shadow space (Windows x64 ABI)
|
||||
|
||||
// Fast version, do not store args on the stack.
|
||||
// Fast version (n <= 4): no stack copy needed.
|
||||
CMPL CX, $0; JE _0args
|
||||
CMPL CX, $1; JE _1args
|
||||
CMPL CX, $2; JE _2args
|
||||
CMPL CX, $3; JE _3args
|
||||
CMPL CX, $4; JE _4args
|
||||
|
||||
// Check we have enough room for args.
|
||||
CMPL CX, $const_MaxArgs
|
||||
JLE 2(PC)
|
||||
INT $3 // not enough room -> crash
|
||||
// Slow version (n > 4): grow stack for remaining args.
|
||||
// Stack stays 16-byte aligned by rounding extra slots to even.
|
||||
LEAQ -3(CX), R8
|
||||
ANDQ $~1, R8
|
||||
SHLQ $3, R8
|
||||
SUBQ R8, SP
|
||||
|
||||
// Copy args to the stack.
|
||||
MOVQ SP, DI
|
||||
@@ -65,7 +68,7 @@ _0args:
|
||||
// Call stdcall function.
|
||||
CALL AX
|
||||
|
||||
ADDQ $(const_MaxArgs*8), SP
|
||||
MOVQ R12, SP // restore frame pointer
|
||||
|
||||
// Return result.
|
||||
MOVQ 0(SP), CX
|
||||
|
||||
@@ -10,13 +10,6 @@ import (
|
||||
"internal/abi"
|
||||
)
|
||||
|
||||
// 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
|
||||
|
||||
// StdCallInfo is a structure used to pass parameters to the system call.
|
||||
type StdCallInfo struct {
|
||||
Fn uintptr
|
||||
|
||||
@@ -7,7 +7,6 @@ package runtime
|
||||
import (
|
||||
"internal/abi"
|
||||
"internal/goarch"
|
||||
"internal/runtime/syscall/windows"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -415,9 +414,6 @@ func syscall_syscalln(fn, n uintptr, args ...uintptr) (r1, r2, err uintptr) {
|
||||
if n > uintptr(len(args)) {
|
||||
panic("syscall: n > len(args)") // should not be reachable from user code
|
||||
}
|
||||
if n > windows.MaxArgs {
|
||||
panic("runtime: SyscallN has too many arguments")
|
||||
}
|
||||
|
||||
// The cgocall parameters are stored in m instead of in
|
||||
// the stack because the stack can move during fn if it
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"fmt"
|
||||
"internal/abi"
|
||||
"internal/race"
|
||||
"internal/runtime/syscall/windows"
|
||||
"internal/syscall/windows/sysdll"
|
||||
"internal/testenv"
|
||||
"io"
|
||||
@@ -773,12 +772,13 @@ func TestSyscallN(t *testing.T) {
|
||||
if _, err := exec.LookPath("gcc"); err != nil {
|
||||
t.Skip("skipping test: gcc is missing")
|
||||
}
|
||||
if runtime.GOARCH != "amd64" {
|
||||
t.Skipf("skipping test: GOARCH=%s", runtime.GOARCH)
|
||||
|
||||
var nargs = 64
|
||||
if testing.Short() {
|
||||
nargs = 16
|
||||
}
|
||||
|
||||
for arglen := 0; arglen <= windows.MaxArgs; arglen++ {
|
||||
arglen := arglen
|
||||
for arglen := range nargs {
|
||||
t.Run(fmt.Sprintf("arg-%d", arglen), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
args := make([]string, arglen)
|
||||
|
||||
Reference in New Issue
Block a user