diff options
| author | qmuntal <quimmuntal@gmail.com> | 2026-03-05 10:07:49 +0100 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2026-03-18 15:32:53 -0700 |
| commit | 6bdfdb5f51951584732e6a95a7ee8a5ba5e8cb93 (patch) | |
| tree | 5de5bf3d98eda9a353de1028b9e0836adb77ea2f /src | |
| parent | 8e137ff9953d7a535170c9f3ff2c55811e7e13c3 (diff) | |
| download | go-6bdfdb5f51951584732e6a95a7ee8a5ba5e8cb93.tar.xz | |
runtime: implement part of library initialization in Go
All architectures supporting c-shared and c-archive share the same
initialization code in assembly, and most of it can be implemented in
pure Go.
Cq-Include-Trybots: luci.golang.try:gotip-darwin-arm64-longtest,gotip-linux-ppc64le_power10,gotip-linux-riscv64,gotip-linux-loong64,gotip-linux-s390x
Change-Id: Iaa9fb7d6f9ca8785f1098461646d607ef6b00d47
Reviewed-on: https://go-review.googlesource.com/c/go/+/706417
Auto-Submit: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/runtime/asm_386.s | 37 | ||||
| -rw-r--r-- | src/runtime/asm_amd64.s | 49 | ||||
| -rw-r--r-- | src/runtime/asm_arm.s | 22 | ||||
| -rw-r--r-- | src/runtime/asm_arm64.s | 24 | ||||
| -rw-r--r-- | src/runtime/asm_loong64.s | 22 | ||||
| -rw-r--r-- | src/runtime/asm_ppc64x.s | 43 | ||||
| -rw-r--r-- | src/runtime/asm_riscv64.s | 22 | ||||
| -rw-r--r-- | src/runtime/asm_s390x.s | 28 | ||||
| -rw-r--r-- | src/runtime/cgo/gcc_libinit_windows.c | 4 | ||||
| -rw-r--r-- | src/runtime/cgo/libcgo.h | 2 | ||||
| -rw-r--r-- | src/runtime/cgo/pthread_unix.c | 4 | ||||
| -rw-r--r-- | src/runtime/os2_aix.go | 6 | ||||
| -rw-r--r-- | src/runtime/os3_solaris.go | 10 | ||||
| -rw-r--r-- | src/runtime/os_aix.go | 4 | ||||
| -rw-r--r-- | src/runtime/os_darwin.go | 4 | ||||
| -rw-r--r-- | src/runtime/os_dragonfly.go | 10 | ||||
| -rw-r--r-- | src/runtime/os_js.go | 10 | ||||
| -rw-r--r-- | src/runtime/os_netbsd.go | 10 | ||||
| -rw-r--r-- | src/runtime/os_openbsd.go | 10 | ||||
| -rw-r--r-- | src/runtime/os_plan9.go | 10 | ||||
| -rw-r--r-- | src/runtime/os_wasip1.go | 10 | ||||
| -rw-r--r-- | src/runtime/os_windows.go | 2 | ||||
| -rw-r--r-- | src/runtime/proc.go | 21 | ||||
| -rw-r--r-- | src/runtime/stubs.go | 1 |
24 files changed, 139 insertions, 226 deletions
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s index 839d0ad147..2049ba0295 100644 --- a/src/runtime/asm_386.s +++ b/src/runtime/asm_386.s @@ -36,48 +36,17 @@ TEXT _rt0_386_lib(SB),NOSPLIT,$0 MOVL 12(BP), AX MOVL AX, _rt0_386_lib_argv<>(SB) - // Synchronous initialization. - CALL runtime·libpreinit(SB) + CALL runtime·libInit(SB) - SUBL $8, SP - - // Create a new thread to do the runtime initialization. - MOVL _cgo_sys_thread_create(SB), AX - TESTL AX, AX - JZ nocgo - - // Align stack to call C function. - // We moved SP to BP above, but BP was clobbered by the libpreinit call. - MOVL SP, BP - ANDL $~15, SP - - MOVL $_rt0_386_lib_go(SB), BX - MOVL BX, 0(SP) - MOVL $0, 4(SP) - - CALL AX - - MOVL BP, SP - - JMP restore - -nocgo: - MOVL $0x800000, 0(SP) // stacksize = 8192KB - MOVL $_rt0_386_lib_go(SB), AX - MOVL AX, 4(SP) // fn - CALL runtime·newosproc0(SB) - -restore: - ADDL $8, SP POPL DI POPL SI POPL BX POPL BP RET -// _rt0_386_lib_go initializes the Go runtime. +// rt0_lib_go initializes the Go runtime. // This is started in a separate thread by _rt0_386_lib. -TEXT _rt0_386_lib_go(SB),NOSPLIT,$8 +TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$8 MOVL _rt0_386_lib_argc<>(SB), AX MOVL AX, 0(SP) MOVL _rt0_386_lib_argv<>(SB), AX diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s index 09fd8e11d2..94120cdbed 100644 --- a/src/runtime/asm_amd64.s +++ b/src/runtime/asm_amd64.s @@ -36,55 +36,22 @@ TEXT _rt0_amd64_lib(SB),NOSPLIT|NOFRAME,$0 MOVQ DI, _rt0_amd64_lib_argc<>(SB) MOVQ SI, _rt0_amd64_lib_argv<>(SB) - // Synchronous initialization. -#ifndef GOOS_windows - // Avoid calling it on Windows because it is not used - // and it would crash the application due to the autogenerated - // ABI wrapper trying to access a non-existent TLS slot. - CALL runtime·libpreinit(SB) -#endif - - // Create a new thread to finish Go runtime initialization. - MOVQ _cgo_sys_thread_create(SB), AX - TESTQ AX, AX - JZ nocgo - - // We're calling back to C. - // Align stack per C ABI requirements. - MOVQ SP, BX // Callee-save in C ABI - ANDQ $~15, SP - MOVQ $_rt0_amd64_lib_go(SB), DI - MOVQ $0, SI #ifdef GOOS_windows - // For Windows ABI - MOVQ DI, CX - MOVQ SI, DX - // Leave space for four words on the stack as required - // by the Windows amd64 calling convention. - ADJSP $32 -#endif - CALL AX -#ifdef GOOS_windows - ADJSP $-32 // just to make the assembler not complain about unbalanced stack + // Set up a dummy TLS value on Windows so that the autogenerated + // ABI wrappers don't crash when trying to load G from TLS before + // wintls has set up the real TLS slot in rt0_go. + MOVQ $zeroTLS<>(SB), DI + CALL runtime·settls(SB) #endif - MOVQ BX, SP - JMP restore -nocgo: - ADJSP $16 - MOVQ $0x800000, 0(SP) // stacksize - MOVQ $_rt0_amd64_lib_go(SB), AX - MOVQ AX, 8(SP) // fn - CALL runtime·newosproc0(SB) - ADJSP $-16 + CALL runtime·libInit(SB) -restore: POP_REGS_HOST_TO_ABI0() RET -// _rt0_amd64_lib_go initializes the Go runtime. +// rt0_lib_go initializes the Go runtime. // This is started in a separate thread by _rt0_amd64_lib. -TEXT _rt0_amd64_lib_go(SB),NOSPLIT,$0 +TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$0 MOVQ _rt0_amd64_lib_argc<>(SB), DI MOVQ _rt0_amd64_lib_argv<>(SB), SI JMP runtime·rt0_go(SB) diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s index d9bf04f4c3..f5c2454752 100644 --- a/src/runtime/asm_arm.s +++ b/src/runtime/asm_arm.s @@ -58,24 +58,8 @@ skipfpsave: MOVW $0, g // Initialize g. - // Synchronous initialization. - CALL runtime·libpreinit(SB) + CALL runtime·libInit(SB) - // Create a new thread to do the runtime initialization. - MOVW _cgo_sys_thread_create(SB), R2 - CMP $0, R2 - BEQ nocgo - MOVW $_rt0_arm_lib_go<>(SB), R0 - MOVW $0, R1 - BL (R2) - B rr -nocgo: - MOVW $0x800000, R0 // stacksize = 8192KB - MOVW $_rt0_arm_lib_go<>(SB), R1 // fn - MOVW R0, 4(R13) - MOVW R1, 8(R13) - BL runtime·newosproc0(SB) -rr: // Restore callee-save registers and return. MOVB runtime·goarmsoftfp(SB), R11 CMP $0, R11 @@ -98,9 +82,9 @@ skipfprest: MOVW 36(R13), R11 RET -// _rt0_arm_lib_go initializes the Go runtime. +// rt0_lib_go initializes the Go runtime. // This is started in a separate thread by _rt0_arm_lib. -TEXT _rt0_arm_lib_go<>(SB),NOSPLIT,$8 +TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$8 MOVW _rt0_arm_lib_argc<>(SB), R0 MOVW _rt0_arm_lib_argv<>(SB), R1 B runtime·rt0_go(SB) diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s index 02ecfc51a1..b16e9151fc 100644 --- a/src/runtime/asm_arm64.s +++ b/src/runtime/asm_arm64.s @@ -41,35 +41,15 @@ TEXT _rt0_arm64_lib(SB),NOSPLIT,$184 MOVD R0, _rt0_arm64_lib_argc<>(SB) MOVD R1, _rt0_arm64_lib_argv<>(SB) - // Synchronous initialization. - MOVD $runtime·libpreinit(SB), R4 + MOVD $runtime·libInit(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 +TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$0 MOVD _rt0_arm64_lib_argc<>(SB), R0 MOVD _rt0_arm64_lib_argv<>(SB), R1 MOVD $runtime·rt0_go(SB),R4 diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s index 88173679e6..b444bc9305 100644 --- a/src/runtime/asm_loong64.s +++ b/src/runtime/asm_loong64.s @@ -21,33 +21,15 @@ TEXT _rt0_loong64_lib(SB),NOSPLIT,$168 MOVV R4, _rt0_loong64_lib_argc<>(SB) MOVV R5, _rt0_loong64_lib_argv<>(SB) - // Synchronous initialization. - MOVV $runtime·libpreinit(SB), R19 + MOVV $runtime·libInit(SB), R19 JAL (R19) - // Create a new thread to do the runtime initialization and return. - MOVV _cgo_sys_thread_create(SB), R19 - BEQ R19, nocgo - MOVV $_rt0_loong64_lib_go(SB), R4 - MOVV $0, R5 - JAL (R19) - JMP restore - -nocgo: - MOVV $0x800000, R4 // stacksize = 8192KB - MOVV $_rt0_loong64_lib_go(SB), R5 - MOVV R4, 8(R3) - MOVV R5, 16(R3) - MOVV $runtime·newosproc0(SB), R19 - JAL (R19) - -restore: // Restore callee-save registers. RESTORE_R22_TO_R31(3*8) RESTORE_F24_TO_F31(13*8) RET -TEXT _rt0_loong64_lib_go(SB),NOSPLIT,$0 +TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$0 MOVV _rt0_loong64_lib_argc<>(SB), R4 MOVV _rt0_loong64_lib_argv<>(SB), R5 MOVV $runtime·rt0_go(SB),R19 diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s index a72974b555..15bd63a1d5 100644 --- a/src/runtime/asm_ppc64x.s +++ b/src/runtime/asm_ppc64x.s @@ -31,53 +31,26 @@ TEXT _rt0_ppc64x_lib(SB),NOSPLIT|NOFRAME,$0 MOVD R12, CTR BL (CTR) + // Initialize g as nil in case of using g later e.g. sigaction in cgo_sigaction.go + MOVD R0, g + #ifdef GOOS_aix // See runtime/cgo/gcc_aix_ppc64.c MOVBZ runtime·isarchive(SB), R3 // Check buildmode = c-archive CMP $0, R3 - BEQ done -#endif - - MOVD $runtime·libpreinit(SB), R12 - MOVD R12, CTR - BL (CTR) - - // Create a new thread to do the runtime initialization and return. - // _cgo_sys_thread_create is a C function. - MOVD _cgo_sys_thread_create(SB), R12 - CMP $0, R12 - BEQ nocgo - MOVD $_rt0_ppc64x_lib_go(SB), R3 - MOVD $0, R4 -#ifdef GO_PPC64X_HAS_FUNCDESC - // Load the real entry address from the first slot of the function descriptor. - MOVD 8(R12), R2 - MOVD (R12), R12 + BEQ skipInit #endif - MOVD R12, CTR - BL (CTR) - MOVD 24(R1), R2 // Restore the old frame, and R2. - BR done -nocgo: - MOVD $0x800000, R12 // stacksize = 8192KB - MOVD R12, 8+FIXED_FRAME(R1) - MOVD $_rt0_ppc64x_lib_go(SB), R12 - MOVD R12, 16+FIXED_FRAME(R1) - MOVD $runtime·newosproc0(SB),R12 + MOVD $runtime·libInit(SB), R12 MOVD R12, CTR BL (CTR) -done: +skipInit: + // Restore and return to ELFv2 caller. UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32) RET -#ifdef GO_PPC64X_HAS_FUNCDESC -DEFINE_PPC64X_FUNCDESC(_rt0_ppc64x_lib_go, __rt0_ppc64x_lib_go) -TEXT __rt0_ppc64x_lib_go(SB),NOSPLIT,$0 -#else -TEXT _rt0_ppc64x_lib_go(SB),NOSPLIT,$0 -#endif +TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$0 MOVD _rt0_ppc64x_lib_argc<>(SB), R3 MOVD _rt0_ppc64x_lib_argv<>(SB), R4 MOVD $runtime·rt0_go(SB), R12 diff --git a/src/runtime/asm_riscv64.s b/src/runtime/asm_riscv64.s index cafef51eb9..2b935b0760 100644 --- a/src/runtime/asm_riscv64.s +++ b/src/runtime/asm_riscv64.s @@ -22,27 +22,9 @@ TEXT _rt0_riscv64_lib(SB),NOSPLIT,$224 MOV A0, _rt0_riscv64_lib_argc<>(SB) MOV A1, _rt0_riscv64_lib_argv<>(SB) - // Synchronous initialization. - MOV $runtime·libpreinit(SB), T1 + MOV $runtime·libInit(SB), T1 JALR RA, T1 - // Create a new thread to do the runtime initialization and return. - MOV _cgo_sys_thread_create(SB), T1 - BEQZ T1, nocgo - MOV $_rt0_riscv64_lib_go(SB), A0 - MOV $0, A1 - JALR RA, T1 - JMP restore - -nocgo: - MOV $0x800000, A0 // stacksize = 8192KB - MOV $_rt0_riscv64_lib_go(SB), A1 - MOV A0, 8(X2) - MOV A1, 16(X2) - MOV $runtime·newosproc0(SB), T1 - JALR RA, T1 - -restore: // Restore callee-save registers, along with X1 (LR). MOV (8*3)(X2), X1 RESTORE_GPR((8*4)) @@ -50,7 +32,7 @@ restore: RET -TEXT _rt0_riscv64_lib_go(SB),NOSPLIT,$0 +TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$0 MOV _rt0_riscv64_lib_argc<>(SB), A0 MOV _rt0_riscv64_lib_argv<>(SB), A1 MOV $runtime·rt0_go(SB), T0 diff --git a/src/runtime/asm_s390x.s b/src/runtime/asm_s390x.s index 2870e32420..f0669af551 100644 --- a/src/runtime/asm_s390x.s +++ b/src/runtime/asm_s390x.s @@ -34,28 +34,12 @@ TEXT _rt0_s390x_lib(SB), NOSPLIT|NOFRAME, $0 FMOVD F14, 64(R15) FMOVD F15, 72(R15) - // Synchronous initialization. - MOVD $runtime·libpreinit(SB), R1 - BL R1 - - // Create a new thread to finish Go runtime initialization. - MOVD _cgo_sys_thread_create(SB), R1 - CMP R1, $0 - BEQ nocgo - MOVD $_rt0_s390x_lib_go(SB), R2 - MOVD $0, R3 - BL R1 - BR restore + // Initialize g as nil in case of using g later e.g. sigaction in cgo_sigaction.go + XOR g, g -nocgo: - MOVD $0x800000, R1 // stacksize - MOVD R1, 0(R15) - MOVD $_rt0_s390x_lib_go(SB), R1 - MOVD R1, 8(R15) // fn - MOVD $runtime·newosproc(SB), R1 + MOVD $runtime·libInit(SB), R1 BL R1 -restore: // Restore F8-F15 from our stack frame. FMOVD 16(R15), F8 FMOVD 24(R15), F9 @@ -71,9 +55,9 @@ restore: LMG 48(R15), R6, R15 RET -// _rt0_s390x_lib_go initializes the Go runtime. +// rt0_lib_go initializes the Go runtime. // This is started in a separate thread by _rt0_s390x_lib. -TEXT _rt0_s390x_lib_go(SB), NOSPLIT|NOFRAME, $0 +TEXT runtime·rt0_lib_go<ABIInternal>(SB), NOSPLIT|NOFRAME, $0 MOVD _rt0_s390x_lib_argc<>(SB), R2 MOVD _rt0_s390x_lib_argv<>(SB), R3 MOVD $runtime·rt0_go(SB), R1 @@ -81,7 +65,7 @@ TEXT _rt0_s390x_lib_go(SB), NOSPLIT|NOFRAME, $0 DATA _rt0_s390x_lib_argc<>(SB)/8, $0 GLOBL _rt0_s390x_lib_argc<>(SB), NOPTR, $8 -DATA _rt0_s90x_lib_argv<>(SB)/8, $0 +DATA _rt0_s390x_lib_argv<>(SB)/8, $0 GLOBL _rt0_s390x_lib_argv<>(SB), NOPTR, $8 TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0 diff --git a/src/runtime/cgo/gcc_libinit_windows.c b/src/runtime/cgo/gcc_libinit_windows.c index d2082e0916..7a1dbc0119 100644 --- a/src/runtime/cgo/gcc_libinit_windows.c +++ b/src/runtime/cgo/gcc_libinit_windows.c @@ -57,8 +57,8 @@ _cgo_maybe_run_preinit() { } void -x_cgo_sys_thread_create(unsigned long (__stdcall *func)(void*), void* arg) { - _cgo_beginthread(func, arg); +x_cgo_sys_thread_create(unsigned long (__stdcall *func)(void*)) { + _cgo_beginthread(func, NULL); } int diff --git a/src/runtime/cgo/libcgo.h b/src/runtime/cgo/libcgo.h index 108b85f794..ae0542df36 100644 --- a/src/runtime/cgo/libcgo.h +++ b/src/runtime/cgo/libcgo.h @@ -49,7 +49,7 @@ extern void (*_cgo_thread_start)(ThreadStart *ts); * Creates a new operating system thread without updating any Go state * (OS dependent). */ -extern void (*_cgo_sys_thread_create)(void* (*func)(void*), void* arg); +extern void (*_cgo_sys_thread_create)(void* (*func)(void*)); /* * Indicates whether a dummy pthread per-thread variable is allocated. diff --git a/src/runtime/cgo/pthread_unix.c b/src/runtime/cgo/pthread_unix.c index a2fe16619e..d38045fdaa 100644 --- a/src/runtime/cgo/pthread_unix.c +++ b/src/runtime/cgo/pthread_unix.c @@ -60,14 +60,14 @@ _cgo_sys_thread_start(ThreadStart *ts) } void -x_cgo_sys_thread_create(void* (*func)(void*), void* arg) { +x_cgo_sys_thread_create(void* (*func)(void*)) { pthread_attr_t attr; pthread_t p; int err; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - err = _cgo_try_pthread_create(&p, &attr, func, arg); + err = _cgo_try_pthread_create(&p, &attr, func, NULL); if (err != 0) { fatalf("pthread_create failed: %s", strerror(err)); } diff --git a/src/runtime/os2_aix.go b/src/runtime/os2_aix.go index 51758bd304..0f5af28f0a 100644 --- a/src/runtime/os2_aix.go +++ b/src/runtime/os2_aix.go @@ -715,17 +715,17 @@ func pthread_attr_setstacksize(attr *pthread_attr, size uint64) int32 { func pthread_create1(tid, attr, fn, arg uintptr) int32 //go:nosplit -func pthread_create(tid *pthread, attr *pthread_attr, fn *funcDescriptor, arg unsafe.Pointer) int32 { +func pthread_create(tid *pthread, attr *pthread_attr, fn unsafe.Pointer, arg unsafe.Pointer) int32 { gp := getg() // Check the validity of g because without a g during // newosproc0. if gp != nil { - r, _ := syscall4(&libpthread_create, uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(fn)), uintptr(arg)) + r, _ := syscall4(&libpthread_create, uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(fn), uintptr(arg)) return int32(r) } - return pthread_create1(uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(fn)), uintptr(arg)) + return pthread_create1(uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(fn), uintptr(arg)) } // On multi-thread program, sigprocmask must not be called. diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go index 3197c66537..a121ed8044 100644 --- a/src/runtime/os3_solaris.go +++ b/src/runtime/os3_solaris.go @@ -644,3 +644,13 @@ const sigPerThreadSyscall = 1 << 31 func runPerThreadSyscall() { throw("runPerThreadSyscall only valid on linux") } + +//go:nowritebarrierrec +//go:nosplit +func libpreinit() {} + +//go:nowritebarrierrec +//go:nosplit +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { + throw("bad newosproc0") +} diff --git a/src/runtime/os_aix.go b/src/runtime/os_aix.go index 4bb8576f42..7a667c2419 100644 --- a/src/runtime/os_aix.go +++ b/src/runtime/os_aix.go @@ -112,7 +112,7 @@ func getCPUCount() int32 { // This function is not safe to use after initialization as it does not pass an M as fnarg. // //go:nosplit -func newosproc0(stacksize uintptr, fn *funcDescriptor) { +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { var ( attr pthread_attr oset sigset @@ -226,7 +226,7 @@ func newosproc(mp *m) { // with signals disabled. It will enable them in minit. sigprocmask(_SIG_SETMASK, &sigset_all, &oset) ret := retryOnEAGAIN(func() int32 { - return pthread_create(&tid, &attr, &tstart, unsafe.Pointer(mp)) + return pthread_create(&tid, &attr, unsafe.Pointer(&tstart), unsafe.Pointer(mp)) }) sigprocmask(_SIG_SETMASK, &oset, nil) if ret != 0 { diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go index 79cd2997c7..19dcf3be8e 100644 --- a/src/runtime/os_darwin.go +++ b/src/runtime/os_darwin.go @@ -273,7 +273,7 @@ func mstart_stub() // This function is not safe to use after initialization as it does not pass an M as fnarg. // //go:nosplit -func newosproc0(stacksize uintptr, fn uintptr) { +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { // Initialize an attribute object. var attr pthreadattr var err int32 @@ -305,7 +305,7 @@ func newosproc0(stacksize uintptr, fn uintptr) { // setup and then calls mstart. var oset sigset sigprocmask(_SIG_SETMASK, &sigset_all, &oset) - err = pthread_create(&attr, fn, nil) + err = pthread_create(&attr, uintptr(fn), nil) sigprocmask(_SIG_SETMASK, &oset, nil) if err != 0 { writeErrStr(failthreadcreate) diff --git a/src/runtime/os_dragonfly.go b/src/runtime/os_dragonfly.go index c34af7f072..e3df32f68b 100644 --- a/src/runtime/os_dragonfly.go +++ b/src/runtime/os_dragonfly.go @@ -349,3 +349,13 @@ const sigPerThreadSyscall = 1 << 31 func runPerThreadSyscall() { throw("runPerThreadSyscall only valid on linux") } + +//go:nowritebarrierrec +//go:nosplit +func libpreinit() {} + +//go:nowritebarrierrec +//go:nosplit +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { + throw("bad newosproc0") +} diff --git a/src/runtime/os_js.go b/src/runtime/os_js.go index 099c5265a0..ca310bd56c 100644 --- a/src/runtime/os_js.go +++ b/src/runtime/os_js.go @@ -40,3 +40,13 @@ func readRandom(r []byte) int { func goenvs() { goenvs_unix() } + +//go:nowritebarrierrec +//go:nosplit +func libpreinit() {} + +//go:nowritebarrierrec +//go:nosplit +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { + throw("bad newosproc0") +} diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go index f117253f34..12a75623cd 100644 --- a/src/runtime/os_netbsd.go +++ b/src/runtime/os_netbsd.go @@ -443,3 +443,13 @@ const sigPerThreadSyscall = 1 << 31 func runPerThreadSyscall() { throw("runPerThreadSyscall only valid on linux") } + +//go:nowritebarrierrec +//go:nosplit +func libpreinit() {} + +//go:nowritebarrierrec +//go:nosplit +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { + throw("bad newosproc0") +} diff --git a/src/runtime/os_openbsd.go b/src/runtime/os_openbsd.go index 3943111853..41bab37e82 100644 --- a/src/runtime/os_openbsd.go +++ b/src/runtime/os_openbsd.go @@ -339,3 +339,13 @@ const sigPerThreadSyscall = 1 << 31 func runPerThreadSyscall() { throw("runPerThreadSyscall only valid on linux") } + +//go:nowritebarrierrec +//go:nosplit +func libpreinit() {} + +//go:nowritebarrierrec +//go:nosplit +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { + throw("bad newosproc0") +} diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go index 80c101f1a1..85e1ecdb22 100644 --- a/src/runtime/os_plan9.go +++ b/src/runtime/os_plan9.go @@ -594,3 +594,13 @@ func walltime() (sec int64, nsec int32) { readtime(&t[0], 1, 1) return timesplit(frombe(t[0])) } + +//go:nowritebarrierrec +//go:nosplit +func libpreinit() {} + +//go:nowritebarrierrec +//go:nosplit +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { + throw("bad newosproc0") +} diff --git a/src/runtime/os_wasip1.go b/src/runtime/os_wasip1.go index ed4f646a62..34f1dd6da0 100644 --- a/src/runtime/os_wasip1.go +++ b/src/runtime/os_wasip1.go @@ -266,3 +266,13 @@ func nanotime1() int64 { } return int64(time) } + +//go:nowritebarrierrec +//go:nosplit +func libpreinit() {} + +//go:nowritebarrierrec +//go:nosplit +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { + throw("bad newosproc0") +} diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go index 8ed4b12c8a..ca1f9837fa 100644 --- a/src/runtime/os_windows.go +++ b/src/runtime/os_windows.go @@ -785,7 +785,7 @@ func newosproc(mp *m) { // //go:nowritebarrierrec //go:nosplit -func newosproc0(stacksize uintptr, fn uintptr) { +func newosproc0(stacksize uintptr, fn unsafe.Pointer) { throw("bad newosproc0") } diff --git a/src/runtime/proc.go b/src/runtime/proc.go index db4febace9..71e80e9cb7 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -8156,3 +8156,24 @@ func doInit1(t *initTask) { t.state = 2 // initialization done } } + +// libInit is common startup code for most architectures when +// using -buildmode=c-archive or -buildmode=c-shared. +// +// May run with m.p==nil, so write barriers are not allowed. +// +//go:nowritebarrierrec +//go:nosplit +func libInit() { + // Synchronous initialization. + libpreinit() + + // Asynchronous initialization. + // Prefer creating a thread via cgo if it is available. + if _cgo_sys_thread_create != nil { + asmcgocall(_cgo_sys_thread_create, unsafe.Pointer(abi.FuncPCABIInternal(rt0_lib_go))) + } else { + const stackSize = 0x800000 // 8192KB + newosproc0(stackSize, unsafe.Pointer(abi.FuncPCABIInternal(rt0_lib_go))) + } +} diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go index d5a35d15b2..31e35c74f5 100644 --- a/src/runtime/stubs.go +++ b/src/runtime/stubs.go @@ -334,6 +334,7 @@ func morestack() func morestack_noctxt() func rt0_go() +func rt0_lib_go() // in asm_*.s // not called directly; definitions here supply type information for traceback. |
