Source file src/runtime/libinit.go
1 // Copyright 2026 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build 386 || amd64 || arm || arm64 || loong64 || ppc64 || ppc64le || riscv64 || s390x 6 7 package runtime 8 9 import ( 10 "internal/abi" 11 "unsafe" 12 ) 13 14 // rt0LibGoFn holds the function pointer to rt0_lib_go suitable for thread 15 // creation. On most platforms it is zero, meaning the raw code address should 16 // be used. On AIX it is set by libpreinit to a function descriptor pointer, 17 // because pthread_create on AIX expects a function descriptor, not a raw 18 // code address. 19 var rt0LibGoFn uintptr 20 21 // libInit is common startup code for most architectures when 22 // using -buildmode=c-archive or -buildmode=c-shared. 23 // 24 // May run with m.p==nil, so write barriers are not allowed. 25 // 26 //go:nowritebarrierrec 27 //go:nosplit 28 func libInit() { 29 // Synchronous initialization. 30 libpreinit() 31 32 // Use the platform-specific function pointer if set (e.g. AIX 33 // function descriptor), otherwise fall back to the raw code address. 34 fn := unsafe.Pointer(rt0LibGoFn) 35 if fn == nil { 36 fn = unsafe.Pointer(abi.FuncPCABIInternal(rt0_lib_go)) 37 } 38 39 // Asynchronous initialization. 40 // Prefer creating a thread via cgo if it is available. 41 if _cgo_sys_thread_create != nil { 42 // No g because the TLS is not set up until later in rt0_go. 43 asmcgocall_no_g(_cgo_sys_thread_create, fn) 44 } else { 45 const stackSize = 0x800000 // 8192KB 46 newosproc0(stackSize, fn) 47 } 48 } 49