...
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
13typedef uint32_t uint32;
14typedef uint64_t uint64;
15typedef 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 */
22typedef struct G G;
23struct 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 */
33typedef struct ThreadStart ThreadStart;
34struct 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 */
46extern void (*_cgo_thread_start)(ThreadStart *ts);
47
48/*
49 * Creates a new operating system thread without updating any Go state
50 * (OS dependent).
51 */
52extern void (*_cgo_sys_thread_create)(void* (*func)(void*), void* arg);
53
54/*
55 * Indicates whether a dummy pthread per-thread variable is allocated.
56 */
57extern uintptr_t *_cgo_pthread_key_created;
58
59/*
60 * Creates the new operating system thread (OS, arch dependent).
61 */
62void _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 */
69uintptr_t _cgo_wait_runtime_init_done(void);
70
71/*
72 * Get the low and high boundaries of the stack.
73 */
74void x_cgo_getstackbound(uintptr bounds[2]);
75
76/*
77 * Prints error then calls abort. For linux and android.
78 */
79void fatalf(const char* format, ...) __attribute__ ((noreturn));
80
81/*
82 * Registers the current mach thread port for EXC_BAD_ACCESS processing.
83 */
84void darwin_arm_init_thread_exception_port(void);
85
86/*
87 * Starts a mach message server processing EXC_BAD_ACCESS.
88 */
89void darwin_arm_init_mach_exception_handler(void);
90
91/*
92 * The cgo traceback callback. See runtime.SetCgoTraceback.
93 */
94struct cgoTracebackArg {
95 uintptr_t Context;
96 uintptr_t SigContext;
97 uintptr_t* Buf;
98 uintptr_t Max;
99};
100extern void (*(_cgo_get_traceback_function(void)))(struct cgoTracebackArg*);
101
102/*
103 * The cgo context callback. See runtime.SetCgoTraceback.
104 */
105struct cgoContextArg {
106 uintptr_t Context;
107};
108extern void (*(_cgo_get_context_function(void)))(struct cgoContextArg*);
109
110/*
111 * The argument for the cgo symbolizer callback. See runtime.SetCgoTraceback.
112 */
113struct cgoSymbolizerArg {
114 uintptr_t PC;
115 const char* File;
116 uintptr_t Lineno;
117 const char* Func;
118 uintptr_t Entry;
119 uintptr_t More;
120 uintptr_t Data;
121};
122extern void (*(_cgo_get_symbolizer_function(void)))(struct cgoSymbolizerArg*);
123
124/*
125 * The argument for x_cgo_set_traceback_functions. See runtime.SetCgoTraceback.
126 */
127struct cgoSetTracebackFunctionsArg {
128 void (*Traceback)(struct cgoTracebackArg*);
129 void (*Context)(struct cgoContextArg*);
130 void (*Symbolizer)(struct cgoSymbolizerArg*);
131};
132
133/*
134 * TSAN support. This is only useful when building with
135 * CGO_CFLAGS="-fsanitize=thread" CGO_LDFLAGS="-fsanitize=thread" go install
136 */
137#undef CGO_TSAN
138#if defined(__has_feature)
139# if __has_feature(thread_sanitizer)
140# define CGO_TSAN
141# endif
142#elif defined(__SANITIZE_THREAD__)
143# define CGO_TSAN
144#endif
145
146#ifdef CGO_TSAN
147
148// _cgo_tsan_acquire tells C/C++ TSAN that we are acquiring a dummy lock. We
149// call this when calling from Go to C. This is necessary because TSAN cannot
150// see the synchronization in Go. Note that C/C++ code built with TSAN is not
151// the same as the Go race detector.
152//
153// cmd/cgo generates calls to _cgo_tsan_acquire and _cgo_tsan_release. For
154// other cgo calls, manual calls are required.
155//
156// These must match the definitions in yesTsanProlog in cmd/cgo/out.go.
157// In general we should call _cgo_tsan_acquire when we enter C code,
158// and call _cgo_tsan_release when we return to Go code.
159//
160// This is only necessary when calling code that might be instrumented
161// by TSAN, which mostly means system library calls that TSAN intercepts.
162//
163// See the comment in cmd/cgo/out.go for more details.
164
165long long _cgo_sync __attribute__ ((common));
166
167extern void __tsan_acquire(void*);
168extern void __tsan_release(void*);
169
170__attribute__ ((unused))
171static void _cgo_tsan_acquire() {
172 __tsan_acquire(&_cgo_sync);
173}
174
175__attribute__ ((unused))
176static void _cgo_tsan_release() {
177 __tsan_release(&_cgo_sync);
178}
179
180#else // !defined(CGO_TSAN)
181
182#define _cgo_tsan_acquire()
183#define _cgo_tsan_release()
184
185#endif // !defined(CGO_TSAN)
View as plain text