1 // Copyright 2016 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 //go:build darwin || linux
6 
7 #include <stdint.h>
8 #include "libcgo.h"
9 
10 #ifndef __has_feature
11 #define __has_feature(x) 0
12 #endif
13 
14 #if __has_feature(memory_sanitizer)
15 #include <sanitizer/msan_interface.h>
16 #endif
17 
18 // Call the user's traceback function and then call sigtramp.
19 // The runtime signal handler will jump to this code.
20 // We do it this way so that the user's traceback function will be called
21 // by a C function with proper unwind info.
22 void
x_cgo_callers(uintptr_t sig,void * info,void * context,void (* cgoTraceback)(struct cgoTracebackArg *),uintptr_t * cgoCallers,void (* sigtramp)(uintptr_t,void *,void *))23 x_cgo_callers(uintptr_t sig, void *info, void *context, void (*cgoTraceback)(struct cgoTracebackArg*), uintptr_t* cgoCallers, void (*sigtramp)(uintptr_t, void*, void*)) {
24 	struct cgoTracebackArg arg;
25 
26 	arg.Context = 0;
27 	arg.SigContext = (uintptr_t)(context);
28 	arg.Buf = cgoCallers;
29 	arg.Max = 32; // must match len(runtime.cgoCallers)
30 
31 #if __has_feature(memory_sanitizer)
32         // This function is called directly from the signal handler.
33         // The arguments are passed in registers, so whether msan
34         // considers cgoCallers to be initialized depends on whether
35         // it considers the appropriate register to be initialized.
36         // That can cause false reports in rare cases.
37         // Explicitly unpoison the memory to avoid that.
38         // See issue #47543 for more details.
39         __msan_unpoison(&arg, sizeof arg);
40 #endif
41 
42 	_cgo_tsan_acquire();
43 	(*cgoTraceback)(&arg);
44 	_cgo_tsan_release();
45 	sigtramp(sig, info, context);
46 }
47