diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:16:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:16:40 +0000 |
commit | 47ab3d4a42e9ab51c465c4322d2ec233f6324e6b (patch) | |
tree | a61a0ffd83f4a3def4b36e5c8e99630c559aa723 /src/runtime/cgo/gcc_darwin_arm64.c | |
parent | Initial commit. (diff) | |
download | golang-1.18-upstream.tar.xz golang-1.18-upstream.zip |
Adding upstream version 1.18.10.upstream/1.18.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/runtime/cgo/gcc_darwin_arm64.c')
-rw-r--r-- | src/runtime/cgo/gcc_darwin_arm64.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/src/runtime/cgo/gcc_darwin_arm64.c b/src/runtime/cgo/gcc_darwin_arm64.c new file mode 100644 index 0000000..a5f07f1 --- /dev/null +++ b/src/runtime/cgo/gcc_darwin_arm64.c @@ -0,0 +1,145 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include <limits.h> +#include <pthread.h> +#include <signal.h> +#include <string.h> /* for strerror */ +#include <sys/param.h> +#include <unistd.h> +#include <stdlib.h> + +#include "libcgo.h" +#include "libcgo_unix.h" + +#include <TargetConditionals.h> + +#if TARGET_OS_IPHONE +#include <CoreFoundation/CFBundle.h> +#include <CoreFoundation/CFString.h> +#endif + +static void *threadentry(void*); +static void (*setg_gcc)(void*); + +void +_cgo_sys_thread_start(ThreadStart *ts) +{ + pthread_attr_t attr; + sigset_t ign, oset; + pthread_t p; + size_t size; + int err; + + //fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug + sigfillset(&ign); + pthread_sigmask(SIG_SETMASK, &ign, &oset); + + pthread_attr_init(&attr); + size = 0; + pthread_attr_getstacksize(&attr, &size); + // Leave stacklo=0 and set stackhi=size; mstart will do the rest. + ts->g->stackhi = size; + err = _cgo_try_pthread_create(&p, &attr, threadentry, ts); + + pthread_sigmask(SIG_SETMASK, &oset, nil); + + if (err != 0) { + fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err)); + abort(); + } +} + +extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g); +static void* +threadentry(void *v) +{ + ThreadStart ts; + + ts = *(ThreadStart*)v; + free(v); + +#if TARGET_OS_IPHONE + darwin_arm_init_thread_exception_port(); +#endif + + crosscall1(ts.fn, setg_gcc, (void*)ts.g); + return nil; +} + +#if TARGET_OS_IPHONE + +// init_working_dir sets the current working directory to the app root. +// By default ios/arm64 processes start in "/". +static void +init_working_dir() +{ + CFBundleRef bundle = CFBundleGetMainBundle(); + if (bundle == NULL) { + fprintf(stderr, "runtime/cgo: no main bundle\n"); + return; + } + CFURLRef url_ref = CFBundleCopyResourceURL(bundle, CFSTR("Info"), CFSTR("plist"), NULL); + if (url_ref == NULL) { + // No Info.plist found. It can happen on Corellium virtual devices. + return; + } + CFStringRef url_str_ref = CFURLGetString(url_ref); + char buf[MAXPATHLEN]; + Boolean res = CFStringGetCString(url_str_ref, buf, sizeof(buf), kCFStringEncodingUTF8); + CFRelease(url_ref); + if (!res) { + fprintf(stderr, "runtime/cgo: cannot get URL string\n"); + return; + } + + // url is of the form "file:///path/to/Info.plist". + // strip it down to the working directory "/path/to". + int url_len = strlen(buf); + if (url_len < sizeof("file://")+sizeof("/Info.plist")) { + fprintf(stderr, "runtime/cgo: bad URL: %s\n", buf); + return; + } + buf[url_len-sizeof("/Info.plist")+1] = 0; + char *dir = &buf[0] + sizeof("file://")-1; + + if (chdir(dir) != 0) { + fprintf(stderr, "runtime/cgo: chdir(%s) failed\n", dir); + } + + // The test harness in go_ios_exec passes the relative working directory + // in the GoExecWrapperWorkingDirectory property of the app bundle. + CFStringRef wd_ref = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("GoExecWrapperWorkingDirectory")); + if (wd_ref != NULL) { + if (!CFStringGetCString(wd_ref, buf, sizeof(buf), kCFStringEncodingUTF8)) { + fprintf(stderr, "runtime/cgo: cannot get GoExecWrapperWorkingDirectory string\n"); + return; + } + if (chdir(buf) != 0) { + fprintf(stderr, "runtime/cgo: chdir(%s) failed\n", buf); + } + } +} + +#endif // TARGET_OS_IPHONE + +void +x_cgo_init(G *g, void (*setg)(void*)) +{ + pthread_attr_t attr; + size_t size; + + //fprintf(stderr, "x_cgo_init = %p\n", &x_cgo_init); // aid debugging in presence of ASLR + setg_gcc = setg; + pthread_attr_init(&attr); + pthread_attr_getstacksize(&attr, &size); + g->stacklo = (uintptr)&attr - size + 4096; + pthread_attr_destroy(&attr); + +#if TARGET_OS_IPHONE + darwin_arm_init_mach_exception_handler(); + darwin_arm_init_thread_exception_port(); + init_working_dir(); +#endif +} |