There is a lot of duplication in how arm64 OSes handle entry points.
Do as amd64, have all the logic in a common function.
Cq-Include-Trybots: luci.golang.try:gotip-darwin-arm64-longtest,gotip-windows-arm64
Change-Id: I370c25c3c4b107b525aba14e9dcac34a02d9872e
Reviewed-on: https://go-review.googlesource.com/c/go/+/706175
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Quim Muntal <quimmuntal@gmail.com>
#include "tls_arm64.h"
#include "funcdata.h"
#include "textflag.h"
+#include "cgo/abi_arm64.h"
+
+// _rt0_arm64 is common startup code for most arm64 systems when using
+// internal linking. This is the entry point for the program from the
+// kernel for an ordinary -buildmode=exe program. The stack holds the
+// number of arguments and the C-style argv.
+TEXT _rt0_arm64(SB),NOSPLIT,$0
+ MOVD 0(RSP), R0 // argc
+ ADD $8, RSP, R1 // argv
+ JMP runtime·rt0_go(SB)
+
+// main is common startup code for most amd64 systems when using
+// external linking. The C startup code will call the symbol "main"
+// passing argc and argv in the usual C ABI registers R0 and R1.
+TEXT main(SB),NOSPLIT,$0
+ JMP runtime·rt0_go(SB)
+
+// _rt0_arm64_lib is common startup code for most arm64 systems when
+// using -buildmode=c-archive or -buildmode=c-shared. The linker will
+// arrange to invoke this function as a global constructor (for
+// c-archive) or when the shared library is loaded (for c-shared).
+// We expect argc and argv to be passed in the usual C ABI registers
+// R0 and R1.
+TEXT _rt0_arm64_lib(SB),NOSPLIT,$184
+ // Preserve callee-save registers.
+ SAVE_R19_TO_R28(24)
+ SAVE_F8_TO_F15(104)
+
+ // Initialize g as null in case of using g later e.g. sigaction in cgo_sigaction.go
+ MOVD ZR, g
+
+ MOVD R0, _rt0_arm64_lib_argc<>(SB)
+ MOVD R1, _rt0_arm64_lib_argv<>(SB)
+
+ // Synchronous initialization.
+ MOVD $runtime·libpreinit(SB), R4
+ BL (R4)
+
+ // Create a new thread to do the runtime initialization and return.
+ MOVD _cgo_sys_thread_create(SB), R4
+ CBZ R4, nocgo
+ MOVD $_rt0_arm64_lib_go(SB), R0
+ MOVD $0, R1
+ SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
+ BL (R4)
+ ADD $16, RSP
+ B restore
+
+nocgo:
+ MOVD $0x800000, R0 // stacksize = 8192KB
+ MOVD $_rt0_arm64_lib_go(SB), R1
+ MOVD R0, 8(RSP)
+ MOVD R1, 16(RSP)
+ MOVD $runtime·newosproc0(SB),R4
+ BL (R4)
+
+restore:
+ // Restore callee-save registers.
+ RESTORE_R19_TO_R28(24)
+ RESTORE_F8_TO_F15(104)
+ RET
+
+TEXT _rt0_arm64_lib_go(SB),NOSPLIT,$0
+ MOVD _rt0_arm64_lib_argc<>(SB), R0
+ MOVD _rt0_arm64_lib_argv<>(SB), R1
+ MOVD $runtime·rt0_go(SB),R4
+ B (R4)
+
+DATA _rt0_arm64_lib_argc<>(SB)/8, $0
+GLOBL _rt0_arm64_lib_argc<>(SB),NOPTR, $8
+DATA _rt0_arm64_lib_argv<>(SB)/8, $0
+GLOBL _rt0_arm64_lib_argv<>(SB),NOPTR, $8
#ifdef GOARM64_LSE
DATA no_lse_msg<>+0x00(SB)/64, $"This program can only run on ARM64 processors with LSE support.\n"
//
//go:nowritebarrierrec
//go:nosplit
-func newosproc0(mp *m, stk unsafe.Pointer) {
- // TODO: this is completely broken. The args passed to newosproc0 (in asm_amd64.s)
- // are stacksize and function, not *m and stack.
- // Check os_linux.go for an implementation that might actually work.
+func newosproc0(stacksize uintptr, fn uintptr) {
throw("bad newosproc0")
}
+//go:nosplit
+//go:nowritebarrierrec
+func libpreinit() {}
+
func exitThread(wait *atomic.Uint32) {
// We should never reach exitThread on Windows because we let
// the OS clean up threads.
#include "textflag.h"
-TEXT _rt0_arm64_android(SB),NOSPLIT|NOFRAME,$0
- MOVD $_rt0_arm64_linux(SB), R4
- B (R4)
+TEXT _rt0_arm64_android(SB),NOSPLIT,$0
+ JMP _rt0_arm64(SB)
// When building with -buildmode=c-shared, this symbol is called when the shared
// library is loaded.
-TEXT _rt0_arm64_android_lib(SB),NOSPLIT|NOFRAME,$0
+TEXT _rt0_arm64_android_lib(SB),NOSPLIT,$0
MOVW $1, R0 // argc
MOVD $_rt0_arm64_android_argv(SB), R1 // **argv
- MOVD $_rt0_arm64_linux_lib(SB), R4
- B (R4)
+ JMP _rt0_arm64_lib(SB)
DATA _rt0_arm64_android_argv+0x00(SB)/8,$_rt0_arm64_android_argv0(SB)
DATA _rt0_arm64_android_argv+0x08(SB)/8,$0 // end argv
// license that can be found in the LICENSE file.
#include "textflag.h"
-#include "cgo/abi_arm64.h"
-TEXT _rt0_arm64_darwin(SB),NOSPLIT|NOFRAME,$0
- MOVD $runtime·rt0_go(SB), R2
- BL (R2)
-exit:
- MOVD $0, R0
- MOVD $1, R16 // sys_exit
- SVC $0x80
- B exit
+TEXT _rt0_arm64_darwin(SB),NOSPLIT,$0
+ // Darwin puts argc and argv in R0 and R1,
+ // so there is no need to go through _rt0_arm64.
+ JMP runtime·rt0_go(SB)
// When linking with -buildmode=c-archive or -buildmode=c-shared,
// this symbol is called from a global initialization function.
-//
-// Note that all currently shipping darwin/arm64 platforms require
-// cgo and do not support c-shared.
-TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$152
- // Preserve callee-save registers.
- SAVE_R19_TO_R28(8)
- SAVE_F8_TO_F15(88)
-
- MOVD R0, _rt0_arm64_darwin_lib_argc<>(SB)
- MOVD R1, _rt0_arm64_darwin_lib_argv<>(SB)
-
- MOVD $0, g // initialize g to nil
-
- // Synchronous initialization.
- MOVD $runtime·libpreinit(SB), R4
- BL (R4)
-
- // Create a new thread to do the runtime initialization and return.
- MOVD _cgo_sys_thread_create(SB), R4
- MOVD $_rt0_arm64_darwin_lib_go(SB), R0
- MOVD $0, R1
- SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
- BL (R4)
- ADD $16, RSP
-
- // Restore callee-save registers.
- RESTORE_R19_TO_R28(8)
- RESTORE_F8_TO_F15(88)
-
- RET
-
-TEXT _rt0_arm64_darwin_lib_go(SB),NOSPLIT,$0
- MOVD _rt0_arm64_darwin_lib_argc<>(SB), R0
- MOVD _rt0_arm64_darwin_lib_argv<>(SB), R1
- MOVD $runtime·rt0_go(SB), R4
- B (R4)
-
-DATA _rt0_arm64_darwin_lib_argc<>(SB)/8, $0
-GLOBL _rt0_arm64_darwin_lib_argc<>(SB),NOPTR, $8
-DATA _rt0_arm64_darwin_lib_argv<>(SB)/8, $0
-GLOBL _rt0_arm64_darwin_lib_argv<>(SB),NOPTR, $8
-
-// external linking entry point.
-TEXT main(SB),NOSPLIT|NOFRAME,$0
- JMP _rt0_arm64_darwin(SB)
+TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$0
+ JMP _rt0_arm64_lib(SB)
// license that can be found in the LICENSE file.
#include "textflag.h"
-#include "cgo/abi_arm64.h"
// On FreeBSD argc/argv are passed in R0, not RSP
-TEXT _rt0_arm64_freebsd(SB),NOSPLIT|NOFRAME,$0
- ADD $8, R0, R1 // argv
- MOVD 0(R0), R0 // argc
- BL main(SB)
+TEXT _rt0_arm64_freebsd(SB),NOSPLIT,$0
+ JMP _rt0_arm64(SB)
// When building with -buildmode=c-shared, this symbol is called when the shared
// library is loaded.
-TEXT _rt0_arm64_freebsd_lib(SB),NOSPLIT,$184
- // Preserve callee-save registers.
- SAVE_R19_TO_R28(24)
- SAVE_F8_TO_F15(104)
-
- // Initialize g as null in case of using g later e.g. sigaction in cgo_sigaction.go
- MOVD ZR, g
-
- MOVD R0, _rt0_arm64_freebsd_lib_argc<>(SB)
- MOVD R1, _rt0_arm64_freebsd_lib_argv<>(SB)
-
- // Synchronous initialization.
- MOVD $runtime·libpreinit(SB), R4
- BL (R4)
-
- // Create a new thread to do the runtime initialization and return.
- MOVD _cgo_sys_thread_create(SB), R4
- CBZ R4, nocgo
- MOVD $_rt0_arm64_freebsd_lib_go(SB), R0
- MOVD $0, R1
- SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
- BL (R4)
- ADD $16, RSP
- B restore
-
-nocgo:
- MOVD $0x800000, R0 // stacksize = 8192KB
- MOVD $_rt0_arm64_freebsd_lib_go(SB), R1
- MOVD R0, 8(RSP)
- MOVD R1, 16(RSP)
- MOVD $runtime·newosproc0(SB),R4
- BL (R4)
-
-restore:
- // Restore callee-save registers.
- RESTORE_R19_TO_R28(24)
- RESTORE_F8_TO_F15(104)
- RET
-
-TEXT _rt0_arm64_freebsd_lib_go(SB),NOSPLIT,$0
- MOVD _rt0_arm64_freebsd_lib_argc<>(SB), R0
- MOVD _rt0_arm64_freebsd_lib_argv<>(SB), R1
- MOVD $runtime·rt0_go(SB),R4
- B (R4)
-
-DATA _rt0_arm64_freebsd_lib_argc<>(SB)/8, $0
-GLOBL _rt0_arm64_freebsd_lib_argc<>(SB),NOPTR, $8
-DATA _rt0_arm64_freebsd_lib_argv<>(SB)/8, $0
-GLOBL _rt0_arm64_freebsd_lib_argv<>(SB),NOPTR, $8
-
-
-TEXT main(SB),NOSPLIT|NOFRAME,$0
- MOVD $runtime·rt0_go(SB), R2
- BL (R2)
-exit:
- MOVD $0, R0
- MOVD $1, R8 // SYS_exit
- SVC
- B exit
+TEXT _rt0_arm64_freebsd_lib(SB),NOSPLIT,$0
+ JMP _rt0_arm64_lib(SB)
// library entry point.
TEXT _rt0_arm64_ios_lib(SB),NOSPLIT|NOFRAME,$0
- JMP _rt0_arm64_darwin_lib(SB)
+ JMP _rt0_arm64_lib(SB)
// license that can be found in the LICENSE file.
#include "textflag.h"
-#include "cgo/abi_arm64.h"
-TEXT _rt0_arm64_linux(SB),NOSPLIT|NOFRAME,$0
- MOVD 0(RSP), R0 // argc
- ADD $8, RSP, R1 // argv
- BL main(SB)
+TEXT _rt0_arm64_linux(SB),NOSPLIT,$0
+ JMP _rt0_arm64(SB)
// When building with -buildmode=c-shared, this symbol is called when the shared
// library is loaded.
-TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$184
- // Preserve callee-save registers.
- SAVE_R19_TO_R28(24)
- SAVE_F8_TO_F15(104)
-
- // Initialize g as null in case of using g later e.g. sigaction in cgo_sigaction.go
- MOVD ZR, g
-
- MOVD R0, _rt0_arm64_linux_lib_argc<>(SB)
- MOVD R1, _rt0_arm64_linux_lib_argv<>(SB)
-
- // Synchronous initialization.
- MOVD $runtime·libpreinit(SB), R4
- BL (R4)
-
- // Create a new thread to do the runtime initialization and return.
- MOVD _cgo_sys_thread_create(SB), R4
- CBZ R4, nocgo
- MOVD $_rt0_arm64_linux_lib_go(SB), R0
- MOVD $0, R1
- SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
- BL (R4)
- ADD $16, RSP
- B restore
-
-nocgo:
- MOVD $0x800000, R0 // stacksize = 8192KB
- MOVD $_rt0_arm64_linux_lib_go(SB), R1
- MOVD R0, 8(RSP)
- MOVD R1, 16(RSP)
- MOVD $runtime·newosproc0(SB),R4
- BL (R4)
-
-restore:
- // Restore callee-save registers.
- RESTORE_R19_TO_R28(24)
- RESTORE_F8_TO_F15(104)
- RET
-
-TEXT _rt0_arm64_linux_lib_go(SB),NOSPLIT,$0
- MOVD _rt0_arm64_linux_lib_argc<>(SB), R0
- MOVD _rt0_arm64_linux_lib_argv<>(SB), R1
- MOVD $runtime·rt0_go(SB),R4
- B (R4)
-
-DATA _rt0_arm64_linux_lib_argc<>(SB)/8, $0
-GLOBL _rt0_arm64_linux_lib_argc<>(SB),NOPTR, $8
-DATA _rt0_arm64_linux_lib_argv<>(SB)/8, $0
-GLOBL _rt0_arm64_linux_lib_argv<>(SB),NOPTR, $8
-
-
-TEXT main(SB),NOSPLIT|NOFRAME,$0
- MOVD $runtime·rt0_go(SB), R2
- BL (R2)
-exit:
- MOVD $0, R0
- MOVD $94, R8 // sys_exit
- SVC
- B exit
+TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$0
+ JMP _rt0_arm64_lib(SB)
// license that can be found in the LICENSE file.
#include "textflag.h"
-#include "cgo/abi_arm64.h"
-TEXT _rt0_arm64_netbsd(SB),NOSPLIT|NOFRAME,$0
+TEXT _rt0_arm64_netbsd(SB),NOSPLIT,$0
MOVD 0(RSP), R0 // argc
ADD $8, RSP, R1 // argv
BL main(SB)
// When building with -buildmode=c-shared, this symbol is called when the shared
// library is loaded.
-TEXT _rt0_arm64_netbsd_lib(SB),NOSPLIT,$184
- // Preserve callee-save registers.
- SAVE_R19_TO_R28(24)
- SAVE_F8_TO_F15(104)
-
- // Initialize g as null in case of using g later e.g. sigaction in cgo_sigaction.go
- MOVD ZR, g
-
- MOVD R0, _rt0_arm64_netbsd_lib_argc<>(SB)
- MOVD R1, _rt0_arm64_netbsd_lib_argv<>(SB)
-
- // Synchronous initialization.
- MOVD $runtime·libpreinit(SB), R4
- BL (R4)
-
- // Create a new thread to do the runtime initialization and return.
- MOVD _cgo_sys_thread_create(SB), R4
- CBZ R4, nocgo
- MOVD $_rt0_arm64_netbsd_lib_go(SB), R0
- MOVD $0, R1
- SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
- BL (R4)
- ADD $16, RSP
- B restore
-
-nocgo:
- MOVD $0x800000, R0 // stacksize = 8192KB
- MOVD $_rt0_arm64_netbsd_lib_go(SB), R1
- MOVD R0, 8(RSP)
- MOVD R1, 16(RSP)
- MOVD $runtime·newosproc0(SB),R4
- BL (R4)
-
-restore:
- // Restore callee-save registers.
- RESTORE_R19_TO_R28(24)
- RESTORE_F8_TO_F15(104)
- RET
-
-TEXT _rt0_arm64_netbsd_lib_go(SB),NOSPLIT,$0
- MOVD _rt0_arm64_netbsd_lib_argc<>(SB), R0
- MOVD _rt0_arm64_netbsd_lib_argv<>(SB), R1
- MOVD $runtime·rt0_go(SB),R4
- B (R4)
-
-DATA _rt0_arm64_netbsd_lib_argc<>(SB)/8, $0
-GLOBL _rt0_arm64_netbsd_lib_argc<>(SB),NOPTR, $8
-DATA _rt0_arm64_netbsd_lib_argv<>(SB)/8, $0
-GLOBL _rt0_arm64_netbsd_lib_argv<>(SB),NOPTR, $8
-
-
-TEXT main(SB),NOSPLIT|NOFRAME,$0
- MOVD $runtime·rt0_go(SB), R2
- BL (R2)
-exit:
- MOVD $0, R0
- SVC $1 // sys_exit
+TEXT _rt0_arm64_netbsd_lib(SB),NOSPLIT,$0
+ JMP _rt0_arm64_lib(SB)
// license that can be found in the LICENSE file.
#include "textflag.h"
-#include "cgo/abi_arm64.h"
-// See comment in runtime/sys_openbsd_arm64.s re this construction.
-#define INVOKE_SYSCALL \
- SVC; \
- NOOP; \
- NOOP
-
-TEXT _rt0_arm64_openbsd(SB),NOSPLIT|NOFRAME,$0
- MOVD 0(RSP), R0 // argc
- ADD $8, RSP, R1 // argv
- BL main(SB)
+TEXT _rt0_arm64_openbsd(SB),NOSPLIT,$0
+ JMP _rt0_arm64(SB)
// When building with -buildmode=c-shared, this symbol is called when the shared
// library is loaded.
TEXT _rt0_arm64_openbsd_lib(SB),NOSPLIT,$184
- // Preserve callee-save registers.
- SAVE_R19_TO_R28(24)
- SAVE_F8_TO_F15(104)
-
- // Initialize g as null in case of using g later e.g. sigaction in cgo_sigaction.go
- MOVD ZR, g
-
- MOVD R0, _rt0_arm64_openbsd_lib_argc<>(SB)
- MOVD R1, _rt0_arm64_openbsd_lib_argv<>(SB)
-
- // Synchronous initialization.
- MOVD $runtime·libpreinit(SB), R4
- BL (R4)
-
- // Create a new thread to do the runtime initialization and return.
- MOVD _cgo_sys_thread_create(SB), R4
- CBZ R4, nocgo
- MOVD $_rt0_arm64_openbsd_lib_go(SB), R0
- MOVD $0, R1
- SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
- BL (R4)
- ADD $16, RSP
- B restore
-
-nocgo:
- MOVD $0x800000, R0 // stacksize = 8192KB
- MOVD $_rt0_arm64_openbsd_lib_go(SB), R1
- MOVD R0, 8(RSP)
- MOVD R1, 16(RSP)
- MOVD $runtime·newosproc0(SB),R4
- BL (R4)
-
-restore:
- // Restore callee-save registers.
- RESTORE_R19_TO_R28(24)
- RESTORE_F8_TO_F15(104)
- RET
-
-TEXT _rt0_arm64_openbsd_lib_go(SB),NOSPLIT,$0
- MOVD _rt0_arm64_openbsd_lib_argc<>(SB), R0
- MOVD _rt0_arm64_openbsd_lib_argv<>(SB), R1
- MOVD $runtime·rt0_go(SB),R4
- B (R4)
-
-DATA _rt0_arm64_openbsd_lib_argc<>(SB)/8, $0
-GLOBL _rt0_arm64_openbsd_lib_argc<>(SB),NOPTR, $8
-DATA _rt0_arm64_openbsd_lib_argv<>(SB)/8, $0
-GLOBL _rt0_arm64_openbsd_lib_argv<>(SB),NOPTR, $8
-
-
-TEXT main(SB),NOSPLIT|NOFRAME,$0
- MOVD $runtime·rt0_go(SB), R2
- BL (R2)
-exit:
- MOVD $0, R0
- MOVD $1, R8 // sys_exit
- INVOKE_SYSCALL
- B exit
+ JMP _rt0_arm64_lib(SB)
// This is the entry point for the program from the
// kernel for an ordinary -buildmode=exe program.
-TEXT _rt0_arm64_windows(SB),NOSPLIT|NOFRAME,$0
- B ·rt0_go(SB)
+TEXT _rt0_arm64_windows(SB),NOSPLIT,$0
+ // Windows doesn't use argc and argv,
+ // so there is no need to go through _rt0_arm64.
+ JMP runtime·rt0_go(SB)
-TEXT _rt0_arm64_windows_lib(SB),NOSPLIT|NOFRAME,$0
- MOVD $_rt0_arm64_windows_lib_go(SB), R0
- MOVD $0, R1
- MOVD _cgo_sys_thread_create(SB), R2
- B (R2)
-
-TEXT _rt0_arm64_windows_lib_go(SB),NOSPLIT|NOFRAME,$0
+// When building with -buildmode=c-shared, this symbol is called when the shared
+// library is loaded.
+TEXT _rt0_arm64_windows_lib(SB),NOSPLIT,$0
+ // We get the argc and argv parameters from Win32.
MOVD $0, R0
MOVD $0, R1
- MOVD $runtime·rt0_go(SB), R2
- B (R2)
-
-TEXT main(SB),NOSPLIT|NOFRAME,$0
- MOVD $runtime·rt0_go(SB), R2
- B (R2)
-
+ JMP _rt0_arm64_lib(SB)