aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/libinit.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/libinit.go')
-rw-r--r--src/runtime/libinit.go18
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)
}
}