1// This file is used from other tests.
2// RUN: true
3
4#include <dlfcn.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8struct MyObject;
9typedef MyObject *MyObjectRef;
10extern "C" {
11 void InitializeLibrary();
12 MyObject *ObjectCreate();
13 long ObjectRead(MyObject *);
14 void ObjectWrite(MyObject *, long);
15 void ObjectWriteAnother(MyObject *, long);
16}
17
18struct MyObject {
19 long _val;
20 long _another;
21};
22
23#if defined(USE_TSAN_CALLBACKS)
24static void *tag;
25void *(*callback_register_tag)(const char *object_type);
26void *(*callback_assign_tag)(void *addr, void *tag);
27void (*callback_read)(void *addr, void *caller_pc, void *tag);
28void (*callback_write)(void *addr, void *caller_pc, void *tag);
29#endif
30
31void InitializeLibrary() {
32#if defined(USE_TSAN_CALLBACKS)
33 callback_register_tag = (decltype(callback_register_tag))dlsym(RTLD_DEFAULT, "__tsan_external_register_tag");
34 callback_assign_tag = (decltype(callback_assign_tag))dlsym(RTLD_DEFAULT, "__tsan_external_assign_tag");
35 callback_read = (decltype(callback_read))dlsym(RTLD_DEFAULT, "__tsan_external_read");
36 callback_write = (decltype(callback_write))dlsym(RTLD_DEFAULT, "__tsan_external_write");
37 tag = callback_register_tag("MyLibrary::MyObject");
38#endif
39}
40
41MyObject *ObjectCreate() {
42 MyObject *ref = (MyObject *)malloc(size: sizeof(MyObject));
43#if defined(USE_TSAN_CALLBACKS)
44 callback_assign_tag(ref, tag);
45#endif
46 return ref;
47}
48
49long ObjectRead(MyObject *ref) {
50#if defined(USE_TSAN_CALLBACKS)
51 callback_read(ref, __builtin_return_address(0), tag);
52#endif
53 return ref->_val;
54}
55
56void ObjectWrite(MyObject *ref, long val) {
57#if defined(USE_TSAN_CALLBACKS)
58 callback_write(ref, __builtin_return_address(0), tag);
59#endif
60 ref->_val = val;
61}
62
63void ObjectWriteAnother(MyObject *ref, long val) {
64#if defined(USE_TSAN_CALLBACKS)
65 callback_write(ref, __builtin_return_address(0), tag);
66#endif
67 ref->_another = val;
68}
69

source code of compiler-rt/test/tsan/Darwin/external-lib.cpp