From 2ff04f1a87fc72a4ffc730d7b64af2da1ab25d94 Mon Sep 17 00:00:00 2001 From: Damian Gryski Date: Wed, 18 Mar 2026 11:00:09 -0700 Subject: [PATCH] runtime: split syscall functions for darwin changes for 1.26 --- src/runtime/os_darwin.go | 67 -------------------------------- src/runtime/os_darwin_go125.go | 70 ++++++++++++++++++++++++++++++++++ src/runtime/os_darwin_go126.go | 69 +++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 67 deletions(-) create mode 100644 src/runtime/os_darwin_go125.go create mode 100644 src/runtime/os_darwin_go126.go diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go index df5c59880..7197c4397 100644 --- a/src/runtime/os_darwin.go +++ b/src/runtime/os_darwin.go @@ -130,73 +130,6 @@ func syscall_Getpagesize() int { return int(libc_getpagesize()) } -// Call "system calls" (actually: libc functions) in a special way. -// - Most calls calls return a C int (which is 32-bits), and -1 on failure. -// - syscallX* is for functions that return a 64-bit integer (and also return -// -1 on failure). -// - syscallPtr is for functions that return a pointer on success or NULL on -// failure. -// - rawSyscall seems to avoid some stack modifications, which isn't relevant -// to TinyGo. - -//go:linkname syscall_syscall syscall.syscall -func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { - // For TinyGo we don't need to do anything special to call C functions. - return syscall_rawSyscall(fn, a1, a2, a3) -} - -//go:linkname syscall_rawSyscall syscall.rawSyscall -func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { - result := call_syscall(fn, a1, a2, a3) - r1 = uintptr(result) - if result == -1 { - // Syscall returns -1 on failure. - err = uintptr(*libc_errno_location()) - } - return -} - -//go:linkname syscall_syscallX syscall.syscallX -func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { - r1 = call_syscallX(fn, a1, a2, a3) - if int64(r1) == -1 { - // Syscall returns -1 on failure. - err = uintptr(*libc_errno_location()) - } - return -} - -//go:linkname syscall_syscallPtr syscall.syscallPtr -func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { - r1 = call_syscallX(fn, a1, a2, a3) - if r1 == 0 { - // Syscall returns a pointer on success, or NULL on failure. - err = uintptr(*libc_errno_location()) - } - return -} - -//go:linkname syscall_syscall6 syscall.syscall6 -func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { - result := call_syscall6(fn, a1, a2, a3, a4, a5, a6) - r1 = uintptr(result) - if result == -1 { - // Syscall returns -1 on failure. - err = uintptr(*libc_errno_location()) - } - return -} - -//go:linkname syscall_syscall6X syscall.syscall6X -func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { - r1 = call_syscall6X(fn, a1, a2, a3, a4, a5, a6) - if int64(r1) == -1 { - // Syscall returns -1 on failure. - err = uintptr(*libc_errno_location()) - } - return -} - // uint32_t arc4random(void); // //export arc4random diff --git a/src/runtime/os_darwin_go125.go b/src/runtime/os_darwin_go125.go new file mode 100644 index 000000000..e48bbbe09 --- /dev/null +++ b/src/runtime/os_darwin_go125.go @@ -0,0 +1,70 @@ +//go:build darwin && !go1.26 + +package runtime + +// Call "system calls" (actually: libc functions) in a special way. +// - Most calls calls return a C int (which is 32-bits), and -1 on failure. +// - syscallX* is for functions that return a 64-bit integer (and also return +// -1 on failure). +// - syscallPtr is for functions that return a pointer on success or NULL on +// failure. +// - rawSyscall seems to avoid some stack modifications, which isn't relevant +// to TinyGo. + +//go:linkname syscall_syscall syscall.syscall +func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + // For TinyGo we don't need to do anything special to call C functions. + return syscall_rawSyscall(fn, a1, a2, a3) +} + +//go:linkname syscall_rawSyscall syscall.rawSyscall +func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + result := call_syscall(fn, a1, a2, a3) + r1 = uintptr(result) + if result == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc_errno_location()) + } + return +} + +//go:linkname syscall_syscallX syscall.syscallX +func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + r1 = call_syscallX(fn, a1, a2, a3) + if int64(r1) == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc_errno_location()) + } + return +} + +//go:linkname syscall_syscallPtr syscall.syscallPtr +func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + r1 = call_syscallX(fn, a1, a2, a3) + if r1 == 0 { + // Syscall returns a pointer on success, or NULL on failure. + err = uintptr(*libc_errno_location()) + } + return +} + +//go:linkname syscall_syscall6 syscall.syscall6 +func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { + result := call_syscall6(fn, a1, a2, a3, a4, a5, a6) + r1 = uintptr(result) + if result == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc_errno_location()) + } + return +} + +//go:linkname syscall_syscall6X syscall.syscall6X +func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { + r1 = call_syscall6X(fn, a1, a2, a3, a4, a5, a6) + if int64(r1) == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc_errno_location()) + } + return +} diff --git a/src/runtime/os_darwin_go126.go b/src/runtime/os_darwin_go126.go new file mode 100644 index 000000000..1845fa513 --- /dev/null +++ b/src/runtime/os_darwin_go126.go @@ -0,0 +1,69 @@ +//go:build darwin && go1.26 + +package runtime + +// syscall_syscalln is a wrapper around the libc call with variable arguments. +// +//go:nosplit +//go:linkname syscall_syscalln syscall.syscalln +func syscall_syscalln(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { + r1, r2, err = syscall_rawsyscalln(fn, args...) + return r1, r2, err +} + +// syscall_rawsyscalln is a wrapper around the libc call with variable arguments. +// +//go:linkname syscall_rawsyscalln syscall.rawsyscalln +//go:nosplit +func syscall_rawsyscalln(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { + + var a1, a2, a3, a4, a5, a6 uintptr + + switch len(args) { + case 3: + a3 = args[2] + fallthrough + case 2: + a2 = args[1] + fallthrough + case 1: + a1 = args[0] + fallthrough + case 0: + return runtime_syscall(fn, a1, a2, a3) + + case 6: + a6 = args[5] + fallthrough + case 5: + a5 = args[4] + fallthrough + case 4: + a3 = args[3] + + a1, a2, a3 = args[0], args[1], args[2] + return runtime_syscall6(fn, a1, a2, a3, a4, a5, a6) + } + + panic("syscall args not handled") +} + +func runtime_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + result := call_syscall(fn, a1, a2, a3) + r1 = uintptr(result) + if result == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc_errno_location()) + } + return +} + +func runtime_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { + result := call_syscall6(fn, a1, a2, a3, a4, a5, a6) + r1 = uintptr(result) + if result == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc_errno_location()) + } + return +}