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