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*));
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 * Calls into the Go tool chain, where all registers are caller save.
78 * Called from C, it saves all callee-save registers and calls
79 * setg_gcc to set g before calling fn.
80 */
81 void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
82
83 /*
84 * Prints error then calls abort. For linux and android.
85 */
86 void fatalf(const char* format, ...) __attribute__ ((noreturn));
87
88 /*
89 * The cgo traceback callback. See runtime.SetCgoTraceback.
90 */
91 struct cgoTracebackArg {
92 uintptr_t Context;
93 uintptr_t SigContext;
94 uintptr_t* Buf;
95 uintptr_t Max;
96 };
97 extern void (*(_cgo_get_traceback_function(void)))(struct cgoTracebackArg*);
98
99 /*
100 * The cgo context callback. See runtime.SetCgoTraceback.
101 */
102 struct cgoContextArg {
103 uintptr_t Context;
104 };
105 extern void (*(_cgo_get_context_function(void)))(struct cgoContextArg*);
106
107 /*
108 * The argument for the cgo symbolizer callback. See runtime.SetCgoTraceback.
109 */
110 struct cgoSymbolizerArg {
111 uintptr_t PC;
112 const char* File;
113 uintptr_t Lineno;
114 const char* Func;
115 uintptr_t Entry;
116 uintptr_t More;
117 uintptr_t Data;
118 };
119 extern void (*(_cgo_get_symbolizer_function(void)))(struct cgoSymbolizerArg*);
120
121 /*
122 * The argument for x_cgo_set_traceback_functions. See runtime.SetCgoTraceback.
123 */
124 struct cgoSetTracebackFunctionsArg {
125 void (*Traceback)(struct cgoTracebackArg*);
126 void (*Context)(struct cgoContextArg*);
127 void (*Symbolizer)(struct cgoSymbolizerArg*);
128 };
129
130 /*
131 * TSAN support. This is only useful when building with
132 * CGO_CFLAGS="-fsanitize=thread" CGO_LDFLAGS="-fsanitize=thread" go install
133 */
134 #undef CGO_TSAN
135 #if defined(__has_feature)
136 # if __has_feature(thread_sanitizer)
137 # define CGO_TSAN
138 # endif
139 #elif defined(__SANITIZE_THREAD__)
140 # define CGO_TSAN
141 #endif
142
143 #ifdef CGO_TSAN
144
145 // _cgo_tsan_acquire tells C/C++ TSAN that we are acquiring a dummy lock. We
146 // call this when calling from Go to C. This is necessary because TSAN cannot
147 // see the synchronization in Go. Note that C/C++ code built with TSAN is not
148 // the same as the Go race detector.
149 //
150 // cmd/cgo generates calls to _cgo_tsan_acquire and _cgo_tsan_release. For
151 // other cgo calls, manual calls are required.
152 //
153 // These must match the definitions in yesTsanProlog in cmd/cgo/out.go.
154 // In general we should call _cgo_tsan_acquire when we enter C code,
155 // and call _cgo_tsan_release when we return to Go code.
156 //
157 // This is only necessary when calling code that might be instrumented
158 // by TSAN, which mostly means system library calls that TSAN intercepts.
159 //
160 // See the comment in cmd/cgo/out.go for more details.
161
162 long long _cgo_sync __attribute__ ((common));
163
164 extern void __tsan_acquire(void*);
165 extern void __tsan_release(void*);
166
167 __attribute__ ((unused))
168 static void _cgo_tsan_acquire() {
169 __tsan_acquire(&_cgo_sync);
170 }
171
172 __attribute__ ((unused))
173 static void _cgo_tsan_release() {
174 __tsan_release(&_cgo_sync);
175 }
176
177 #else // !defined(CGO_TSAN)
178
179 #define _cgo_tsan_acquire()
180 #define _cgo_tsan_release()
181
182 #endif // !defined(CGO_TSAN)
183
View as plain text