aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sys_darwin.go
diff options
context:
space:
mode:
authorqmuntal <quimmuntal@gmail.com>2025-08-26 11:47:51 +0200
committerQuim Muntal <quimmuntal@gmail.com>2025-09-15 01:16:22 -0700
commit8320fe8f0e5283eb67429de30b4e24be6a85c7a7 (patch)
treec9769641570bc4f484c6f88a10b5e27fa90062f8 /src/runtime/sys_darwin.go
parent080882a928c96f997a1cb67cef40d2cc6126ffcd (diff)
downloadgo-8320fe8f0e5283eb67429de30b4e24be6a85c7a7.tar.xz
runtime: deduplicate syscall assembly for darwin
The darwin port provides different syscall functions that only differ on how they handle the errors, and they are all written in assembly. This duplication can be removed by factoring out the error handling logic to arch-agnostic Go code and leaving the assembly functions with the only reponsibility of making the syscall and mapping parameters between ABIs. Updates #51087 Cq-Include-Trybots: luci.golang.try:gotip-darwin-arm64-longtest,gotip-darwin-amd64-longtest Change-Id: I9524377f3ef9c9a638412c7e87c8f46a33ee3453 Reviewed-on: https://go-review.googlesource.com/c/go/+/699135 Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Mark Freeman <markfreeman@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/runtime/sys_darwin.go')
-rw-r--r--src/runtime/sys_darwin.go136
1 files changed, 99 insertions, 37 deletions
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
index ad423afc60..aa628021a0 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -10,12 +10,27 @@ import (
"unsafe"
)
+//go:nosplit
+func libcError() uintptr {
+ errPtr, _ := syscall(abi.FuncPCABI0(libc_error_trampoline), 0, 0, 0)
+ return errPtr
+}
+func libc_error_trampoline()
+
// The X versions of syscall expect the libc call to return a 64-bit result.
// Otherwise (the non-X version) expects a 32-bit result.
// This distinction is required because an error is indicated by returning -1,
// and we need to know whether to check 32 or 64 bits of the result.
// (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.)
+//go:nosplit
+func syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr) {
+ args := struct{ fn, a1, a2, a3, r1, r2 uintptr }{fn, a1, a2, a3, r1, r2}
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall_trampoline)), unsafe.Pointer(&args))
+ return args.r1, args.r2
+}
+func syscall_trampoline()
+
// golang.org/x/sys linknames syscall_syscall
// (in addition to standard package syscall).
// Do not remove or change the type signature.
@@ -23,24 +38,28 @@ import (
//go:linkname syscall_syscall syscall.syscall
//go:nosplit
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&args))
+ r1, r2, err = syscall_rawSyscall(fn, a1, a2, a3)
exitsyscall()
- return args.r1, args.r2, args.err
+ return r1, r2, err
}
-func syscall()
//go:linkname syscall_syscallX syscall.syscallX
//go:nosplit
func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallX)), unsafe.Pointer(&args))
+ r1, r2, err = syscall_rawSyscallX(fn, a1, a2, a3)
exitsyscall()
- return args.r1, args.r2, args.err
+ return r1, r2, err
}
-func syscallX()
+
+//go:nosplit
+func syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr) {
+ args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2 uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2}
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6_trampoline)), unsafe.Pointer(&args))
+ return args.r1, args.r2
+}
+func syscall6_trampoline()
// golang.org/x/sys linknames syscall.syscall6
// (in addition to standard package syscall).
@@ -56,13 +75,28 @@ func syscallX()
//go:linkname syscall_syscall6 syscall.syscall6
//go:nosplit
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err}
entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&args))
+ r1, r2, err = syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6)
+ exitsyscall()
+ return r1, r2, err
+}
+
+//go:linkname syscall_syscall6X syscall.syscall6X
+//go:nosplit
+func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+ entersyscall()
+ r1, r2, err = syscall_rawSyscall6X(fn, a1, a2, a3, a4, a5, a6)
exitsyscall()
- return args.r1, args.r2, args.err
+ return r1, r2, err
}
-func syscall6()
+
+//go:nosplit
+func syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr) {
+ args := struct{ fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, r1, r2 uintptr }{fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, r1, r2}
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall9_trampoline)), unsafe.Pointer(&args))
+ return args.r1, args.r2
+}
+func syscall9_trampoline()
// golang.org/x/sys linknames syscall.syscall9
// (in addition to standard package syscall).
@@ -71,24 +105,11 @@ func syscall6()
//go:linkname syscall_syscall9 syscall.syscall9
//go:nosplit
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, r1, r2, err}
- entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall9)), unsafe.Pointer(&args))
- exitsyscall()
- return args.r1, args.r2, args.err
-}
-func syscall9()
-
-//go:linkname syscall_syscall6X syscall.syscall6X
-//go:nosplit
-func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err}
entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&args))
+ r1, r2, err = syscall_rawSyscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9)
exitsyscall()
- return args.r1, args.r2, args.err
+ return r1, r2, err
}
-func syscall6X()
// golang.org/x/sys linknames syscall.syscallPtr
// (in addition to standard package syscall).
@@ -97,13 +118,11 @@ func syscall6X()
//go:linkname syscall_syscallPtr syscall.syscallPtr
//go:nosplit
func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallPtr)), unsafe.Pointer(&args))
+ r1, r2, err = syscall_rawSyscallPtr(fn, a1, a2, a3)
exitsyscall()
- return args.r1, args.r2, args.err
+ return r1, r2, err
}
-func syscallPtr()
// golang.org/x/sys linknames syscall_rawSyscall
// (in addition to standard package syscall).
@@ -112,9 +131,30 @@ func syscallPtr()
//go:linkname syscall_rawSyscall syscall.rawSyscall
//go:nosplit
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&args))
- return args.r1, args.r2, args.err
+ r1, r2 = syscall(fn, a1, a2, a3)
+ // Check if r1 low 32 bits is -1, indicating an error.
+ if int32(r1) == -1 {
+ err = libcError()
+ }
+ return r1, r2, err
+}
+
+//go:nosplit
+func syscall_rawSyscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+ r1, r2 = syscall(fn, a1, a2, a3)
+ if r1 == ^uintptr(0) {
+ err = libcError()
+ }
+ return r1, r2, err
+}
+
+//go:nosplit
+func syscall_rawSyscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+ r1, r2 = syscall(fn, a1, a2, a3)
+ if r1 == 0 {
+ err = libcError()
+ }
+ return r1, r2, err
}
// golang.org/x/sys linknames syscall_rawSyscall6
@@ -124,9 +164,31 @@ func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
//go:nosplit
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err}
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&args))
- return args.r1, args.r2, args.err
+ r1, r2 = syscall6(fn, a1, a2, a3, a4, a5, a6)
+ // Check if r1 low 32 bits is -1, indicating an error.
+ if int32(r1) == -1 {
+ err = libcError()
+ }
+ return r1, r2, err
+}
+
+//go:nosplit
+func syscall_rawSyscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+ r1, r2 = syscall6(fn, a1, a2, a3, a4, a5, a6)
+ if r1 == ^uintptr(0) {
+ err = libcError()
+ }
+ return r1, r2, err
+}
+
+//go:nosplit
+func syscall_rawSyscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
+ r1, r2 = syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9)
+ // Check if r1 low 32 bits is -1, indicating an error.
+ if int32(r1) == -1 {
+ err = libcError()
+ }
+ return r1, r2, err
}
// crypto_x509_syscall is used in crypto/x509/internal/macos to call into Security.framework and CF.