3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 #include "shared_info.h"
14 static DWORD _my_oldfunc
;
16 static char *search_for
= (char *) cygthread::stub
;
17 unsigned threadfunc_ix
[8];
19 static bool dll_finished_loading
;
20 #define OLDFUNC_OFFSET -1
23 threadfunc_fe (VOID
*arg
)
25 _cygtls::call ((DWORD (*) (void *, void *)) TlsGetValue (_my_oldfunc
), arg
);
28 /* If possible, redirect the thread entry point to a cygwin routine which
29 adds tls stuff to the stack. */
34 char **ebp
= (char **) __builtin_frame_address (0);
35 if (!threadfunc_ix
[0])
38 char **top
= (char **) NtCurrentTeb()->Tib
.StackBase
;
39 for (peb
= ebp
, i
= 0; peb
< top
&& i
< 7; peb
++)
40 if (*peb
== search_for
)
41 threadfunc_ix
[i
++] = peb
- ebp
;
42 if (0 && !threadfunc_ix
[0])
51 char *threadfunc
= NULL
;
53 NtQueryInformationThread (NtCurrentThread (),
54 ThreadQuerySetWin32StartAddress
,
55 &threadfunc
, sizeof threadfunc
, NULL
);
56 if (!search_for
|| threadfunc
== search_for
)
59 for (i
= 0; threadfunc_ix
[i
]; i
++)
60 if (!threadfunc
|| ebp
[threadfunc_ix
[i
]] == threadfunc
)
61 ebp
[threadfunc_ix
[i
]] = (char *) threadfunc_fe
;
62 TlsSetValue (_my_oldfunc
, threadfunc
);
69 /* Non-static fake variable so GCC doesn't second-guess if we *really*
70 need the alloca'd space in the DLL_PROCESS_ATTACH case below... */
74 dll_entry (HANDLE h
, DWORD reason
, void *static_load
)
76 BOOL test_stack_marker
;
80 case DLL_PROCESS_ATTACH
:
81 init_console_handler (false);
83 cygwin_hmodule
= (HMODULE
) h
;
84 dynamically_loaded
= (static_load
== NULL
);
86 /* Starting with adding the POSIX-1.2008 per-thread locale functionality,
87 we need an initalized _REENT area even for the functions called from
88 dll_crt0_0. Most importantly, we need the _REENT->_locale pointer
89 initialized to NULL, so subsequent calls to locale-specific functions
90 will always fall back to __global_locale, rather then crash due to
91 _REENT->_locale having an arbitrary value. */
92 alloca_dummy
= alloca (__CYGTLS_PADSIZE__
);
93 ZeroMemory (alloca_dummy
, __CYGTLS_PADSIZE__
);
94 memcpy (_REENT
, _GLOBAL_REENT
, sizeof (struct _reent
));
97 _my_oldfunc
= TlsAlloc ();
98 dll_finished_loading
= true;
100 case DLL_PROCESS_DETACH
:
101 if (dynamically_loaded
)
104 case DLL_THREAD_ATTACH
:
105 if (dll_finished_loading
)
108 case DLL_THREAD_DETACH
:
109 if (dll_finished_loading
110 && (PVOID
) &_my_tls
> (PVOID
) &test_stack_marker
111 && _my_tls
.isinitialized ())