1*bcaeed49SFangrui Song // RUN: %clang_tsan -fno-sanitize=thread -shared -fPIC -O1 -DBUILD_SO=1 %s -o \ 2*bcaeed49SFangrui Song // RUN: %t.so && \ 3*bcaeed49SFangrui Song // RUN: %clang_tsan -O1 %s %t.so -o %t && %run %t 2>&1 | FileCheck %s 4*bcaeed49SFangrui Song // RUN: llvm-objdump -t %t | FileCheck %s --check-prefix=CHECK-DUMP 5*bcaeed49SFangrui Song // CHECK-DUMP: {{[.]preinit_array.*__local_tsan_preinit}} 6*bcaeed49SFangrui Song 7*bcaeed49SFangrui Song // SANITIZER_CAN_USE_PREINIT_ARRAY is undefined on android. 8*bcaeed49SFangrui Song // UNSUPPORTED: android 9*bcaeed49SFangrui Song 10*bcaeed49SFangrui Song // Test checks if __tsan_init is called from .preinit_array. 11*bcaeed49SFangrui Song // Without initialization from .preinit_array, __tsan_init will be called from 12*bcaeed49SFangrui Song // constructors of the binary which are called after constructors of shared 13*bcaeed49SFangrui Song // library. 14*bcaeed49SFangrui Song 15*bcaeed49SFangrui Song #include <stdio.h> 16*bcaeed49SFangrui Song 17*bcaeed49SFangrui Song #if BUILD_SO 18*bcaeed49SFangrui Song 19*bcaeed49SFangrui Song // "volatile" is needed to avoid compiler optimize-out constructors. 20*bcaeed49SFangrui Song volatile int counter = 0; 21*bcaeed49SFangrui Song volatile int lib_constructor_call = 0; 22*bcaeed49SFangrui Song volatile int tsan_init_call = 0; 23*bcaeed49SFangrui Song 24*bcaeed49SFangrui Song __attribute__ ((constructor)) LibConstructor()25*bcaeed49SFangrui Songvoid LibConstructor() { 26*bcaeed49SFangrui Song lib_constructor_call = ++counter; 27*bcaeed49SFangrui Song }; 28*bcaeed49SFangrui Song 29*bcaeed49SFangrui Song #else // BUILD_SO 30*bcaeed49SFangrui Song 31*bcaeed49SFangrui Song extern int counter; 32*bcaeed49SFangrui Song extern int lib_constructor_call; 33*bcaeed49SFangrui Song extern int tsan_init_call; 34*bcaeed49SFangrui Song 35*bcaeed49SFangrui Song volatile int bin_constructor_call = 0; 36*bcaeed49SFangrui Song 37*bcaeed49SFangrui Song __attribute__ ((constructor)) BinConstructor()38*bcaeed49SFangrui Songvoid BinConstructor() { 39*bcaeed49SFangrui Song bin_constructor_call = ++counter; 40*bcaeed49SFangrui Song }; 41*bcaeed49SFangrui Song 42*bcaeed49SFangrui Song namespace __tsan { 43*bcaeed49SFangrui Song OnInitialize()44*bcaeed49SFangrui Songvoid OnInitialize() { 45*bcaeed49SFangrui Song tsan_init_call = ++counter; 46*bcaeed49SFangrui Song } 47*bcaeed49SFangrui Song 48*bcaeed49SFangrui Song } 49*bcaeed49SFangrui Song main()50*bcaeed49SFangrui Songint main() { 51*bcaeed49SFangrui Song // CHECK: TSAN_INIT 1 52*bcaeed49SFangrui Song // CHECK: LIB_CONSTRUCTOR 2 53*bcaeed49SFangrui Song // CHECK: BIN_CONSTRUCTOR 3 54*bcaeed49SFangrui Song printf("TSAN_INIT %d\n", tsan_init_call); 55*bcaeed49SFangrui Song printf("LIB_CONSTRUCTOR %d\n", lib_constructor_call); 56*bcaeed49SFangrui Song printf("BIN_CONSTRUCTOR %d\n", bin_constructor_call); 57*bcaeed49SFangrui Song return 0; 58*bcaeed49SFangrui Song } 59*bcaeed49SFangrui Song 60*bcaeed49SFangrui Song #endif // BUILD_SO 61