syscall: add //go:norace to rawSyscall on darwin

On darwin, rawSyscall, rawSyscall6, and rawSyscall9 are Go
functions (not assembly as on Linux) that get race-detector
instrumentation. When forkAndExecInChild calls rawSyscall in
the forked child process, the TSan ThreadState pointer is
invalid, causing SIGSEGV in TraceSwitchPartImpl.

Add //go:norace to these functions so the race detector does
not instrument them. Also update the stale comment in
exec_libc2.go that referred to rawSyscall as assembly.

Fixes #79804

Change-Id: Ia1d5ffea9bc9729ce5392daaf00b45ab1f779d71
GitHub-Last-Rev: 21d574438c6ff11cd4939d463955152315827680
GitHub-Pull-Request: golang/go#79805
Reviewed-on: https://go-review.googlesource.com/c/go/+/786620
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/src/syscall/exec_libc2.go b/src/syscall/exec_libc2.go
index 3de2c94..50f8d42 100644
--- a/src/syscall/exec_libc2.go
+++ b/src/syscall/exec_libc2.go
@@ -48,8 +48,9 @@
 // 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 ca76cc2..b65f69f 100644
--- a/src/syscall/syscall_darwin.go
+++ b/src/syscall/syscall_darwin.go
@@ -326,6 +326,7 @@
 // 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 @@
 // 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 @@
 // 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 @@
 // 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 @@
 
 //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 @@
 
 //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 @@
 
 //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)