Cygwin: flock: Fix overlap handling in lf_setlock() and lf_clearlock()
[newlib-cygwin.git] / winsup / cygwin / init.cc
blobce6484afff9bf66e8f99a96394f2cac496dda304
1 /* init.cc
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
7 details. */
9 #include "winsup.h"
10 #include "cygtls.h"
11 #include "ntdll.h"
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
22 static void
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. */
30 static void
31 munge_threadfunc ()
33 int i;
34 char **ebp = (char **) __builtin_frame_address (0);
35 if (!threadfunc_ix[0])
37 char **peb;
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])
44 try_to_debug ();
45 return;
49 if (threadfunc_ix[0])
51 char *threadfunc = NULL;
53 NtQueryInformationThread (NtCurrentThread (),
54 ThreadQuerySetWin32StartAddress,
55 &threadfunc, sizeof threadfunc, NULL);
56 if (!search_for || threadfunc == search_for)
58 search_for = NULL;
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);
67 void dll_crt0_0 ();
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... */
71 void *alloca_dummy;
73 extern "C" BOOL
74 dll_entry (HANDLE h, DWORD reason, void *static_load)
76 BOOL test_stack_marker;
78 switch (reason)
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));
96 dll_crt0_0 ();
97 _my_oldfunc = TlsAlloc ();
98 dll_finished_loading = true;
99 break;
100 case DLL_PROCESS_DETACH:
101 if (dynamically_loaded)
102 shared_destroy ();
103 break;
104 case DLL_THREAD_ATTACH:
105 if (dll_finished_loading)
106 munge_threadfunc ();
107 break;
108 case DLL_THREAD_DETACH:
109 if (dll_finished_loading
110 && (PVOID) &_my_tls > (PVOID) &test_stack_marker
111 && _my_tls.isinitialized ())
112 _my_tls.remove (0);
113 break;
116 return TRUE;