|  | // Copyright 2009 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 <stdint.h> | 
|  | #include <stdlib.h> | 
|  | #include <stdio.h> | 
|  |  | 
|  | #undef nil | 
|  | #define nil ((void*)0) | 
|  | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | 
|  |  | 
|  | typedef uint32_t uint32; | 
|  | typedef uint64_t uint64; | 
|  | typedef uintptr_t uintptr; | 
|  |  | 
|  | /* | 
|  | * The beginning of the per-goroutine structure, | 
|  | * as defined in ../pkg/runtime/runtime.h. | 
|  | * Just enough to edit these two fields. | 
|  | */ | 
|  | typedef struct G G; | 
|  | struct G | 
|  | { | 
|  | uintptr stacklo; | 
|  | uintptr stackhi; | 
|  | }; | 
|  |  | 
|  | /* | 
|  | * Arguments to the _cgo_thread_start call. | 
|  | * Also known to ../pkg/runtime/runtime.h. | 
|  | */ | 
|  | typedef struct ThreadStart ThreadStart; | 
|  | struct ThreadStart | 
|  | { | 
|  | G *g; | 
|  | uintptr *tls; | 
|  | void (*fn)(void); | 
|  | }; | 
|  |  | 
|  | /* | 
|  | * Called by 5c/6c/8c world. | 
|  | * Makes a local copy of the ThreadStart and | 
|  | * calls _cgo_sys_thread_start(ts). | 
|  | */ | 
|  | extern void (*_cgo_thread_start)(ThreadStart *ts); | 
|  |  | 
|  | /* | 
|  | * Creates a new operating system thread without updating any Go state | 
|  | * (OS dependent). | 
|  | */ | 
|  | extern void (*_cgo_sys_thread_create)(void* (*func)(void*), void* arg); | 
|  |  | 
|  | /* | 
|  | * Creates the new operating system thread (OS, arch dependent). | 
|  | */ | 
|  | void _cgo_sys_thread_start(ThreadStart *ts); | 
|  |  | 
|  | /* | 
|  | * Waits for the Go runtime to be initialized (OS dependent). | 
|  | * If runtime.SetCgoTraceback is used to set a context function, | 
|  | * calls the context function and returns the context value. | 
|  | */ | 
|  | uintptr_t _cgo_wait_runtime_init_done(); | 
|  |  | 
|  | /* | 
|  | * Call fn in the 6c world. | 
|  | */ | 
|  | void crosscall_amd64(void (*fn)(void)); | 
|  |  | 
|  | /* | 
|  | * Call fn in the 8c world. | 
|  | */ | 
|  | void crosscall_386(void (*fn)(void)); | 
|  |  | 
|  | /* | 
|  | * Prints error then calls abort. For linux and android. | 
|  | */ | 
|  | void fatalf(const char* format, ...); | 
|  |  | 
|  | /* | 
|  | * Registers the current mach thread port for EXC_BAD_ACCESS processing. | 
|  | */ | 
|  | void darwin_arm_init_thread_exception_port(void); | 
|  |  | 
|  | /* | 
|  | * Starts a mach message server processing EXC_BAD_ACCESS. | 
|  | */ | 
|  | void darwin_arm_init_mach_exception_handler(void); | 
|  |  | 
|  | /* | 
|  | * The cgo context function. See runtime.SetCgoTraceback. | 
|  | */ | 
|  | struct context_arg { | 
|  | uintptr_t Context; | 
|  | }; | 
|  | extern void (*(_cgo_get_context_function(void)))(struct context_arg*); | 
|  |  | 
|  | /* | 
|  | * The argument for the cgo traceback callback. See runtime.SetCgoTraceback. | 
|  | */ | 
|  | struct cgoTracebackArg { | 
|  | uintptr_t  Context; | 
|  | uintptr_t  SigContext; | 
|  | uintptr_t* Buf; | 
|  | uintptr_t  Max; | 
|  | }; | 
|  |  | 
|  | /* | 
|  | * TSAN support.  This is only useful when building with | 
|  | *   CGO_CFLAGS="-fsanitize=thread" CGO_LDFLAGS="-fsanitize=thread" go install | 
|  | */ | 
|  | #undef CGO_TSAN | 
|  | #if defined(__has_feature) | 
|  | # if __has_feature(thread_sanitizer) | 
|  | #  define CGO_TSAN | 
|  | # endif | 
|  | #elif defined(__SANITIZE_THREAD__) | 
|  | # define CGO_TSAN | 
|  | #endif | 
|  |  | 
|  | #ifdef CGO_TSAN | 
|  |  | 
|  | // These must match the definitions in yesTsanProlog in cmd/cgo/out.go. | 
|  | // In general we should call _cgo_tsan_acquire when we enter C code, | 
|  | // and call _cgo_tsan_release when we return to Go code. | 
|  | // This is only necessary when calling code that might be instrumented | 
|  | // by TSAN, which mostly means system library calls that TSAN intercepts. | 
|  | // See the comment in cmd/cgo/out.go for more details. | 
|  |  | 
|  | long long _cgo_sync __attribute__ ((common)); | 
|  |  | 
|  | extern void __tsan_acquire(void*); | 
|  | extern void __tsan_release(void*); | 
|  |  | 
|  | __attribute__ ((unused)) | 
|  | static void _cgo_tsan_acquire() { | 
|  | __tsan_acquire(&_cgo_sync); | 
|  | } | 
|  |  | 
|  | __attribute__ ((unused)) | 
|  | static void _cgo_tsan_release() { | 
|  | __tsan_release(&_cgo_sync); | 
|  | } | 
|  |  | 
|  | #else // !defined(CGO_TSAN) | 
|  |  | 
|  | #define _cgo_tsan_acquire() | 
|  | #define _cgo_tsan_release() | 
|  |  | 
|  | #endif // !defined(CGO_TSAN) |