aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/asm_386.s37
-rw-r--r--src/runtime/asm_amd64.s49
-rw-r--r--src/runtime/asm_arm.s22
-rw-r--r--src/runtime/asm_arm64.s24
-rw-r--r--src/runtime/asm_loong64.s22
-rw-r--r--src/runtime/asm_ppc64x.s43
-rw-r--r--src/runtime/asm_riscv64.s22
-rw-r--r--src/runtime/asm_s390x.s28
-rw-r--r--src/runtime/cgo/gcc_libinit_windows.c4
-rw-r--r--src/runtime/cgo/libcgo.h2
-rw-r--r--src/runtime/cgo/pthread_unix.c4
-rw-r--r--src/runtime/os2_aix.go6
-rw-r--r--src/runtime/os3_solaris.go10
-rw-r--r--src/runtime/os_aix.go4
-rw-r--r--src/runtime/os_darwin.go4
-rw-r--r--src/runtime/os_dragonfly.go10
-rw-r--r--src/runtime/os_js.go10
-rw-r--r--src/runtime/os_netbsd.go10
-rw-r--r--src/runtime/os_openbsd.go10
-rw-r--r--src/runtime/os_plan9.go10
-rw-r--r--src/runtime/os_wasip1.go10
-rw-r--r--src/runtime/os_windows.go2
-rw-r--r--src/runtime/proc.go21
-rw-r--r--src/runtime/stubs.go1
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.