Home | History | Annotate | Download | only in cgo
      1 // Copyright 2009 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 #include <stdint.h>
      6 #include <stdlib.h>
      7 #include <stdio.h>
      8 
      9 #define nil ((void*)0)
     10 #define nelem(x) (sizeof(x)/sizeof((x)[0]))
     11 
     12 typedef uint32_t uint32;
     13 typedef uint64_t uint64;
     14 typedef uintptr_t uintptr;
     15 
     16 /*
     17  * The beginning of the per-goroutine structure,
     18  * as defined in ../pkg/runtime/runtime.h.
     19  * Just enough to edit these two fields.
     20  */
     21 typedef struct G G;
     22 struct G
     23 {
     24 	uintptr stacklo;
     25 	uintptr stackhi;
     26 };
     27 
     28 /*
     29  * Arguments to the _cgo_thread_start call.
     30  * Also known to ../pkg/runtime/runtime.h.
     31  */
     32 typedef struct ThreadStart ThreadStart;
     33 struct ThreadStart
     34 {
     35 	G *g;
     36 	uintptr *tls;
     37 	void (*fn)(void);
     38 };
     39 
     40 /*
     41  * Called by 5c/6c/8c world.
     42  * Makes a local copy of the ThreadStart and
     43  * calls _cgo_sys_thread_start(ts).
     44  */
     45 extern void (*_cgo_thread_start)(ThreadStart *ts);
     46 
     47 /*
     48  * Creates a new operating system thread without updating any Go state
     49  * (OS dependent).
     50  */
     51 extern void (*_cgo_sys_thread_create)(void* (*func)(void*), void* arg);
     52 
     53 /*
     54  * Creates the new operating system thread (OS, arch dependent).
     55  */
     56 void _cgo_sys_thread_start(ThreadStart *ts);
     57 
     58 /*
     59  * Waits for the Go runtime to be initialized (OS dependent).
     60  * If runtime.SetCgoTraceback is used to set a context function,
     61  * calls the context function and returns the context value.
     62  */
     63 uintptr_t _cgo_wait_runtime_init_done();
     64 
     65 /*
     66  * Call fn in the 6c world.
     67  */
     68 void crosscall_amd64(void (*fn)(void));
     69 
     70 /*
     71  * Call fn in the 8c world.
     72  */
     73 void crosscall_386(void (*fn)(void));
     74 
     75 /*
     76  * Prints error then calls abort. For linux and android.
     77  */
     78 void fatalf(const char* format, ...);
     79 
     80 /*
     81  * Registers the current mach thread port for EXC_BAD_ACCESS processing.
     82  */
     83 void darwin_arm_init_thread_exception_port(void);
     84 
     85 /*
     86  * Starts a mach message server processing EXC_BAD_ACCESS.
     87  */
     88 void darwin_arm_init_mach_exception_handler(void);
     89 
     90 /*
     91  * The cgo context function. See runtime.SetCgoTraceback.
     92  */
     93 struct context_arg {
     94 	uintptr_t Context;
     95 };
     96 extern void (*(_cgo_get_context_function(void)))(struct context_arg*);
     97 
     98 /*
     99  * TSAN support.  This is only useful when building with
    100  *   CGO_CFLAGS="-fsanitize=thread" CGO_LDFLAGS="-fsanitize=thread" go install
    101  */
    102 #undef CGO_TSAN
    103 #if defined(__has_feature)
    104 # if __has_feature(thread_sanitizer)
    105 #  define CGO_TSAN
    106 # endif
    107 #elif defined(__SANITIZE_THREAD__)
    108 # define CGO_TSAN
    109 #endif
    110 
    111 #ifdef CGO_TSAN
    112 
    113 // These must match the definitions in yesTsanProlog in cmd/cgo/out.go.
    114 // In general we should call _cgo_tsan_acquire when we enter C code,
    115 // and call _cgo_tsan_release when we return to Go code.
    116 // This is only necessary when calling code that might be instrumented
    117 // by TSAN, which mostly means system library calls that TSAN intercepts.
    118 // See the comment in cmd/cgo/out.go for more details.
    119 
    120 long long _cgo_sync __attribute__ ((common));
    121 
    122 extern void __tsan_acquire(void*);
    123 extern void __tsan_release(void*);
    124 
    125 __attribute__ ((unused))
    126 static void _cgo_tsan_acquire() {
    127 	__tsan_acquire(&_cgo_sync);
    128 }
    129 
    130 __attribute__ ((unused))
    131 static void _cgo_tsan_release() {
    132 	__tsan_release(&_cgo_sync);
    133 }
    134 
    135 #else // !defined(CGO_TSAN)
    136 
    137 #define _cgo_tsan_acquire()
    138 #define _cgo_tsan_release()
    139 
    140 #endif // !defined(CGO_TSAN)
    141