Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
1 parent
49e9a81
commit 1326391
Showing
3 changed files
with
93 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |