150
|
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(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 }
|