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
12typedef uint32_t uint32;
13typedef uint64_t uint64;
14typedef 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 */
21typedef struct G G;
22struct 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 */
32typedef struct ThreadStart ThreadStart;
33struct 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 */
45extern void (*_cgo_thread_start)(ThreadStart *ts);
46
47/*
48 * Creates a new operating system thread without updating any Go state
49 * (OS dependent).
50 */
51extern void (*_cgo_sys_thread_create)(void* (*func)(void*), void* arg);
52
53/*
54 * Creates the new operating system thread (OS, arch dependent).
55 */
56void _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 */
63uintptr_t _cgo_wait_runtime_init_done();
64
65/*
66 * Call fn in the 6c world.
67 */
68void crosscall_amd64(void (*fn)(void));
69
70/*
71 * Call fn in the 8c world.
72 */
73void crosscall_386(void (*fn)(void));
74
75/*
76 * Prints error then calls abort. For linux and android.
77 */
78void fatalf(const char* format, ...);
79
80/*
81 * Registers the current mach thread port for EXC_BAD_ACCESS processing.
82 */
83void darwin_arm_init_thread_exception_port(void);
84
85/*
86 * Starts a mach message server processing EXC_BAD_ACCESS.
87 */
88void darwin_arm_init_mach_exception_handler(void);
89
90/*
91 * The cgo context function. See runtime.SetCgoTraceback.
92 */
93struct context_arg {
94	uintptr_t Context;
95};
96extern 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
120long long _cgo_sync __attribute__ ((common));
121
122extern void __tsan_acquire(void*);
123extern void __tsan_release(void*);
124
125__attribute__ ((unused))
126static void _cgo_tsan_acquire() {
127	__tsan_acquire(&_cgo_sync);
128}
129
130__attribute__ ((unused))
131static 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