Skip to content

Commit

Permalink
Init tsan with .preinit_array section
Browse files Browse the repository at this point in the history
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
  • Loading branch information
vitalybuka committed May 26, 2016
1 parent 49e9a81 commit 1326391
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 5 deletions.
11 changes: 6 additions & 5 deletions compiler-rt/lib/tsan/CMakeLists.txt
Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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*
Expand Down
27 changes: 27 additions & 0 deletions 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
60 changes: 60 additions & 0 deletions 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

0 comments on commit 1326391

Please sign in to comment.