diff --git a/src/syscall/exec_libc2.go b/src/syscall/exec_libc2.go index 3de2c94c99b1c5..50f8d42046bc27 100644 --- a/src/syscall/exec_libc2.go +++ b/src/syscall/exec_libc2.go @@ -48,8 +48,9 @@ func runtime_AfterForkInChild() // they might have been locked at the time of the fork. This means // no rescheduling, no malloc calls, and no new stack segments. // For the same reason compiler does not race instrument it. -// The calls to rawSyscall are okay because they are assembly -// functions that do not grow the stack. +// The calls to rawSyscall are okay because they are nosplit +// functions that do not grow the stack and are not race +// instrumented (go:norace). // //go:norace func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err1 Errno) { diff --git a/src/syscall/syscall_darwin.go b/src/syscall/syscall_darwin.go index ca76cc2962b098..b65f69f978d81b 100644 --- a/src/syscall/syscall_darwin.go +++ b/src/syscall/syscall_darwin.go @@ -326,6 +326,7 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { // errno return e if int32(r) is -1, else it returns 0. // //go:nosplit +//go:norace func errno(r uintptr, e Errno) Errno { if int32(r) == -1 { return e @@ -336,6 +337,7 @@ func errno(r uintptr, e Errno) Errno { // errnoX return e if r is -1, else it returns 0. // //go:nosplit +//go:norace func errnoX(r uintptr, e Errno) Errno { if r == ^uintptr(0) { return e @@ -346,6 +348,7 @@ func errnoX(r uintptr, e Errno) Errno { // errnoPtr return e if r is 0, else it returns 0. // //go:nosplit +//go:norace func errnoPtr(r uintptr, e Errno) Errno { if r == 0 { return e @@ -358,6 +361,22 @@ func errnoPtr(r uintptr, e Errno) Errno { // golang.org/x/sys linknames the following syscalls. // Do not remove or change the type signature. +// N.B. For the Syscall functions below: +// +// //go:uintptrkeepalive because the uintptr argument may be converted pointers +// that need to be kept alive in the caller. +// +// //go:nosplit because stack copying does not account for uintptrkeepalive, so +// the stack must not grow. Stack copying cannot blindly assume that all +// uintptr arguments are pointers, because some values may look like pointers, +// but not really be pointers, and adjusting their value would break the call. +// +// //go:norace, on RawSyscall, to avoid race instrumentation if RawSyscall is +// called after fork, or from a signal handler. +// +// //go:linkname to ensure ABI wrappers are generated for external callers +// (notably x/sys/unix assembly). + //go:linkname syscall //go:nosplit //go:uintptrkeepalive @@ -409,6 +428,7 @@ func syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, e //go:linkname rawSyscall //go:nosplit +//go:norace //go:uintptrkeepalive func rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { r1, r2, err = rawsyscalln(fn, a1, a2, a3) @@ -417,6 +437,7 @@ func rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { //go:linkname rawSyscall6 //go:nosplit +//go:norace //go:uintptrkeepalive func rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { r1, r2, err = rawsyscalln(fn, a1, a2, a3, a4, a5, a6) @@ -425,6 +446,7 @@ func rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) //go:linkname rawSyscall9 //go:nosplit +//go:norace //go:uintptrkeepalive func rawSyscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) { r1, r2, err = rawsyscalln(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9)