diff options
| author | Timur Iskhodzhanov <timurrrr@google.com> | 2014-06-02 14:40:07 +0000 |
|---|---|---|
| committer | Timur Iskhodzhanov <timurrrr@google.com> | 2014-06-02 14:40:07 +0000 |
| commit | b1415c46fb5859d29ebd04bf78bc542881a590e7 (patch) | |
| tree | bb6044800dd47dc7d9bf7f201695166cb1c7f9c2 | |
| parent | 82899febf07aa2cc42761102f92609a804034ba2 (diff) | |
| download | bcm5719-llvm-b1415c46fb5859d29ebd04bf78bc542881a590e7.tar.gz bcm5719-llvm-b1415c46fb5859d29ebd04bf78bc542881a590e7.zip | |
[ASan Win] Manually call __asan_init early in the DLL initialization process to avoid a null function call in cout/cerr constructors
llvm-svn: 210030
| -rw-r--r-- | compiler-rt/lib/asan/asan_dll_thunk.cc | 17 | ||||
| -rw-r--r-- | compiler-rt/test/asan/TestCases/Windows/dll_cerr.cc | 23 |
2 files changed, 39 insertions, 1 deletions
diff --git a/compiler-rt/lib/asan/asan_dll_thunk.cc b/compiler-rt/lib/asan/asan_dll_thunk.cc index 15482ba8ca3..aa27c404f4d 100644 --- a/compiler-rt/lib/asan/asan_dll_thunk.cc +++ b/compiler-rt/lib/asan/asan_dll_thunk.cc @@ -325,9 +325,24 @@ INTERCEPT_LIBRARY_FUNCTION(strnlen); INTERCEPT_LIBRARY_FUNCTION(strtol); INTERCEPT_LIBRARY_FUNCTION(wcslen); -// Must be at the end of the file due to the way INTERCEPT_HOOKS is defined. +// Must be after all the interceptor declarations due to the way INTERCEPT_HOOKS +// is defined. void InterceptHooks() { INTERCEPT_HOOKS(); } +// We want to call __asan_init before C/C++ initializers/constructors are +// executed, otherwise functions like memset might be invoked. +// For some strange reason, merely linking in asan_preinit.cc doesn't work +// as the callback is never called... Is link.exe doing something too smart? + +// In DLLs, the callbacks are expected to return 0, +// otherwise CRT initialization fails. +static int call_asan_init() { + __asan_init_v3(); + return 0; +} +#pragma section(".CRT$XIB", long, read) // NOLINT +__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = call_asan_init; + #endif // ASAN_DLL_THUNK diff --git a/compiler-rt/test/asan/TestCases/Windows/dll_cerr.cc b/compiler-rt/test/asan/TestCases/Windows/dll_cerr.cc new file mode 100644 index 00000000000..8f1a699ba80 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Windows/dll_cerr.cc @@ -0,0 +1,23 @@ +// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t +// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll +// RUN: %run %t %t.dll 2>&1 | FileCheck %s + +// Test that it works correctly even with ICF enabled. +// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll -link /OPT:REF /OPT:ICF +// RUN: %run %t %t.dll 2>&1 | FileCheck %s + +#include <iostream> + +extern "C" __declspec(dllexport) +int test_function() { + // Just make sure we can use cout. + std::cout << "All ok\n"; +// CHECK: All ok + + // This line forces a declaration of some global basic_ostream internal object that + // calls memcpy() in its constructor. This doesn't work if __asan_init is not + // called early enough. + std::cout << 42; +// CHECK: 42 + return 0; +} |

