aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2026-02-25 12:26:54 -0500
committerCherry Mui <cherryyz@google.com>2026-04-02 13:12:00 -0700
commitcaa169ee4804ba0dbe1c430e8e9a4d2940f5145b (patch)
tree24486172c5b6a6ac45e864233d692bf2f26dae2e
parent3a0f18376fb974b6f5d30613f1a20d826a2564aa (diff)
downloadgo-caa169ee4804ba0dbe1c430e8e9a4d2940f5145b.tar.xz
all: add export linknames for assembly symbols accessed from other package
For Go symbols accessed from other package via linkname or assembly, we have an export linkname from the definition side. We currently don't always have the linkname directive for assembly functions, for which external accesses are allowed. We may want to tighten up the restriction. So add export linknames for the ones that are needed. Change-Id: If664634c81580edd49086d916024f23f86871092 Reviewed-on: https://go-review.googlesource.com/c/go/+/749981 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com>
-rw-r--r--src/runtime/alg.go4
-rw-r--r--src/runtime/stubs.go9
-rw-r--r--src/runtime/stubs_amd64.go4
-rw-r--r--src/runtime/stubs_arm.go6
-rw-r--r--src/runtime/stubs_arm64.go8
-rw-r--r--src/runtime/stubs_loong64.go8
-rw-r--r--src/runtime/stubs_mips64x.go4
-rw-r--r--src/runtime/stubs_mipsx.go6
-rw-r--r--src/runtime/stubs_ppc64x.go10
-rw-r--r--src/runtime/stubs_riscv64.go8
-rw-r--r--src/runtime/stubs_s390x.go8
-rw-r--r--src/sync/atomic/doc.go3
-rw-r--r--src/syscall/linkname_bsd.go8
-rw-r--r--src/syscall/syscall_aix.go5
-rw-r--r--src/syscall/syscall_linux_386.go9
-rw-r--r--src/syscall/syscall_linux_amd64.go5
-rw-r--r--src/syscall/syscall_linux_arm.go4
-rw-r--r--src/syscall/syscall_linux_mipsx.go4
-rw-r--r--src/syscall/syscall_plan9.go11
-rw-r--r--src/syscall/syscall_solaris.go8
20 files changed, 130 insertions, 2 deletions
diff --git a/src/runtime/alg.go b/src/runtime/alg.go
index 9b726b2180..e99acf8242 100644
--- a/src/runtime/alg.go
+++ b/src/runtime/alg.go
@@ -80,8 +80,12 @@ var useAeshash bool
//go:linkname memhash
func memhash(p unsafe.Pointer, h, s uintptr) uintptr
+// Accessed in internal/runtime/maps.
+//
+//go:linknamestd memhash32
func memhash32(p unsafe.Pointer, h uintptr) uintptr
+//go:linknamestd memhash64
func memhash64(p unsafe.Pointer, h uintptr) uintptr
// strhash should be an internal detail,
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
index 31e35c74f5..d4c79d288c 100644
--- a/src/runtime/stubs.go
+++ b/src/runtime/stubs.go
@@ -203,12 +203,14 @@ func noEscapePtr[T any](p *T) *T {
// Not all cgocallback frames are actually cgocallback,
// so not all have these arguments. Mark them uintptr so that the GC
// does not misinterpret memory when the arguments are not present.
-// cgocallback is not called from Go, only from crosscall2.
+// cgocallback is not called from Go, only from crosscall2 in runtime/cgo.
// This in turn calls cgocallbackg, which is where we'll find
// pointer-declared arguments.
//
// When fn is nil (frame is saved g), call dropm instead,
// this is used when the C thread is exiting.
+//
+//go:linknamestd cgocallback
func cgocallback(fn, frame, ctxt uintptr)
func gogo(buf *gobuf)
@@ -260,6 +262,7 @@ func breakpoint()
// only in a very limited callee of reflectcall, the stackArgs are copied, and
// regArgs is only used in the reflectcall frame.
//
+//go:linknamestd reflectcall
//go:noescape
func reflectcall(stackArgsType *_type, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
@@ -409,6 +412,10 @@ func bool2int(x bool) int {
// (e.g., an INT3 on x86). A crash in abort is recognized by the
// signal handler, which will attempt to tear down the runtime
// immediately.
+//
+// Also called from runtime test.
+//
+//go:linkname abort
func abort()
// Called from compiled code; declared for vet; do NOT call from Go.
diff --git a/src/runtime/stubs_amd64.go b/src/runtime/stubs_amd64.go
index 6d0b113740..9517d03283 100644
--- a/src/runtime/stubs_amd64.go
+++ b/src/runtime/stubs_amd64.go
@@ -48,7 +48,11 @@ func asmcgocall_landingpad()
//
// Spills/loads arguments in registers to/from an internal/abi.RegArgs
// respectively. Does not follow the Go ABI.
+//
+//go:linknamestd spillArgs
func spillArgs()
+
+//go:linknamestd unspillArgs
func unspillArgs()
// getfp returns the frame pointer register of its caller or 0 if not implemented.
diff --git a/src/runtime/stubs_arm.go b/src/runtime/stubs_arm.go
index 49bfd9ef04..786d90174b 100644
--- a/src/runtime/stubs_arm.go
+++ b/src/runtime/stubs_arm.go
@@ -14,12 +14,16 @@ func _mod()
func _modu()
// Called from assembly only; declared for go vet.
-func usplitR0()
+//
+// load_g is also called from runtime/cgo.
+//
+//go:linknamestd load_g
func load_g()
func save_g()
func emptyfunc()
func _initcgo()
func read_tls_fallback()
+func usplitR0()
//go:noescape
func asmcgocall_no_g(fn, arg unsafe.Pointer)
diff --git a/src/runtime/stubs_arm64.go b/src/runtime/stubs_arm64.go
index df04e64291..f6cba6c2fa 100644
--- a/src/runtime/stubs_arm64.go
+++ b/src/runtime/stubs_arm64.go
@@ -7,6 +7,10 @@ package runtime
import "unsafe"
// Called from assembly only; declared for go vet.
+//
+// load_g is also called from runtime/cgo.
+//
+//go:linknamestd load_g
func load_g()
func save_g()
@@ -19,7 +23,11 @@ func emptyfunc()
//
// Spills/loads arguments in registers to/from an internal/abi.RegArgs
// respectively. Does not follow the Go ABI.
+//
+//go:linknamestd spillArgs
func spillArgs()
+
+//go:linknamestd unspillArgs
func unspillArgs()
// getfp returns the frame pointer register of its caller or 0 if not implemented.
diff --git a/src/runtime/stubs_loong64.go b/src/runtime/stubs_loong64.go
index dfcfff2d16..9b73e8d963 100644
--- a/src/runtime/stubs_loong64.go
+++ b/src/runtime/stubs_loong64.go
@@ -9,6 +9,10 @@ package runtime
import "unsafe"
// Called from assembly only; declared for go vet.
+//
+// load_g is also called from runtime/cgo.
+//
+//go:linknamestd load_g
func load_g()
func save_g()
@@ -19,7 +23,11 @@ func asmcgocall_no_g(fn, arg unsafe.Pointer)
//
// Spills/loads arguments in registers to/from an internal/abi.RegArgs
// respectively. Does not follow the Go ABI.
+//
+//go:linknamestd spillArgs
func spillArgs()
+
+//go:linknamestd unspillArgs
func unspillArgs()
// getfp returns the frame pointer register of its caller or 0 if not implemented.
diff --git a/src/runtime/stubs_mips64x.go b/src/runtime/stubs_mips64x.go
index fb5220b0de..f73fbefad7 100644
--- a/src/runtime/stubs_mips64x.go
+++ b/src/runtime/stubs_mips64x.go
@@ -9,6 +9,10 @@ package runtime
import "unsafe"
// Called from assembly only; declared for go vet.
+//
+// load_g is also called from runtime/cgo.
+//
+//go:linknamestd load_g
func load_g()
func save_g()
diff --git a/src/runtime/stubs_mipsx.go b/src/runtime/stubs_mipsx.go
index 175d4f9741..242a7e4554 100644
--- a/src/runtime/stubs_mipsx.go
+++ b/src/runtime/stubs_mipsx.go
@@ -6,7 +6,13 @@
package runtime
+import _ "unsafe" // for linkname
+
// Called from assembly only; declared for go vet.
+//
+// load_g is also called from runtime/cgo.
+//
+//go:linknamestd load_g
func load_g()
func save_g()
diff --git a/src/runtime/stubs_ppc64x.go b/src/runtime/stubs_ppc64x.go
index dbc82c8453..7a0d8cec36 100644
--- a/src/runtime/stubs_ppc64x.go
+++ b/src/runtime/stubs_ppc64x.go
@@ -9,6 +9,10 @@ package runtime
import "unsafe"
// Called from assembly only; declared for go vet.
+//
+// load_g is also called from runtime/cgo.
+//
+//go:linknamestd load_g
func load_g()
func save_g()
func reginit()
@@ -16,9 +20,15 @@ func reginit()
//go:noescape
func asmcgocall_no_g(fn, arg unsafe.Pointer)
+// Used by reflectcall and the reflect package.
+//
// Spills/loads arguments in registers to/from an internal/abi.RegArgs
// respectively. Does not follow the Go ABI.
+//
+//go:linknamestd spillArgs
func spillArgs()
+
+//go:linknamestd unspillArgs
func unspillArgs()
// getfp returns the frame pointer register of its caller or 0 if not implemented.
diff --git a/src/runtime/stubs_riscv64.go b/src/runtime/stubs_riscv64.go
index 2306ba878b..302a0f41e8 100644
--- a/src/runtime/stubs_riscv64.go
+++ b/src/runtime/stubs_riscv64.go
@@ -7,6 +7,10 @@ package runtime
import "unsafe"
// Called from assembly only; declared for go vet.
+//
+// load_g is also called from runtime/cgo.
+//
+//go:linknamestd load_g
func load_g()
func save_g()
@@ -17,7 +21,11 @@ func asmcgocall_no_g(fn, arg unsafe.Pointer)
//
// Spills/loads arguments in registers to/from an internal/abi.RegArgs
// respectively. Does not follow the Go ABI.
+//
+//go:linknamestd spillArgs
func spillArgs()
+
+//go:linknamestd unspillArgs
func unspillArgs()
// getfp returns the frame pointer register of its caller or 0 if not implemented.
diff --git a/src/runtime/stubs_s390x.go b/src/runtime/stubs_s390x.go
index c872799a56..ee62dcf3b5 100644
--- a/src/runtime/stubs_s390x.go
+++ b/src/runtime/stubs_s390x.go
@@ -7,6 +7,10 @@ package runtime
import "unsafe"
// Called from assembly only; declared for go vet.
+//
+// load_g is also called from runtime/cgo.
+//
+//go:linknamestd load_g
func load_g()
func save_g()
@@ -17,7 +21,11 @@ func asmcgocall_no_g(fn, arg unsafe.Pointer)
//
// Spills/loads arguments in registers to/from an internal/abi.RegArgs
// respectively. Does not follow the Go ABI.
+//
+//go:linknamestd spillArgs
func spillArgs()
+
+//go:linknamestd unspillArgs
func unspillArgs()
// getfp returns the frame pointer register of its caller or 0 if not implemented.
diff --git a/src/sync/atomic/doc.go b/src/sync/atomic/doc.go
index 4e93404757..4382a13ed6 100644
--- a/src/sync/atomic/doc.go
+++ b/src/sync/atomic/doc.go
@@ -80,6 +80,7 @@ func SwapUint32(addr *uint32, new uint32) (old uint32)
// Consider using the more ergonomic and less error-prone [Uintptr.Swap] instead.
//
//go:noescape
+//go:linknamestd SwapUintptr
func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
// SwapPointer atomically stores new into *addr and returns the previous *addr value.
@@ -102,6 +103,7 @@ func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
// Consider using the more ergonomic and less error-prone [Uintptr.CompareAndSwap] instead.
//
//go:noescape
+//go:linknamestd CompareAndSwapUintptr
func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
@@ -208,6 +210,7 @@ func StoreUint32(addr *uint32, val uint32)
// Consider using the more ergonomic and less error-prone [Uintptr.Store] instead.
//
//go:noescape
+//go:linknamestd StoreUintptr
func StoreUintptr(addr *uintptr, val uintptr)
// StorePointer atomically stores val into *addr.
diff --git a/src/syscall/linkname_bsd.go b/src/syscall/linkname_bsd.go
index c3c6a58420..431d850422 100644
--- a/src/syscall/linkname_bsd.go
+++ b/src/syscall/linkname_bsd.go
@@ -15,3 +15,11 @@ import _ "unsafe"
// Do not remove or change the type signature.
//
//go:linkname sysctl
+
+// golang.org/x/sys accesses these in assembly.
+//
+//go:linkname Syscall
+//go:linkname Syscall6
+//go:linkname Syscall9
+//go:linkname RawSyscall
+//go:linkname RawSyscall6
diff --git a/src/syscall/syscall_aix.go b/src/syscall/syscall_aix.go
index 36dfd90678..1add20bf12 100644
--- a/src/syscall/syscall_aix.go
+++ b/src/syscall/syscall_aix.go
@@ -21,7 +21,12 @@ func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
// Implemented in runtime/syscall_aix.go.
+// Accessed in assembly in x/sys/unix and x/sys/cpu.
+//
+//go:linkname rawSyscall6
func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+
+//go:linkname syscall6
func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
// Constant expected by package but not supported
diff --git a/src/syscall/syscall_linux_386.go b/src/syscall/syscall_linux_386.go
index a90565a001..ba916dfcb8 100644
--- a/src/syscall/syscall_linux_386.go
+++ b/src/syscall/syscall_linux_386.go
@@ -74,6 +74,10 @@ func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int6
// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
+//
+// Accessed via assembly in x/sys/unix.
+//
+//go:linkname seek
func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
@@ -121,7 +125,12 @@ const (
_SENDMMSG = 20
)
+// socketcall and rawsocketcall are accessed via assembly in x/sys/unix.
+//
+//go:linkname socketcall
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
+
+//go:linkname rawsocketcall
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
diff --git a/src/syscall/syscall_linux_amd64.go b/src/syscall/syscall_linux_amd64.go
index 725ebdba22..1a8b70b1c1 100644
--- a/src/syscall/syscall_linux_amd64.go
+++ b/src/syscall/syscall_linux_amd64.go
@@ -4,6 +4,8 @@
package syscall
+import _ "unsafe" // for linkname
+
const (
_SYS_setgroups = SYS_SETGROUPS
_SYS_clone3 = 435
@@ -71,7 +73,10 @@ func Lstat(path string, stat *Stat_t) (err error) {
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
+// Accessed via assembly in x/sys/unix.
+//
//go:noescape
+//go:linkname gettimeofday
func gettimeofday(tv *Timeval) (err Errno)
func Gettimeofday(tv *Timeval) (err error) {
diff --git a/src/syscall/syscall_linux_arm.go b/src/syscall/syscall_linux_arm.go
index 2019b15169..725de63d41 100644
--- a/src/syscall/syscall_linux_arm.go
+++ b/src/syscall/syscall_linux_arm.go
@@ -23,6 +23,10 @@ func setTimeval(sec, usec int64) Timeval {
// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
+//
+// Accessed via assembly in x/sys/unix.
+//
+//go:linkname seek
func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
diff --git a/src/syscall/syscall_linux_mipsx.go b/src/syscall/syscall_linux_mipsx.go
index aa08792606..7cfc8aff26 100644
--- a/src/syscall/syscall_linux_mipsx.go
+++ b/src/syscall/syscall_linux_mipsx.go
@@ -15,6 +15,10 @@ const (
_SYS_fchmodat2 = 4452
)
+// Syscall9 is accessed via assembly in x/sys/unix.
+//
+//go:linkname Syscall9
+
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
//sys Dup2(oldfd int, newfd int) (err error)
diff --git a/src/syscall/syscall_plan9.go b/src/syscall/syscall_plan9.go
index dffab546d5..2a6229b273 100644
--- a/src/syscall/syscall_plan9.go
+++ b/src/syscall/syscall_plan9.go
@@ -116,6 +116,13 @@ var (
// creation of IPv6 sockets to return [EAFNOSUPPORT].
var SocketDisableIPv6 bool
+// x/sys/plan9 accesses these in assembly.
+//
+//go:linkname Syscall
+//go:linkname Syscall6
+//go:linkname RawSyscall
+//go:linkname RawSyscall6
+
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
@@ -227,6 +234,10 @@ func Pipe(p []int) (err error) {
// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
+//
+// Accessed via assembly from x/sys/plan9.
+//
+//go:linkname seek
func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
diff --git a/src/syscall/syscall_solaris.go b/src/syscall/syscall_solaris.go
index 9ae721b573..e2d407b9de 100644
--- a/src/syscall/syscall_solaris.go
+++ b/src/syscall/syscall_solaris.go
@@ -22,7 +22,15 @@ func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
// Implemented in asm_solaris_amd64.s.
+//
+// Accessed via assembly in x/sys/unix.
+//
+//go:linkname rawSysvicall6
func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+
+// Accessed via assembly in x/sys/unix and x/net/lif.
+//
+//go:linkname sysvicall6
func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
type SockaddrDatalink struct {