summaryrefslogtreecommitdiffstats
path: root/src/runtime/cgo/libcgo.h
blob: af4960e7e952206a0923d4495137bb8eafeac9b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

#undef nil
#define nil ((void*)0)
#define nelem(x) (sizeof(x)/sizeof((x)[0]))

typedef uint32_t uint32;
typedef uint64_t uint64;
typedef uintptr_t uintptr;

/*
 * The beginning of the per-goroutine structure,
 * as defined in ../pkg/runtime/runtime.h.
 * Just enough to edit these two fields.
 */
typedef struct G G;
struct G
{
	uintptr stacklo;
	uintptr stackhi;
};

/*
 * Arguments to the _cgo_thread_start call.
 * Also known to ../pkg/runtime/runtime.h.
 */
typedef struct ThreadStart ThreadStart;
struct ThreadStart
{
	G *g;
	uintptr *tls;
	void (*fn)(void);
};

/*
 * Called by 5c/6c/8c world.
 * Makes a local copy of the ThreadStart and
 * calls _cgo_sys_thread_start(ts).
 */
extern void (*_cgo_thread_start)(ThreadStart *ts);

/*
 * Creates a new operating system thread without updating any Go state
 * (OS dependent).
 */
extern void (*_cgo_sys_thread_create)(void* (*func)(void*), void* arg);

/*
 * Creates the new operating system thread (OS, arch dependent).
 */
void _cgo_sys_thread_start(ThreadStart *ts);

/*
 * Waits for the Go runtime to be initialized (OS dependent).
 * If runtime.SetCgoTraceback is used to set a context function,
 * calls the context function and returns the context value.
 */
uintptr_t _cgo_wait_runtime_init_done(void);

/*
 * Call fn in the 6c world.
 */
void crosscall_amd64(void (*fn)(void), void (*setg_gcc)(void*), void *g);

/*
 * Call fn in the 8c world.
 */
void crosscall_386(void (*fn)(void));

/*
 * Prints error then calls abort. For linux and android.
 */
void fatalf(const char* format, ...);

/*
 * Registers the current mach thread port for EXC_BAD_ACCESS processing.
 */
void darwin_arm_init_thread_exception_port(void);

/*
 * Starts a mach message server processing EXC_BAD_ACCESS.
 */
void darwin_arm_init_mach_exception_handler(void);

/*
 * The cgo context function. See runtime.SetCgoTraceback.
 */
struct context_arg {
	uintptr_t Context;
};
extern void (*(_cgo_get_context_function(void)))(struct context_arg*);

/*
 * The argument for the cgo traceback callback. See runtime.SetCgoTraceback.
 */
struct cgoTracebackArg {
	uintptr_t  Context;
	uintptr_t  SigContext;
	uintptr_t* Buf;
	uintptr_t  Max;
};

/*
 * TSAN support.  This is only useful when building with
 *   CGO_CFLAGS="-fsanitize=thread" CGO_LDFLAGS="-fsanitize=thread" go install
 */
#undef CGO_TSAN
#if defined(__has_feature)
# if __has_feature(thread_sanitizer)
#  define CGO_TSAN
# endif
#elif defined(__SANITIZE_THREAD__)
# define CGO_TSAN
#endif

#ifdef CGO_TSAN

// These must match the definitions in yesTsanProlog in cmd/cgo/out.go.
// In general we should call _cgo_tsan_acquire when we enter C code,
// and call _cgo_tsan_release when we return to Go code.
// This is only necessary when calling code that might be instrumented
// by TSAN, which mostly means system library calls that TSAN intercepts.
// See the comment in cmd/cgo/out.go for more details.

long long _cgo_sync __attribute__ ((common));

extern void __tsan_acquire(void*);
extern void __tsan_release(void*);

__attribute__ ((unused))
static void _cgo_tsan_acquire() {
	__tsan_acquire(&_cgo_sync);
}

__attribute__ ((unused))
static void _cgo_tsan_release() {
	__tsan_release(&_cgo_sync);
}

#else // !defined(CGO_TSAN)

#define _cgo_tsan_acquire()
#define _cgo_tsan_release()

#endif // !defined(CGO_TSAN)