mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 18:47:47 +00:00
ddacdfacd5
Go 1.26 changed all Windows syscall wrappers in zsyscall_windows.go to use SyscallN instead of fixed-argument Syscall/Syscall6/etc. The SyscallN function now has a body that calls an unexported syscalln function (provided by runtime via //go:linkname). TinyGo's existing createSyscall compiler builtin used call.Args[2:] to extract syscall arguments, but for variadic SyscallN the SSA representation passes args as a slice value (not individual args), causing call.Args[2:] to be empty -- resulting in zero arguments being passed to Windows API calls and 0xc0000005 access violations. Fix this by: 1. Excluding syscall.SyscallN from builtin interception, letting Go 1.26's function body compile normally (it calls syscalln) 2. Adding a new createSyscalln compiler builtin that intercepts syscall.syscalln and correctly handles the variadic slice: - Generates a switch on the arg count n (0-18 cases) - Each case loads args from the slice via GEP/Load - Wraps calls with SetLastError(0)/GetLastError() as before - Handles i386 stdcall conventions 3. Adding runtime stubs for both Go versions: - go1.26: syscall.syscalln stub (body intercepted by compiler) - pre-go1.26: syscall.SyscallN stub (linker satisfaction)
18 lines
818 B
Go
18 lines
818 B
Go
//go:build windows && go1.26
|
|
|
|
package runtime
|
|
|
|
// Starting with Go 1.26, the syscall package on Windows defines function bodies
|
|
// for Syscall, SyscallN, etc., that all call syscalln (lowercase). In standard
|
|
// Go, syscalln is provided by the runtime via //go:linkname. TinyGo's compiler
|
|
// intercepts calls to syscall.syscalln and replaces them with inline LLVM IR
|
|
// (see compiler/syscall.go createSyscalln), so this function body is never
|
|
// actually called at runtime. However, the compiled function bodies in the
|
|
// syscall package still reference it, so we must provide a definition to
|
|
// satisfy the linker.
|
|
|
|
//go:linkname syscall_syscalln syscall.syscalln
|
|
func syscall_syscalln(fn, n uintptr, args ...uintptr) (r1, r2, err uintptr) {
|
|
panic("unreachable: syscall.syscalln should be handled by the compiler")
|
|
}
|