3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
15 #include "perprocess.h"
21 int NO_COPY dynamically_loaded;
22 static char NO_COPY *search_for = (char *) cygthread::stub;
23 unsigned threadfunc_ix[8] __attribute__((section (".cygwin_dll_common"), shared));
24 extern cygthread *hwait_sig;
26 #define OLDFUNC_OFFSET -1
29 threadfunc_fe (VOID *arg)
31 (void)__builtin_return_address(1);
32 asm volatile ("andl $-16,%%esp" ::: "%esp");
33 _cygtls::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[OLDFUNC_OFFSET]), arg);
36 /* If possible, redirect the thread entry point to a cygwin routine which
37 adds tls stuff to the stack. */
42 char **ebp = (char **) __builtin_frame_address (0);
43 if (!threadfunc_ix[0])
46 char **top = (char **) _tlsbase;
47 for (peb = ebp, i = 0; peb < top && i < 7; peb++)
48 if (*peb == search_for)
49 threadfunc_ix[i++] = peb - ebp;
50 if (0 && !threadfunc_ix[0])
59 char *threadfunc = ebp[threadfunc_ix[0]];
60 if (!search_for || threadfunc == search_for)
63 for (i = 0; threadfunc_ix[i]; i++)
64 ebp[threadfunc_ix[i]] = (char *) threadfunc_fe;
65 ((char **) _tlsbase)[OLDFUNC_OFFSET] = threadfunc;
71 respawn_wow64_process ()
74 PROCESS_BASIC_INFORMATION pbi;
77 BOOL is_wow64_proc = TRUE; /* Opt on the safe side. */
79 /* Unfortunately there's no simpler way to retrieve the
80 parent process in NT, as far as I know. Hints welcome. */
81 ret = NtQueryInformationProcess (GetCurrentProcess (),
82 ProcessBasicInformation,
85 if (ret == STATUS_SUCCESS
86 && (parent = OpenProcess (PROCESS_QUERY_INFORMATION,
88 pbi.InheritedFromUniqueProcessId)))
90 IsWow64Process (parent, &is_wow64_proc);
94 /* The parent is a real 64 bit process? Respawn! */
97 PROCESS_INFORMATION pi;
101 GetStartupInfo (&si);
102 if (!CreateProcessA (NULL, GetCommandLineA (), NULL, NULL, TRUE,
103 CREATE_DEFAULT_ERROR_MODE
104 | GetPriorityClass (GetCurrentProcess ()),
105 NULL, NULL, &si, &pi))
106 api_fatal ("Failed to create process <%s>, %E", GetCommandLineA ());
107 CloseHandle (pi.hThread);
108 if (WaitForSingleObject (pi.hProcess, INFINITE) == WAIT_FAILED)
109 api_fatal ("Waiting for process %d failed, %E", pi.dwProcessId);
110 GetExitCodeProcess (pi.hProcess, &ret);
111 CloseHandle (pi.hProcess);
116 extern void __stdcall dll_crt0_0 ();
118 HMODULE NO_COPY cygwin_hmodule;
121 extern "C" BOOL WINAPI
122 dll_entry (HANDLE h, DWORD reason, void *static_load)
124 BOOL wow64_test_stack_marker;
130 case DLL_PROCESS_ATTACH:
131 cygwin_hmodule = (HMODULE) h;
132 dynamically_loaded = (static_load == NULL);
136 /* Is the stack at an unusual address? This is, an address which
137 is in the usual space occupied by the process image, but below
138 the auto load address of DLLs?
139 Check if we're running in WOW64 on a 64 bit machine *and* are
140 spawned by a genuine 64 bit process. If so, respawn. */
141 if (wincap.is_wow64 ()
142 && &wow64_test_stack_marker >= (PBOOL) 0x400000
143 && &wow64_test_stack_marker <= (PBOOL) 0x10000000)
144 respawn_wow64_process ();
148 case DLL_PROCESS_DETACH:
150 case DLL_THREAD_ATTACH:
154 case DLL_THREAD_DETACH: