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 } 69