diff options
Diffstat (limited to 'src/runtime/libinit.go')
| -rw-r--r-- | src/runtime/libinit.go | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/runtime/libinit.go b/src/runtime/libinit.go index 7e298a2eca..2c81f61644 100644 --- a/src/runtime/libinit.go +++ b/src/runtime/libinit.go @@ -11,6 +11,13 @@ import ( "unsafe" ) +// rt0LibGoFn holds the function pointer to rt0_lib_go suitable for thread +// creation. On most platforms it is zero, meaning the raw code address should +// be used. On AIX it is set by libpreinit to a function descriptor pointer, +// because pthread_create on AIX expects a function descriptor, not a raw +// code address. +var rt0LibGoFn uintptr + // libInit is common startup code for most architectures when // using -buildmode=c-archive or -buildmode=c-shared. // @@ -22,13 +29,20 @@ func libInit() { // Synchronous initialization. libpreinit() + // Use the platform-specific function pointer if set (e.g. AIX + // function descriptor), otherwise fall back to the raw code address. + fn := unsafe.Pointer(rt0LibGoFn) + if fn == nil { + fn = unsafe.Pointer(abi.FuncPCABIInternal(rt0_lib_go)) + } + // Asynchronous initialization. // Prefer creating a thread via cgo if it is available. if _cgo_sys_thread_create != nil { // No g because the TLS is not set up until later in rt0_go. - asmcgocall_no_g(_cgo_sys_thread_create, unsafe.Pointer(abi.FuncPCABIInternal(rt0_lib_go))) + asmcgocall_no_g(_cgo_sys_thread_create, fn) } else { const stackSize = 0x800000 // 8192KB - newosproc0(stackSize, unsafe.Pointer(abi.FuncPCABIInternal(rt0_lib_go))) + newosproc0(stackSize, fn) } } |
