From 8320fe8f0e5283eb67429de30b4e24be6a85c7a7 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Tue, 26 Aug 2025 11:47:51 +0200 Subject: [PATCH] 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 Reviewed-by: Mark Freeman LUCI-TryBot-Result: Go LUCI --- src/runtime/sys_darwin.go | 136 ++++++++++++++++------- src/runtime/sys_darwin_amd64.s | 190 +++------------------------------ src/runtime/sys_darwin_arm64.s | 174 +++--------------------------- 3 files changed, 131 insertions(+), 369 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. diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s index cc4e52d305..e746257967 100644 --- a/src/runtime/sys_darwin_amd64.s +++ b/src/runtime/sys_darwin_amd64.s @@ -506,8 +506,8 @@ TEXT runtime·arc4random_buf_trampoline(SB),NOSPLIT,$0 CALL libc_arc4random_buf(SB) RET -// syscall calls a function in libc on behalf of the syscall package. -// syscall takes a pointer to a struct like: +// syscall_trampoline calls a function in libc on behalf of the syscall package. +// syscall_trampoline takes a pointer to a struct like: // struct { // fn uintptr // a1 uintptr @@ -515,14 +515,10 @@ TEXT runtime·arc4random_buf_trampoline(SB),NOSPLIT,$0 // a3 uintptr // r1 uintptr // r2 uintptr -// err uintptr // } -// syscall must be called on the g0 stack with the +// syscall_trampoline must be called on the g0 stack with the // C calling convention (use libcCall). -// -// syscall expects a 32-bit result and tests for 32-bit -1 -// to decide there was an error. -TEXT runtime·syscall(SB),NOSPLIT,$16 +TEXT runtime·syscall_trampoline(SB),NOSPLIT,$16 MOVQ (0*8)(DI), CX // fn MOVQ (2*8)(DI), SI // a2 MOVQ (3*8)(DI), DX // a3 @@ -536,99 +532,11 @@ TEXT runtime·syscall(SB),NOSPLIT,$16 MOVQ AX, (4*8)(DI) // r1 MOVQ DX, (5*8)(DI) // r2 - // Standard libc functions return -1 on error - // and set errno. - CMPL AX, $-1 // Note: high 32 bits are junk - JNE ok - - // Get error code from libc. - CALL libc_error(SB) - MOVLQSX (AX), AX - MOVQ (SP), DI - MOVQ AX, (6*8)(DI) // err - -ok: XORL AX, AX // no error (it's ignored anyway) RET -// syscallX calls a function in libc on behalf of the syscall package. -// syscallX takes a pointer to a struct like: -// struct { -// fn uintptr -// a1 uintptr -// a2 uintptr -// a3 uintptr -// r1 uintptr -// r2 uintptr -// err uintptr -// } -// syscallX must be called on the g0 stack with the -// C calling convention (use libcCall). -// -// syscallX is like syscall but expects a 64-bit result -// and tests for 64-bit -1 to decide there was an error. -TEXT runtime·syscallX(SB),NOSPLIT,$16 - MOVQ (0*8)(DI), CX // fn - MOVQ (2*8)(DI), SI // a2 - MOVQ (3*8)(DI), DX // a3 - MOVQ DI, (SP) - MOVQ (1*8)(DI), DI // a1 - XORL AX, AX // vararg: say "no float args" - - CALL CX - - MOVQ (SP), DI - MOVQ AX, (4*8)(DI) // r1 - MOVQ DX, (5*8)(DI) // r2 - - // Standard libc functions return -1 on error - // and set errno. - CMPQ AX, $-1 - JNE ok - - // Get error code from libc. - CALL libc_error(SB) - MOVLQSX (AX), AX - MOVQ (SP), DI - MOVQ AX, (6*8)(DI) // err - -ok: - XORL AX, AX // no error (it's ignored anyway) - RET - -// syscallPtr is like syscallX except that the libc function reports an -// error by returning NULL and setting errno. -TEXT runtime·syscallPtr(SB),NOSPLIT,$16 - MOVQ (0*8)(DI), CX // fn - MOVQ (2*8)(DI), SI // a2 - MOVQ (3*8)(DI), DX // a3 - MOVQ DI, (SP) - MOVQ (1*8)(DI), DI // a1 - XORL AX, AX // vararg: say "no float args" - - CALL CX - - MOVQ (SP), DI - MOVQ AX, (4*8)(DI) // r1 - MOVQ DX, (5*8)(DI) // r2 - - // syscallPtr libc functions return NULL on error - // and set errno. - TESTQ AX, AX - JNE ok - - // Get error code from libc. - CALL libc_error(SB) - MOVLQSX (AX), AX - MOVQ (SP), DI - MOVQ AX, (6*8)(DI) // err - -ok: - XORL AX, AX // no error (it's ignored anyway) - RET - -// syscall6 calls a function in libc on behalf of the syscall package. -// syscall6 takes a pointer to a struct like: +// syscall6_trampoline calls a function in libc on behalf of the syscall package. +// syscall6_trampoline takes a pointer to a struct like: // struct { // fn uintptr // a1 uintptr @@ -639,14 +547,10 @@ ok: // a6 uintptr // r1 uintptr // r2 uintptr -// err uintptr // } -// syscall6 must be called on the g0 stack with the +// syscall6_trampoline must be called on the g0 stack with the // C calling convention (use libcCall). -// -// syscall6 expects a 32-bit result and tests for 32-bit -1 -// to decide there was an error. -TEXT runtime·syscall6(SB),NOSPLIT,$16 +TEXT runtime·syscall6_trampoline(SB),NOSPLIT,$16 MOVQ (0*8)(DI), R11// fn MOVQ (2*8)(DI), SI // a2 MOVQ (3*8)(DI), DX // a3 @@ -663,68 +567,11 @@ TEXT runtime·syscall6(SB),NOSPLIT,$16 MOVQ AX, (7*8)(DI) // r1 MOVQ DX, (8*8)(DI) // r2 - CMPL AX, $-1 - JNE ok - - CALL libc_error(SB) - MOVLQSX (AX), AX - MOVQ (SP), DI - MOVQ AX, (9*8)(DI) // err - -ok: XORL AX, AX // no error (it's ignored anyway) RET -// syscall6X calls a function in libc on behalf of the syscall package. -// syscall6X takes a pointer to a struct like: -// struct { -// fn uintptr -// a1 uintptr -// a2 uintptr -// a3 uintptr -// a4 uintptr -// a5 uintptr -// a6 uintptr -// r1 uintptr -// r2 uintptr -// err uintptr -// } -// syscall6X must be called on the g0 stack with the -// C calling convention (use libcCall). -// -// syscall6X is like syscall6 but expects a 64-bit result -// and tests for 64-bit -1 to decide there was an error. -TEXT runtime·syscall6X(SB),NOSPLIT,$16 - MOVQ (0*8)(DI), R11// fn - MOVQ (2*8)(DI), SI // a2 - MOVQ (3*8)(DI), DX // a3 - MOVQ (4*8)(DI), CX // a4 - MOVQ (5*8)(DI), R8 // a5 - MOVQ (6*8)(DI), R9 // a6 - MOVQ DI, (SP) - MOVQ (1*8)(DI), DI // a1 - XORL AX, AX // vararg: say "no float args" - - CALL R11 - - MOVQ (SP), DI - MOVQ AX, (7*8)(DI) // r1 - MOVQ DX, (8*8)(DI) // r2 - - CMPQ AX, $-1 - JNE ok - - CALL libc_error(SB) - MOVLQSX (AX), AX - MOVQ (SP), DI - MOVQ AX, (9*8)(DI) // err - -ok: - XORL AX, AX // no error (it's ignored anyway) - RET - -// syscall9 calls a function in libc on behalf of the syscall package. -// syscall9 takes a pointer to a struct like: +// syscall9_trampoline calls a function in libc on behalf of the syscall package. +// syscall9_trampoline takes a pointer to a struct like: // struct { // fn uintptr // a1 uintptr @@ -740,12 +587,9 @@ ok: // r2 uintptr // err uintptr // } -// syscall9 must be called on the g0 stack with the +// syscall9_trampoline must be called on the g0 stack with the // C calling convention (use libcCall). -// -// syscall9 expects a 32-bit result and tests for 32-bit -1 -// to decide there was an error. -TEXT runtime·syscall9(SB),NOSPLIT,$32 +TEXT runtime·syscall9_trampoline(SB),NOSPLIT,$32 MOVQ (0*8)(DI), R13// fn MOVQ (2*8)(DI), SI // a2 MOVQ (3*8)(DI), DX // a3 @@ -768,16 +612,12 @@ TEXT runtime·syscall9(SB),NOSPLIT,$32 MOVQ AX, (10*8)(DI) // r1 MOVQ DX, (11*8)(DI) // r2 - CMPL AX, $-1 - JNE ok + XORL AX, AX // no error (it's ignored anyway) + RET +TEXT runtime·libc_error_trampoline(SB),NOSPLIT,$0 CALL libc_error(SB) MOVLQSX (AX), AX - MOVQ 24(SP), DI - MOVQ AX, (12*8)(DI) // err - -ok: - XORL AX, AX // no error (it's ignored anyway) RET // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors, diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s index a3901bdb3b..adbb2adafe 100644 --- a/src/runtime/sys_darwin_arm64.s +++ b/src/runtime/sys_darwin_arm64.s @@ -481,8 +481,8 @@ TEXT runtime·arc4random_buf_trampoline(SB),NOSPLIT,$0 BL libc_arc4random_buf(SB) RET -// syscall calls a function in libc on behalf of the syscall package. -// syscall takes a pointer to a struct like: +// syscall_trampoline calls a function in libc on behalf of the syscall package. +// syscall_trampoline takes a pointer to a struct like: // struct { // fn uintptr // a1 uintptr @@ -490,12 +490,11 @@ TEXT runtime·arc4random_buf_trampoline(SB),NOSPLIT,$0 // a3 uintptr // r1 uintptr // r2 uintptr -// err uintptr // } -// syscall must be called on the g0 stack with the +// syscall_trampoline must be called on the g0 stack with the // C calling convention (use libcCall). -TEXT runtime·syscall(SB),NOSPLIT,$0 - SUB $16, RSP // push structure pointer +TEXT runtime·syscall_trampoline(SB),NOSPLIT,$0 + SUB $16, RSP // push structure pointer MOVD R0, 8(RSP) MOVD 0(R0), R12 // fn @@ -517,87 +516,10 @@ TEXT runtime·syscall(SB),NOSPLIT,$0 ADD $16, RSP MOVD R0, 32(R2) // save r1 MOVD R1, 40(R2) // save r2 - CMPW $-1, R0 - BNE ok - SUB $16, RSP // push structure pointer - MOVD R2, 8(RSP) - BL libc_error(SB) - MOVW (R0), R0 - MOVD 8(RSP), R2 // pop structure pointer - ADD $16, RSP - MOVD R0, 48(R2) // save err -ok: - RET - -// syscallX calls a function in libc on behalf of the syscall package. -// syscallX takes a pointer to a struct like: -// struct { -// fn uintptr -// a1 uintptr -// a2 uintptr -// a3 uintptr -// r1 uintptr -// r2 uintptr -// err uintptr -// } -// syscallX must be called on the g0 stack with the -// C calling convention (use libcCall). -TEXT runtime·syscallX(SB),NOSPLIT,$0 - SUB $16, RSP // push structure pointer - MOVD R0, (RSP) - - MOVD 0(R0), R12 // fn - MOVD 16(R0), R1 // a2 - MOVD 24(R0), R2 // a3 - MOVD 8(R0), R0 // a1 - BL (R12) - - MOVD (RSP), R2 // pop structure pointer - ADD $16, RSP - MOVD R0, 32(R2) // save r1 - MOVD R1, 40(R2) // save r2 - CMP $-1, R0 - BNE ok - SUB $16, RSP // push structure pointer - MOVD R2, (RSP) - BL libc_error(SB) - MOVW (R0), R0 - MOVD (RSP), R2 // pop structure pointer - ADD $16, RSP - MOVD R0, 48(R2) // save err -ok: - RET - -// syscallPtr is like syscallX except that the libc function reports an -// error by returning NULL and setting errno. -TEXT runtime·syscallPtr(SB),NOSPLIT,$0 - SUB $16, RSP // push structure pointer - MOVD R0, (RSP) - - MOVD 0(R0), R12 // fn - MOVD 16(R0), R1 // a2 - MOVD 24(R0), R2 // a3 - MOVD 8(R0), R0 // a1 - BL (R12) - - MOVD (RSP), R2 // pop structure pointer - ADD $16, RSP - MOVD R0, 32(R2) // save r1 - MOVD R1, 40(R2) // save r2 - CMP $0, R0 - BNE ok - SUB $16, RSP // push structure pointer - MOVD R2, (RSP) - BL libc_error(SB) - MOVW (R0), R0 - MOVD (RSP), R2 // pop structure pointer - ADD $16, RSP - MOVD R0, 48(R2) // save err -ok: RET -// syscall6 calls a function in libc on behalf of the syscall package. -// syscall6 takes a pointer to a struct like: +// syscall6_trampoline calls a function in libc on behalf of the syscall package. +// syscall6_trampoline takes a pointer to a struct like: // struct { // fn uintptr // a1 uintptr @@ -608,11 +530,10 @@ ok: // a6 uintptr // r1 uintptr // r2 uintptr -// err uintptr // } -// syscall6 must be called on the g0 stack with the +// syscall6_trampoline must be called on the g0 stack with the // C calling convention (use libcCall). -TEXT runtime·syscall6(SB),NOSPLIT,$0 +TEXT runtime·syscall6_trampoline(SB),NOSPLIT,$0 SUB $16, RSP // push structure pointer MOVD R0, 8(RSP) @@ -625,7 +546,7 @@ TEXT runtime·syscall6(SB),NOSPLIT,$0 MOVD 8(R0), R0 // a1 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. - // See syscall above. The only function this applies to is openat, for which the 4th + // See syscall_trampoline above. The only function this applies to is openat, for which the 4th // arg must be on the stack. MOVD R3, (RSP) @@ -635,65 +556,10 @@ TEXT runtime·syscall6(SB),NOSPLIT,$0 ADD $16, RSP MOVD R0, 56(R2) // save r1 MOVD R1, 64(R2) // save r2 - CMPW $-1, R0 - BNE ok - SUB $16, RSP // push structure pointer - MOVD R2, 8(RSP) - BL libc_error(SB) - MOVW (R0), R0 - MOVD 8(RSP), R2 // pop structure pointer - ADD $16, RSP - MOVD R0, 72(R2) // save err -ok: - RET - -// syscall6X calls a function in libc on behalf of the syscall package. -// syscall6X takes a pointer to a struct like: -// struct { -// fn uintptr -// a1 uintptr -// a2 uintptr -// a3 uintptr -// a4 uintptr -// a5 uintptr -// a6 uintptr -// r1 uintptr -// r2 uintptr -// err uintptr -// } -// syscall6X must be called on the g0 stack with the -// C calling convention (use libcCall). -TEXT runtime·syscall6X(SB),NOSPLIT,$0 - SUB $16, RSP // push structure pointer - MOVD R0, (RSP) - - MOVD 0(R0), R12 // fn - MOVD 16(R0), R1 // a2 - MOVD 24(R0), R2 // a3 - MOVD 32(R0), R3 // a4 - MOVD 40(R0), R4 // a5 - MOVD 48(R0), R5 // a6 - MOVD 8(R0), R0 // a1 - BL (R12) - - MOVD (RSP), R2 // pop structure pointer - ADD $16, RSP - MOVD R0, 56(R2) // save r1 - MOVD R1, 64(R2) // save r2 - CMP $-1, R0 - BNE ok - SUB $16, RSP // push structure pointer - MOVD R2, (RSP) - BL libc_error(SB) - MOVW (R0), R0 - MOVD (RSP), R2 // pop structure pointer - ADD $16, RSP - MOVD R0, 72(R2) // save err -ok: RET -// syscall9 calls a function in libc on behalf of the syscall package. -// syscall9 takes a pointer to a struct like: +// syscall9_trampoline calls a function in libc on behalf of the syscall package. +// syscall9_trampoline takes a pointer to a struct like: // struct { // fn uintptr // a1 uintptr @@ -707,11 +573,10 @@ ok: // a9 uintptr // r1 uintptr // r2 uintptr -// err uintptr // } -// syscall9 must be called on the g0 stack with the +// syscall9_trampoline must be called on the g0 stack with the // C calling convention (use libcCall). -TEXT runtime·syscall9(SB),NOSPLIT,$0 +TEXT runtime·syscall9_trampoline(SB),NOSPLIT,$0 SUB $16, RSP // push structure pointer MOVD R0, 8(RSP) @@ -733,16 +598,11 @@ TEXT runtime·syscall9(SB),NOSPLIT,$0 ADD $16, RSP MOVD R0, 80(R2) // save r1 MOVD R1, 88(R2) // save r2 - CMPW $-1, R0 - BNE ok - SUB $16, RSP // push structure pointer - MOVD R2, 8(RSP) + RET + +TEXT runtime·libc_error_trampoline(SB),NOSPLIT,$0 BL libc_error(SB) MOVW (R0), R0 - MOVD 8(RSP), R2 // pop structure pointer - ADD $16, RSP - MOVD R0, 96(R2) // save err -ok: RET // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors, -- 2.52.0