github.com/jwijenbergh/purego@v0.0.0-20240126093400-70ff3a61df13/internal/fakecgo/go_darwin_arm64.go (about) 1 // Copyright 2011 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 package fakecgo 6 7 import "unsafe" 8 9 //go:nosplit 10 //go:norace 11 func _cgo_sys_thread_start(ts *ThreadStart) { 12 var attr pthread_attr_t 13 var ign, oset sigset_t 14 var p pthread_t 15 var size size_t 16 var err int 17 18 sigfillset(&ign) 19 pthread_sigmask(SIG_SETMASK, &ign, &oset) 20 21 size = pthread_get_stacksize_np(pthread_self()) 22 pthread_attr_init(&attr) 23 pthread_attr_setstacksize(&attr, size) 24 // Leave stacklo=0 and set stackhi=size; mstart will do the rest. 25 ts.g.stackhi = uintptr(size) 26 27 err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts) 28 29 pthread_sigmask(SIG_SETMASK, &oset, nil) 30 31 if err != 0 { 32 print("fakecgo: pthread_create failed: ") 33 println(err) 34 abort() 35 } 36 } 37 38 // threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function 39 // 40 //go:linkname x_threadentry_trampoline threadentry_trampoline 41 var x_threadentry_trampoline byte 42 var threadentry_trampolineABI0 = &x_threadentry_trampoline 43 44 //go:nosplit 45 //go:norace 46 func threadentry(v unsafe.Pointer) unsafe.Pointer { 47 ts := *(*ThreadStart)(v) 48 free(v) 49 50 // TODO: support ios 51 //#if TARGET_OS_IPHONE 52 // darwin_arm_init_thread_exception_port(); 53 //#endif 54 setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g))) 55 56 // faking funcs in go is a bit a... involved - but the following works :) 57 fn := uintptr(unsafe.Pointer(&ts.fn)) 58 (*(*func())(unsafe.Pointer(&fn)))() 59 60 return nil 61 } 62 63 // here we will store a pointer to the provided setg func 64 var setg_func uintptr 65 66 // x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c) 67 // This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us 68 // Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup 69 // This function can't be go:systemstack since go is not in a state where the systemcheck would work. 70 // 71 //go:nosplit 72 //go:norace 73 func x_cgo_init(g *G, setg uintptr) { 74 var size size_t 75 76 setg_func = setg 77 size = pthread_get_stacksize_np(pthread_self()) 78 g.stacklo = uintptr(unsafe.Add(unsafe.Pointer(&size), -size+4096)) 79 80 //TODO: support ios 81 //#if TARGET_OS_IPHONE 82 // darwin_arm_init_mach_exception_handler(); 83 // darwin_arm_init_thread_exception_port(); 84 // init_working_dir(); 85 //#endif 86 }