diff options
Diffstat (limited to 'test/asan/TestCases/Windows')
22 files changed, 215 insertions, 66 deletions
diff --git a/test/asan/TestCases/Windows/bind_io_completion_callback.cc b/test/asan/TestCases/Windows/bind_io_completion_callback.cc index 44b92ab914655..ef7e45867ede0 100644 --- a/test/asan/TestCases/Windows/bind_io_completion_callback.cc +++ b/test/asan/TestCases/Windows/bind_io_completion_callback.cc @@ -1,11 +1,6 @@ // Make sure we can throw exceptions from work items executed via // BindIoCompletionCallback. // -// Clang doesn't support exceptions on Windows yet, so for the time being we -// build this program in two parts: the code with exceptions is built with CL, -// the rest is built with Clang. This represents the typical scenario when we -// build a large project using "clang-cl -fallback -fsanitize=address". -// // RUN: %clangxx_asan %s -o %t.exe // RUN: %run %t.exe 2>&1 | FileCheck %s diff --git a/test/asan/TestCases/Windows/coverage-dll-stdio.cc b/test/asan/TestCases/Windows/coverage-dll-stdio.cc new file mode 100644 index 0000000000000..5e12e38554499 --- /dev/null +++ b/test/asan/TestCases/Windows/coverage-dll-stdio.cc @@ -0,0 +1,16 @@ +// Test that coverage and MSVC CRT stdio work from a DLL. This ensures that the +// __local_stdio_printf_options function isn't instrumented for coverage. + +// RUN: rm -rf %t && mkdir %t && cd %t +// RUN: %clang_cl_asan -fsanitize-coverage=func -O0 %p/dll_host.cc -Fet.exe +// RUN: %clang_cl_asan -fsanitize-coverage=func -LD -O0 %s -Fet.dll +// RUN: %run ./t.exe t.dll 2>&1 | FileCheck %s + +#include <stdio.h> + +extern "C" __declspec(dllexport) +int test_function() { + printf("hello world\n"); + // CHECK: hello world + return 0; +} diff --git a/test/asan/TestCases/Windows/default_options.cc b/test/asan/TestCases/Windows/default_options.cc deleted file mode 100644 index 6e0a28f336926..0000000000000 --- a/test/asan/TestCases/Windows/default_options.cc +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clangxx_asan -O2 %s -o %t -// RUN: %run %t 2>&1 | FileCheck %s - -// FIXME: merge this with the common default_options test when we can run common -// tests on Windows. - -const char *kAsanDefaultOptions="verbosity=1 help=1"; - -extern "C" -__attribute__((no_sanitize_address)) -const char *__asan_default_options() { - // CHECK: Available flags for AddressSanitizer: - return kAsanDefaultOptions; -} - -int main() { - return 0; -} diff --git a/test/asan/TestCases/Windows/delay_dbghelp.cc b/test/asan/TestCases/Windows/delay_dbghelp.cc new file mode 100644 index 0000000000000..81cd2d389c3b4 --- /dev/null +++ b/test/asan/TestCases/Windows/delay_dbghelp.cc @@ -0,0 +1,18 @@ +// Build an executable with ASan, then extract the DLLs that it depends on. +// RUN: %clang_cl_asan %s -Fe%t.exe +// RUN: llvm-readobj -coff-imports %t.exe | grep Name: | sed -e 's/ *Name: *//' > %t +// +// Make sure the binary doesn't depend on dbghelp directly. +// RUN: not grep dbghelp.dll %t +// +// Make sure any clang_rt DLLs it depends on don't depend on dbghelp. In the +// static build, there won't be any clang_rt DLLs. +// RUN: not grep cl""ang_rt %t || \ +// RUN: grep cl""ang_rt %t | xargs which | \ +// RUN: xargs llvm-readobj -coff-imports | not grep dbghelp.dll %t + +extern "C" int puts(const char *); + +int main() { + puts("main"); +} diff --git a/test/asan/TestCases/Windows/dll_global_dead_strip.c b/test/asan/TestCases/Windows/dll_global_dead_strip.c new file mode 100644 index 0000000000000..2664f5baff6c0 --- /dev/null +++ b/test/asan/TestCases/Windows/dll_global_dead_strip.c @@ -0,0 +1,28 @@ +// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t +// +// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll +// RUN: %env_asan_opts=report_globals=2 %run %t %t.dll 2>&1 | FileCheck %s --check-prefix=NOSTRIP +// RUN: %clang_cl_asan -LD -O2 %s -Fe%t.dll -link -opt:ref +// RUN: %env_asan_opts=report_globals=2 %run %t %t.dll 2>&1 | FileCheck %s --check-prefix=STRIP + +#include <stdio.h> + +int dead_global = 42; +int live_global = 0; + +__declspec(dllexport) +int test_function() { + puts("main"); + return live_global; +} + +// Check that our global registration scheme works with MSVC's linker dead +// stripping (/OPT:REF). + +// NOSTRIP: Added Global{{.*}}name=dead_global +// NOSTRIP: Added Global{{.*}}name=live_global +// NOSTRIP: main + +// STRIP-NOT: Added Global{{.*}}name=dead_global +// STRIP: Added Global{{.*}}name=live_global +// STRIP: main diff --git a/test/asan/TestCases/Windows/dll_host.cc b/test/asan/TestCases/Windows/dll_host.cc index 71721fe29e888..6a029c96d4d8c 100644 --- a/test/asan/TestCases/Windows/dll_host.cc +++ b/test/asan/TestCases/Windows/dll_host.cc @@ -5,20 +5,41 @@ // RUN: %clang_cl_asan -O0 %s -Fe%t // // Get the list of ASan wrappers exported by the main module RTL: -// RUN: dumpbin /EXPORTS %t | grep -o "__asan_wrap[^ ]*" | grep -v @ | sort | uniq > %t.exported_wrappers +// note: The mangling decoration (i.e. @4 )is removed because calling convention +// differ from 32-bit and 64-bit. +// RUN: dumpbin /EXPORTS %t | grep -o "__asan_wrap[^ ]*" | sed -e s/@.*// > %t.exported_wrappers1 // FIXME: we should really check the other __asan exports too. -// RUN: dumpbin /EXPORTS %t | grep -o "__sanitizer_[^ ]*" | grep -v @ | sort | uniq >> %t.exported_wrappers +// RUN: dumpbin /EXPORTS %t | grep -o "__sanitizer_[^ ]*" | sed -e s/@.*// > %t.exported_wrappers2 // // Get the list of ASan wrappers imported by the DLL RTL: // [BEWARE: be really careful with the sed commands, as this test can be run // from different environemnts with different shells and seds] -// RUN: grep INTERCEPT_LIBRARY_FUNCTION %p/../../../../lib/asan/asan_win_dll_thunk.cc | grep -v define | sed -e s/.*(/__asan_wrap_/ | sed -e s/).*// | sort | uniq > %t.dll_imports -// RUN: grep "^INTERFACE_FUNCTION.*sanitizer" %p/../../../../lib/asan/asan_win_dll_thunk.cc | grep -v define | sed -e s/.*(// | sed -e s/).*// | sort | uniq >> %t.dll_imports +// RUN: grep INTERCEPT_LIBRARY_FUNCTION %p/../../../../lib/asan/asan_win_dll_thunk.cc | grep -v define | sed -e s/.*(/__asan_wrap_/ | sed -e s/).*// > %t.dll_imports1 +// RUN: grep "^INTERFACE_FUNCTION.*sanitizer" %p/../../../../lib/asan/asan_win_dll_thunk.cc | grep -v define | sed -e s/.*(// | sed -e s/).*// > %t.dll_imports2 +// +// Add functions interecepted in asan_malloc.win.cc and asan_win.cc. +// RUN: grep '[I]MPORT:' %s | sed -e 's/.*[I]MPORT: //' > %t.dll_imports3 +// IMPORT: __asan_wrap_HeapAlloc +// IMPORT: __asan_wrap_HeapFree +// IMPORT: __asan_wrap_HeapReAlloc +// IMPORT: __asan_wrap_HeapSize +// IMPORT: __asan_wrap_CreateThread +// IMPORT: __asan_wrap_RaiseException +// IMPORT: __asan_wrap_RtlRaiseException +// +// The exception handlers differ in 32-bit and 64-bit, so we ignore them: +// RUN: grep '[E]XPORT:' %s | sed -e 's/.*[E]XPORT: //' > %t.exported_wrappers3 +// EXPORT: __asan_wrap__except_handler3 +// EXPORT: __asan_wrap__except_handler4 +// EXPORT: __asan_wrap___C_specific_handler +// +// RUN: cat %t.dll_imports1 %t.dll_imports2 %t.dll_imports3 | sort | uniq > %t.dll_imports-sorted +// RUN: cat %t.exported_wrappers1 %t.exported_wrappers2 %t.exported_wrappers3 | sort | uniq > %t.exported_wrappers-sorted // // Now make sure the DLL thunk imports everything: // RUN: echo // RUN: echo "=== NOTE === If you see a mismatch below, please update asan_win_dll_thunk.cc" -// RUN: diff %t.dll_imports %t.exported_wrappers +// RUN: diff %t.dll_imports-sorted %t.exported_wrappers-sorted // REQUIRES: asan-static-runtime #include <stdio.h> diff --git a/test/asan/TestCases/Windows/dll_intercept_memchr.cc b/test/asan/TestCases/Windows/dll_intercept_memchr.cc index 1435bdc50127e..4f794a212706a 100644 --- a/test/asan/TestCases/Windows/dll_intercept_memchr.cc +++ b/test/asan/TestCases/Windows/dll_intercept_memchr.cc @@ -2,6 +2,12 @@ // RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll // RUN: not %run %t %t.dll 2>&1 | FileCheck %s +// On windows 64-bit, the memchr function is written in assembly and is not +// hookable with the interception library. There is not enough padding before +// the function and there is a short jump on the second instruction which +// doesn't not allow enough space to encode a 64-bit indirect jump. +// UNSUPPORTED: x86_64-windows + #include <string.h> extern "C" __declspec(dllexport) diff --git a/test/asan/TestCases/Windows/dll_intercept_memcpy_indirect.cc b/test/asan/TestCases/Windows/dll_intercept_memcpy_indirect.cc index c5f44df3faaf5..4e28905923cc2 100644 --- a/test/asan/TestCases/Windows/dll_intercept_memcpy_indirect.cc +++ b/test/asan/TestCases/Windows/dll_intercept_memcpy_indirect.cc @@ -24,7 +24,7 @@ int test_function() { call_memcpy(&memcpy, buff2, buff1, 6); // CHECK: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] // CHECK: WRITE of size 6 at [[ADDR]] thread T0 -// CHECK-NEXT: __asan_{{.*}}memcpy +// CHECK-NEXT: __asan_{{.*}}mem{{.*}} // CHECK-NEXT: call_memcpy // CHECK-NEXT: test_function {{.*}}dll_intercept_memcpy_indirect.cc:[[@LINE-5]] // CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame diff --git a/test/asan/TestCases/Windows/dll_operator_array_new_with_dtor_left_oob.cc b/test/asan/TestCases/Windows/dll_operator_array_new_with_dtor_left_oob.cc index 8306a737bfffa..b514c994c1dfe 100644 --- a/test/asan/TestCases/Windows/dll_operator_array_new_with_dtor_left_oob.cc +++ b/test/asan/TestCases/Windows/dll_operator_array_new_with_dtor_left_oob.cc @@ -10,7 +10,7 @@ struct C { extern "C" __declspec(dllexport) int test_function() { C *buffer = new C[42]; - buffer[-2].x = 42; + buffer[-(1 + sizeof(void*) / 4)].x = 42; // CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] // CHECK: WRITE of size 4 at [[ADDR]] thread T0 // CHECK-NEXT: test_function {{.*}}dll_operator_array_new_with_dtor_left_oob.cc:[[@LINE-3]] @@ -19,7 +19,7 @@ int test_function() { // FIXME: Currently it says "4 bytes ... left of 172-byte region", // should be "8 bytes ... left of 168-byte region", see // https://code.google.com/p/address-sanitizer/issues/detail?id=314 -// CHECK: [[ADDR]] is located {{.*}} bytes to the left of 172-byte region +// CHECK: [[ADDR]] is located {{.*}} bytes to the left of {{(172|176)}}-byte region // FIXME: Should get rid of the malloc/free frames called from the inside of // operator new/delete in DLLs when using -MT CRT. // FIXME: The operator new frame should have []. diff --git a/test/asan/TestCases/Windows/free_hook_realloc.cc b/test/asan/TestCases/Windows/free_hook_realloc.cc index 297218bf8e99f..11e8c9975cf3b 100644 --- a/test/asan/TestCases/Windows/free_hook_realloc.cc +++ b/test/asan/TestCases/Windows/free_hook_realloc.cc @@ -5,6 +5,9 @@ // FIXME: merge this with the common free_hook_realloc test when we can run // common tests on Windows. +// FIXME: Doesn't work with DLLs +// XFAIL: win32-dynamic-asan + #include <stdlib.h> #include <io.h> #include <sanitizer/allocator_interface.h> diff --git a/test/asan/TestCases/Windows/global_dead_strip.c b/test/asan/TestCases/Windows/global_dead_strip.c new file mode 100644 index 0000000000000..e68549050be6f --- /dev/null +++ b/test/asan/TestCases/Windows/global_dead_strip.c @@ -0,0 +1,23 @@ +// RUN: %clang_cl_asan /O0 %s /Fe%t.exe +// RUN: %env_asan_opts=report_globals=2 %t.exe 2>&1 | FileCheck %s --check-prefix=NOSTRIP +// RUN: %clang_cl_asan /O2 %s /Fe%t.exe -link -opt:ref +// RUN: %env_asan_opts=report_globals=2 %t.exe 2>&1 | FileCheck %s --check-prefix=STRIP + +#include <stdio.h> +int dead_global = 42; +int live_global = 0; +int main() { + puts("main"); + return live_global; +} + +// Check that our global registration scheme works with MSVC's linker dead +// stripping (/OPT:REF). + +// NOSTRIP: Added Global{{.*}}name=dead_global +// NOSTRIP: Added Global{{.*}}name=live_global +// NOSTRIP: main + +// STRIP-NOT: Added Global{{.*}}name=dead_global +// STRIP: Added Global{{.*}}name=live_global +// STRIP: main diff --git a/test/asan/TestCases/Windows/intercept_memcpy.cc b/test/asan/TestCases/Windows/intercept_memcpy.cc index 9ee984b1873db..6e45e7fc6b309 100644 --- a/test/asan/TestCases/Windows/intercept_memcpy.cc +++ b/test/asan/TestCases/Windows/intercept_memcpy.cc @@ -22,8 +22,8 @@ int main() { call_memcpy(&memcpy, buff2, buff1, 6); // CHECK: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] // CHECK: WRITE of size 6 at [[ADDR]] thread T0 -// CHECK-NEXT: __asan_{{.*}}memcpy -// CHECK-NEXT: call_memcpy +// CHECK-NEXT: __asan_{{.*}}mem{{.*}} +// CHECK-NEXT: call_mem{{.*}} // CHECK-NEXT: main {{.*}}intercept_memcpy.cc:[[@LINE-5]] // CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame // CHECK-NEXT: #0 {{.*}} main diff --git a/test/asan/TestCases/Windows/on_error_callback.cc b/test/asan/TestCases/Windows/on_error_callback.cc deleted file mode 100644 index 9e690a342b564..0000000000000 --- a/test/asan/TestCases/Windows/on_error_callback.cc +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s - -// FIXME: merge this with the common on_error_callback test when we can run -// common tests on Windows. - -#include <stdio.h> -#include <stdlib.h> - -extern "C" -void __asan_on_error() { - fprintf(stderr, "__asan_on_error called"); - fflush(0); -} - -int main() { - char *x = (char*)malloc(10 * sizeof(char)); - free(x); - return x[5]; - // CHECK: __asan_on_error called -} diff --git a/test/asan/TestCases/Windows/oom.cc b/test/asan/TestCases/Windows/oom.cc index 3475af79e6a4c..59cc7ed0e9d12 100644 --- a/test/asan/TestCases/Windows/oom.cc +++ b/test/asan/TestCases/Windows/oom.cc @@ -1,5 +1,6 @@ // RUN: %clang_cl_asan -O0 %s -Fe%t // RUN: not %run %t 2>&1 | FileCheck %s +// REQUIRES: asan-32-bits #include <malloc.h> diff --git a/test/asan/TestCases/Windows/operator_array_new_with_dtor_left_oob.cc b/test/asan/TestCases/Windows/operator_array_new_with_dtor_left_oob.cc index 63f2929bd89be..aae9d5ec82be2 100644 --- a/test/asan/TestCases/Windows/operator_array_new_with_dtor_left_oob.cc +++ b/test/asan/TestCases/Windows/operator_array_new_with_dtor_left_oob.cc @@ -8,7 +8,7 @@ struct C { int main() { C *buffer = new C[42]; - buffer[-2].x = 42; + buffer[-(1 + sizeof(void*) / 4)].x = 42; // CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] // CHECK: WRITE of size 4 at [[ADDR]] thread T0 // CHECK-NEXT: {{#0 .* main .*operator_array_new_with_dtor_left_oob.cc}}:[[@LINE-3]] @@ -16,7 +16,7 @@ int main() { // FIXME: Currently it says "4 bytes ... left of 172-byte region", // should be "8 bytes ... left of 168-byte region", see // https://code.google.com/p/address-sanitizer/issues/detail?id=314 -// CHECK: [[ADDR]] is located {{.*}} bytes to the left of 172-byte region +// CHECK: [[ADDR]] is located {{.*}} bytes to the left of {{(172|176)}}-byte region // CHECK-LABEL: allocated by thread T0 here: // FIXME: The 'operator new' frame should have []. // CHECK-NEXT: {{#0 .* operator new}} diff --git a/test/asan/TestCases/Windows/queue_user_work_item.cc b/test/asan/TestCases/Windows/queue_user_work_item.cc index 2a0b622f62185..2a8beb828ee29 100644 --- a/test/asan/TestCases/Windows/queue_user_work_item.cc +++ b/test/asan/TestCases/Windows/queue_user_work_item.cc @@ -1,11 +1,6 @@ // Make sure we can throw exceptions from work items executed via // QueueUserWorkItem. // -// Clang doesn't support exceptions on Windows yet, so for the time being we -// build this program in two parts: the code with exceptions is built with CL, -// the rest is built with Clang. This represents the typical scenario when we -// build a large project using "clang-cl -fallback -fsanitize=address". -// // RUN: %clangxx_asan %s -o %t.exe // RUN: %run %t.exe 2>&1 | FileCheck %s diff --git a/test/asan/TestCases/Windows/queue_user_work_item_report.cc b/test/asan/TestCases/Windows/queue_user_work_item_report.cc index e500a919fdaed..26bd5e09d3ebd 100644 --- a/test/asan/TestCases/Windows/queue_user_work_item_report.cc +++ b/test/asan/TestCases/Windows/queue_user_work_item_report.cc @@ -12,8 +12,6 @@ DWORD CALLBACK work_item(LPVOID) { // CHECK: AddressSanitizer: stack-buffer-underflow on address [[ADDR:0x[0-9a-f]+]] // CHECK: WRITE of size 1 at [[ADDR]] thread T1 // CHECK: {{#0 .* work_item.*queue_user_work_item_report.cc}}:[[@LINE-3]] -// CHECK: Address [[ADDR]] is located in stack of thread T1 at offset {{.*}} in frame -// CHECK: work_item SetEvent(done); return 0; } diff --git a/test/asan/TestCases/Windows/report_after_syminitialize.cc b/test/asan/TestCases/Windows/report_after_syminitialize.cc index 20bf695141798..eec50297478c0 100644 --- a/test/asan/TestCases/Windows/report_after_syminitialize.cc +++ b/test/asan/TestCases/Windows/report_after_syminitialize.cc @@ -4,6 +4,8 @@ #include <windows.h> #include <dbghelp.h> +#pragma comment(lib, "dbghelp") + int main() { // Make sure the RTL recovers from "no options enabled" dbghelp setup. SymSetOptions(0); @@ -16,8 +18,8 @@ int main() { // CHECK: ERROR: AddressSanitizer: access-violation on unknown address // CHECK: The signal is caused by a WRITE memory access. // CHECK: Hint: address points to the zero page. - // CHECK-NEXT: {{WARNING: Failed to use and restart external symbolizer}} - // CHECK-NEXT: {{WARNING: .*DbgHelp}} + // CHECK: {{WARNING: .*DbgHelp}} + // CHECK: {{WARNING: Failed to use and restart external symbolizer}} // CHECK: {{#0 0x.* in main.*report_after_syminitialize.cc:}}[[@LINE-6]] // CHECK: AddressSanitizer can not provide additional info. } diff --git a/test/asan/TestCases/Windows/shadow_conflict_32.cc b/test/asan/TestCases/Windows/shadow_conflict_32.cc new file mode 100644 index 0000000000000..7c6d94b37483c --- /dev/null +++ b/test/asan/TestCases/Windows/shadow_conflict_32.cc @@ -0,0 +1,29 @@ +// Load this DLL at the default 32-bit ASan shadow base, and test how we dump +// the process memory layout. +// REQUIRES: asan-32-bits +// +// RUN: %clang_cl_asan -DBUILD_DLL -LD %s -Fe%t_dll.dll -link -base:0x30000000 -fixed -dynamicbase:no +// RUN: %clang_cl_asan %s -Fe%t.exe -link %t_dll.lib +// RUN: not %run %t.exe 2>&1 | FileCheck %s + +#ifndef BUILD_DLL +#include <stdio.h> + +extern "C" __declspec(dllimport) int test_function(); + +int main() { + fprintf(stderr, "should have failed to initialize, DLL got loaded near 0x%p\n", + (void *)&test_function); +} + +#else +extern "C" __declspec(dllexport) int test_function() { return 0; } +#endif + +// CHECK: =={{[0-9]+}}==Shadow memory range interleaves with an existing memory mapping. ASan cannot proceed correctly. ABORTING. +// CHECK: =={{[0-9]+}}==ASan shadow was supposed to be located in the [0x2fff0000-0x3fffffff] range. +// CHECK: =={{[0-9]+}}==Dumping process modules + +// CHECK-DAG: {{0x30000000-0x300.....}} {{.*}}\shadow_conflict_32.cc.tmp_dll.dll +// CHECK-DAG: {{0x........-0x........}} {{.*}}\shadow_conflict_32.cc.tmp.exe +// CHECK-DAG: {{0x........-0x........}} {{.*}}\ntdll.dll diff --git a/test/asan/TestCases/Windows/shadow_mapping_failure.cc b/test/asan/TestCases/Windows/shadow_mapping_failure.cc index 9b83947442ed0..510f169401dc3 100644 --- a/test/asan/TestCases/Windows/shadow_mapping_failure.cc +++ b/test/asan/TestCases/Windows/shadow_mapping_failure.cc @@ -1,5 +1,6 @@ // RUN: %clang_cl_asan -O0 %s -Fe%t // RUN: not %run %t 2>&1 | FileCheck %s +// REQUIRES: asan-32-bits #include <stdio.h> diff --git a/test/asan/TestCases/Windows/tls_init.cc b/test/asan/TestCases/Windows/tls_init.cc new file mode 100644 index 0000000000000..c29c4a377834b --- /dev/null +++ b/test/asan/TestCases/Windows/tls_init.cc @@ -0,0 +1,51 @@ +// RUN: %clang_cl_asan %s -Fe%t.exe +// RUN: %run %t.exe | FileCheck %s + +// CHECK: my_thread_callback +// CHECK: ran_before_main: 1 + +#include <windows.h> +#include <stdio.h> +#include <string.h> + +#pragma comment (lib, "dbghelp") + +static bool ran_before_main = false; + +extern "C" void __asan_init(void); + +static void NTAPI /*__attribute__((no_sanitize_address))*/ +my_thread_callback(PVOID module, DWORD reason, PVOID reserved) { + ran_before_main = true; + static const char str[] = "my_thread_callback\n"; + + // Fail the test if we aren't called for the expected reason or we can't write + // stdout. + if (reason != DLL_PROCESS_ATTACH) + return; + HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); + if (!out || out == INVALID_HANDLE_VALUE) + return; + + DWORD written = 0; + WriteFile(out, &str[0], sizeof(str), &written, NULL); +} + +extern "C" { +#pragma const_seg(".CRT$XLC") +extern const PIMAGE_TLS_CALLBACK p_thread_callback; +const PIMAGE_TLS_CALLBACK p_thread_callback = my_thread_callback; +#pragma const_seg() +} + +#ifdef _WIN64 +#pragma comment(linker, "/INCLUDE:_tls_used") +#pragma comment(linker, "/INCLUDE:p_thread_callback") +#else +#pragma comment(linker, "/INCLUDE:__tls_used") +#pragma comment(linker, "/INCLUDE:_p_thread_callback") +#endif + +int main() { + printf("ran_before_main: %d\n", ran_before_main); +} diff --git a/test/asan/TestCases/Windows/unsymbolized.cc b/test/asan/TestCases/Windows/unsymbolized.cc index e44b4bbabb87f..5854dc56d2e99 100644 --- a/test/asan/TestCases/Windows/unsymbolized.cc +++ b/test/asan/TestCases/Windows/unsymbolized.cc @@ -20,6 +20,6 @@ int do_uaf(void) { free(x); return x[5]; // CHECK: AddressSanitizer: heap-use-after-free - // CHECK: #0 {{0x[a-f0-9]+ \(.*[\\/]unsymbolized.cc.*.exe\+0x40[a-f0-9]{4}\)}} - // CHECK: #1 {{0x[a-f0-9]+ \(.*[\\/]unsymbolized.cc.*.exe\+0x40[a-f0-9]{4}\)}} + // CHECK: #0 {{0x[a-f0-9]+ \(.*[\\/]unsymbolized.cc.*.exe\+(0x40|0x14000)[a-f0-9]{4}\)}} + // CHECK: #1 {{0x[a-f0-9]+ \(.*[\\/]unsymbolized.cc.*.exe\+(0x40|0x14000)[a-f0-9]{4}\)}} } |