diff options
| author | Vitaly Buka <vitalybuka@google.com> | 2016-05-26 17:05:36 +0000 |
|---|---|---|
| committer | Vitaly Buka <vitalybuka@google.com> | 2016-05-26 17:05:36 +0000 |
| commit | 132639120a20dd8be79c274b674361a5a6bbf53d (patch) | |
| tree | 4d894fa1f2d9e49e076da7060f06757c8f64e074 | |
| parent | 49e9a8123676041262c59ca1d28c42424b2c4c55 (diff) | |
| download | bcm5719-llvm-132639120a20dd8be79c274b674361a5a6bbf53d.tar.gz bcm5719-llvm-132639120a20dd8be79c274b674361a5a6bbf53d.zip | |
Init tsan with .preinit_array section
Summary: Some libraries, like OpenSSL, runs code from .init section.
Reviewers: kcc, eugenis
Subscribers: kubabrecka, llvm-commits
Differential Revision: http://reviews.llvm.org/D20646
llvm-svn: 270873
| -rw-r--r-- | compiler-rt/lib/tsan/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_preinit.cc | 27 | ||||
| -rw-r--r-- | compiler-rt/test/tsan/Linux/check_preinit.cc | 60 |
3 files changed, 93 insertions, 5 deletions
diff --git a/compiler-rt/lib/tsan/CMakeLists.txt b/compiler-rt/lib/tsan/CMakeLists.txt index cf5a42b8c96..7c533fbff05 100644 --- a/compiler-rt/lib/tsan/CMakeLists.txt +++ b/compiler-rt/lib/tsan/CMakeLists.txt @@ -25,24 +25,25 @@ append_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors set(TSAN_SOURCES rtl/tsan_clock.cc rtl/tsan_debugging.cc - rtl/tsan_flags.cc rtl/tsan_fd.cc + rtl/tsan_flags.cc rtl/tsan_ignoreset.cc rtl/tsan_interceptors.cc + rtl/tsan_interface.cc rtl/tsan_interface_ann.cc rtl/tsan_interface_atomic.cc - rtl/tsan_interface.cc rtl/tsan_interface_java.cc rtl/tsan_malloc_mac.cc rtl/tsan_md5.cc rtl/tsan_mman.cc rtl/tsan_mutex.cc rtl/tsan_mutexset.cc + rtl/tsan_preinit.cc rtl/tsan_report.cc rtl/tsan_rtl.cc rtl/tsan_rtl_mutex.cc - rtl/tsan_rtl_report.cc rtl/tsan_rtl_proc.cc + rtl/tsan_rtl_report.cc rtl/tsan_rtl_thread.cc rtl/tsan_stack_trace.cc rtl/tsan_stat.cc @@ -117,7 +118,7 @@ if(APPLE) RTUbsan CFLAGS ${TSAN_RTL_CFLAGS} PARENT_TARGET tsan) - add_compiler_rt_object_libraries(RTTsan_dynamic + add_compiler_rt_object_libraries(RTTsan_dynamic OS ${TSAN_SUPPORTED_OS} ARCHS ${TSAN_SUPPORTED_ARCH} SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES} @@ -197,7 +198,7 @@ add_dependencies(compiler-rt tsan) # FreeBSD does not install a number of Clang-provided headers for the compiler # in the base system due to incompatibilities between FreeBSD's and Clang's # versions. As a workaround do not use --sysroot=. on FreeBSD until this is -# addressed. +# addressed. if(COMPILER_RT_HAS_SYSROOT_FLAG AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD") file(GLOB _tsan_generic_sources rtl/tsan*) file(GLOB _tsan_platform_sources rtl/tsan*posix* rtl/tsan*mac* diff --git a/compiler-rt/lib/tsan/rtl/tsan_preinit.cc b/compiler-rt/lib/tsan/rtl/tsan_preinit.cc new file mode 100644 index 00000000000..a96618d7dc8 --- /dev/null +++ b/compiler-rt/lib/tsan/rtl/tsan_preinit.cc @@ -0,0 +1,27 @@ +//===-- tsan_preinit.cc ---------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of ThreadSanitizer. +// +// Call __tsan_init at the very early stage of process startup. +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_internal_defs.h" +#include "tsan_interface.h" + +#if SANITIZER_CAN_USE_PREINIT_ARRAY + +// The symbol is called __local_tsan_preinit, because it's not intended to be +// exported. +// This code linked into the main executable when -fsanitize=thread is in +// the link flags. It can only use exported interface functions. +__attribute__((section(".preinit_array"), used)) +void (*__local_tsan_preinit)(void) = __tsan_init; + +#endif diff --git a/compiler-rt/test/tsan/Linux/check_preinit.cc b/compiler-rt/test/tsan/Linux/check_preinit.cc new file mode 100644 index 00000000000..8f5bf403376 --- /dev/null +++ b/compiler-rt/test/tsan/Linux/check_preinit.cc @@ -0,0 +1,60 @@ +// RUN: %clang_tsan -fno-sanitize=thread -shared -fPIC -O1 -DBUILD_SO=1 %s -o \ +// RUN: %t.so && \ +// RUN: %clang_tsan -O1 %s %t.so -o %t && %run %t 2>&1 | FileCheck %s +// RUN: llvm-objdump -t %t | FileCheck %s --check-prefix=CHECK-DUMP +// CHECK-DUMP: {{[.]preinit_array.*__local_tsan_preinit}} + +// SANITIZER_CAN_USE_PREINIT_ARRAY is undefined on android. +// UNSUPPORTED: android + +// Test checks if __tsan_init is called from .preinit_array. +// Without initialization from .preinit_array, __tsan_init will be called from +// constructors of the binary which are called after constructors of shared +// library. + +#include <stdio.h> + +#if BUILD_SO + +// "volatile" is needed to avoid compiler optimize-out constructors. +volatile int counter = 0; +volatile int lib_constructor_call = 0; +volatile int tsan_init_call = 0; + +__attribute__ ((constructor)) +void LibConstructor() { + lib_constructor_call = ++counter; +}; + +#else // BUILD_SO + +extern int counter; +extern int lib_constructor_call; +extern int tsan_init_call; + +volatile int bin_constructor_call = 0; + +__attribute__ ((constructor)) +void BinConstructor() { + bin_constructor_call = ++counter; +}; + +namespace __tsan { + +void OnInitialize() { + tsan_init_call = ++counter; +} + +} + +int main() { + // CHECK: TSAN_INIT 1 + // CHECK: LIB_CONSTRUCTOR 2 + // CHECK: BIN_CONSTRUCTOR 3 + printf("TSAN_INIT %d\n", tsan_init_call); + printf("LIB_CONSTRUCTOR %d\n", lib_constructor_call); + printf("BIN_CONSTRUCTOR %d\n", bin_constructor_call); + return 0; +} + +#endif // BUILD_SO |

