summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2016-05-26 17:05:36 +0000
committerVitaly Buka <vitalybuka@google.com>2016-05-26 17:05:36 +0000
commit132639120a20dd8be79c274b674361a5a6bbf53d (patch)
tree4d894fa1f2d9e49e076da7060f06757c8f64e074
parent49e9a8123676041262c59ca1d28c42424b2c4c55 (diff)
downloadbcm5719-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.txt11
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_preinit.cc27
-rw-r--r--compiler-rt/test/tsan/Linux/check_preinit.cc60
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
OpenPOWER on IntegriCloud