xref: /llvm-project/compiler-rt/test/asan/TestCases/Windows/msvc/tls_init.cpp (revision 65abcf6c0ce1315fa0404f5cd0f6b093c038794e)
1*65abcf6cSAlvin Wong // RUN: %clang_cl_asan %s -Fe%t.exe /MD
2*65abcf6cSAlvin Wong // RUN: %run %t.exe | FileCheck %s
3*65abcf6cSAlvin Wong 
4*65abcf6cSAlvin Wong // CHECK: my_thread_callback
5*65abcf6cSAlvin Wong // CHECK: ran_before_main: 1
6*65abcf6cSAlvin Wong 
7*65abcf6cSAlvin Wong #include <windows.h>
8*65abcf6cSAlvin Wong #include <stdio.h>
9*65abcf6cSAlvin Wong #include <string.h>
10*65abcf6cSAlvin Wong 
11*65abcf6cSAlvin Wong #pragma comment (lib, "dbghelp")
12*65abcf6cSAlvin Wong 
13*65abcf6cSAlvin Wong static bool ran_before_main = false;
14*65abcf6cSAlvin Wong 
15*65abcf6cSAlvin Wong extern "C" void __asan_init(void);
16*65abcf6cSAlvin Wong 
17*65abcf6cSAlvin Wong static void NTAPI /*__attribute__((no_sanitize_address))*/
my_thread_callback(PVOID module,DWORD reason,PVOID reserved)18*65abcf6cSAlvin Wong my_thread_callback(PVOID module, DWORD reason, PVOID reserved) {
19*65abcf6cSAlvin Wong   ran_before_main = true;
20*65abcf6cSAlvin Wong   static const char str[] = "my_thread_callback\n";
21*65abcf6cSAlvin Wong 
22*65abcf6cSAlvin Wong   // Fail the test if we aren't called for the expected reason or we can't write
23*65abcf6cSAlvin Wong   // stdout.
24*65abcf6cSAlvin Wong   if (reason != DLL_PROCESS_ATTACH)
25*65abcf6cSAlvin Wong     return;
26*65abcf6cSAlvin Wong   HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
27*65abcf6cSAlvin Wong   if (!out || out == INVALID_HANDLE_VALUE)
28*65abcf6cSAlvin Wong     return;
29*65abcf6cSAlvin Wong 
30*65abcf6cSAlvin Wong   DWORD written = 0;
31*65abcf6cSAlvin Wong   WriteFile(out, &str[0], sizeof(str), &written, NULL);
32*65abcf6cSAlvin Wong }
33*65abcf6cSAlvin Wong 
34*65abcf6cSAlvin Wong extern "C" {
35*65abcf6cSAlvin Wong #pragma const_seg(".CRT$XLC")
36*65abcf6cSAlvin Wong extern const PIMAGE_TLS_CALLBACK p_thread_callback;
37*65abcf6cSAlvin Wong const PIMAGE_TLS_CALLBACK p_thread_callback = my_thread_callback;
38*65abcf6cSAlvin Wong #pragma const_seg()
39*65abcf6cSAlvin Wong }
40*65abcf6cSAlvin Wong 
41*65abcf6cSAlvin Wong #ifdef _WIN64
42*65abcf6cSAlvin Wong #pragma comment(linker, "/INCLUDE:_tls_used")
43*65abcf6cSAlvin Wong #pragma comment(linker, "/INCLUDE:p_thread_callback")
44*65abcf6cSAlvin Wong #else
45*65abcf6cSAlvin Wong #pragma comment(linker, "/INCLUDE:__tls_used")
46*65abcf6cSAlvin Wong #pragma comment(linker, "/INCLUDE:_p_thread_callback")
47*65abcf6cSAlvin Wong #endif
48*65abcf6cSAlvin Wong 
main()49*65abcf6cSAlvin Wong int main() {
50*65abcf6cSAlvin Wong   printf("ran_before_main: %d\n", ran_before_main);
51*65abcf6cSAlvin Wong }
52