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 | |
8 | struct MyObject; |
9 | typedef MyObject *MyObjectRef; |
10 | extern "C" { |
11 | void InitializeLibrary(); |
12 | MyObject *ObjectCreate(); |
13 | long ObjectRead(MyObject *); |
14 | void ObjectWrite(MyObject *, long); |
15 | void ObjectWriteAnother(MyObject *, long); |
16 | } |
17 | |
18 | struct MyObject { |
19 | long _val; |
20 | long _another; |
21 | }; |
22 | |
23 | #if defined(USE_TSAN_CALLBACKS) |
24 | static void *tag; |
25 | void *(*callback_register_tag)(const char *object_type); |
26 | void *(*callback_assign_tag)(void *addr, void *tag); |
27 | void (*callback_read)(void *addr, void *caller_pc, void *tag); |
28 | void (*callback_write)(void *addr, void *caller_pc, void *tag); |
29 | #endif |
30 | |
31 | void 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 | |
41 | MyObject *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 | |
49 | long 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 | |
56 | void 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 | |
63 | void 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 | |