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  

View as plain text