OSDN Git Service

* dcrt0.cc (_dll_crt0): Fix formatting.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / dcrt0.cc
1 /* dcrt0.cc -- essentially the main() for the Cygwin dll
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4    2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 #include "winsup.h"
13 #include "miscfuncs.h"
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include "glob.h"
17 #include <ctype.h>
18 #include <locale.h>
19 #include "environ.h"
20 #include "sigproc.h"
21 #include "pinfo.h"
22 #include "cygerrno.h"
23 #define NEED_VFORK
24 #include "perprocess.h"
25 #include "path.h"
26 #include "fhandler.h"
27 #include "dtable.h"
28 #include "cygheap.h"
29 #include "child_info_magic.h"
30 #include "cygtls.h"
31 #include "shared_info.h"
32 #include "cygwin_version.h"
33 #include "dll_init.h"
34 #include "heap.h"
35 #include "tls_pbuf.h"
36 #include "exception.h"
37 #include "cygxdr.h"
38 #include "fenv.h"
39 #include "ntdll.h"
40 #include "wow64.h"
41
42 #define MAX_AT_FILE_LEVEL 10
43
44 #define PREMAIN_LEN (sizeof (user_data->premain) / sizeof (user_data->premain[0]))
45
46 extern "C" void cygwin_exit (int) __attribute__ ((noreturn));
47 extern "C" void __sinit (_reent *);
48
49 static int NO_COPY envc;
50 static char NO_COPY **envp;
51
52 bool NO_COPY jit_debug;
53
54 static void
55 do_global_dtors ()
56 {
57   void (**pfunc) () = user_data->dtors;
58   if (pfunc)
59     {
60       user_data->dtors = NULL;
61       while (*++pfunc)
62         (*pfunc) ();
63     }
64 }
65
66 static void __stdcall
67 do_global_ctors (void (**in_pfunc)(), int force)
68 {
69   if (!force && in_forkee)
70     return;             // inherit constructed stuff from parent pid
71
72   /* Run ctors backwards, so skip the first entry and find how many
73      there are, then run them. */
74
75   void (**pfunc) () = in_pfunc;
76
77   while (*++pfunc)
78     ;
79   while (--pfunc > in_pfunc)
80     (*pfunc) ();
81 }
82
83 /*
84  * Replaces @file in the command line with the contents of the file.
85  * There may be multiple @file's in a single command line
86  * A \@file is replaced with @file so that echo \@foo would print
87  * @foo and not the contents of foo.
88  */
89 static bool __stdcall
90 insert_file (char *name, char *&cmd)
91 {
92   HANDLE f;
93   DWORD size;
94   tmp_pathbuf tp;
95
96   PWCHAR wname = tp.w_get ();
97   sys_mbstowcs (wname, NT_MAX_PATH, name + 1);
98   f = CreateFileW (wname,
99                    GENERIC_READ,                /* open for reading     */
100                    FILE_SHARE_VALID_FLAGS,      /* share for reading    */
101                    &sec_none_nih,               /* default security     */
102                    OPEN_EXISTING,               /* existing file only   */
103                    FILE_ATTRIBUTE_NORMAL,       /* normal file          */
104                    NULL);                       /* no attr. template    */
105
106   if (f == INVALID_HANDLE_VALUE)
107     {
108       debug_printf ("couldn't open file '%s', %E", name);
109       return false;
110     }
111
112   /* This only supports files up to about 4 billion bytes in
113      size.  I am making the bold assumption that this is big
114      enough for this feature */
115   size = GetFileSize (f, NULL);
116   if (size == 0xFFFFFFFF)
117     {
118       debug_printf ("couldn't get file size for '%s', %E", name);
119       return false;
120     }
121
122   int new_size = strlen (cmd) + size + 2;
123   char *tmp = (char *) malloc (new_size);
124   if (!tmp)
125     {
126       debug_printf ("malloc failed, %E");
127       return false;
128     }
129
130   /* realloc passed as it should */
131   DWORD rf_read;
132   BOOL rf_result;
133   rf_result = ReadFile (f, tmp, size, &rf_read, NULL);
134   CloseHandle (f);
135   if (!rf_result || (rf_read != size))
136     {
137       debug_printf ("ReadFile failed, %E");
138       return false;
139     }
140
141   tmp[size++] = ' ';
142   strcpy (tmp + size, cmd);
143   cmd = tmp;
144   return true;
145 }
146
147 static inline int
148 isquote (char c)
149 {
150   char ch = c;
151   return ch == '"' || ch == '\'';
152 }
153
154 /* Step over a run of characters delimited by quotes */
155 static /*__inline*/ char *
156 quoted (char *cmd, int winshell)
157 {
158   char *p;
159   char quote = *cmd;
160
161   if (!winshell)
162     {
163       char *p;
164       strcpy (cmd, cmd + 1);
165       if (*(p = strechr (cmd, quote)))
166         strcpy (p, p + 1);
167       return p;
168     }
169
170   const char *s = quote == '\'' ? "'" : "\\\"";
171   /* This must have been run from a Windows shell, so preserve
172      quotes for globify to play with later. */
173   while (*cmd && *++cmd)
174     if ((p = strpbrk (cmd, s)) == NULL)
175       {
176         cmd = strchr (cmd, '\0');       // no closing quote
177         break;
178       }
179     else if (*p == '\\')
180       cmd = ++p;
181     else if (quote == '"' && p[1] == '"')
182       {
183         *p = '\\';
184         cmd = ++p;                      // a quoted quote
185       }
186     else
187       {
188         cmd = p + 1;            // point to after end
189         break;
190       }
191   return cmd;
192 }
193
194 /* Perform a glob on word if it contains wildcard characters.
195    Also quote every character between quotes to force glob to
196    treat the characters literally. */
197 static int __stdcall
198 globify (char *word, char **&argv, int &argc, int &argvlen)
199 {
200   if (*word != '~' && strpbrk (word, "?*[\"\'(){}") == NULL)
201     return 0;
202
203   int n = 0;
204   char *p, *s;
205   int dos_spec = isdrive (word);
206   if (!dos_spec && isquote (*word) && word[1] && word[2])
207     dos_spec = isdrive (word + 1);
208
209   /* We'll need more space if there are quoting characters in
210      word.  If that is the case, doubling the size of the
211      string should provide more than enough space. */
212   if (strpbrk (word, "'\""))
213     n = strlen (word);
214   char pattern[strlen (word) + ((dos_spec + 1) * n) + 1];
215
216   /* Fill pattern with characters from word, quoting any
217      characters found within quotes. */
218   for (p = pattern, s = word; *s != '\000'; s++, p++)
219     if (!isquote (*s))
220       {
221         if (dos_spec && *s == '\\')
222           *p++ = '\\';
223         *p = *s;
224       }
225     else
226       {
227         char quote = *s;
228         while (*++s && *s != quote)
229           {
230             if (dos_spec || *s != '\\')
231               /* nothing */;
232             else if (s[1] == quote || s[1] == '\\')
233               s++;
234             *p++ = '\\';
235             size_t cnt = isascii (*s) ? 1 : mbtowc (NULL, s, MB_CUR_MAX);
236             if (cnt <= 1 || cnt == (size_t)-1)
237               *p++ = *s;
238             else
239               {
240                 --s;
241                 while (cnt-- > 0)
242                   *p++ = *++s;
243               }
244           }
245         if (*s == quote)
246           p--;
247         if (*s == '\0')
248             break;
249       }
250
251   *p = '\0';
252
253   glob_t gl;
254   gl.gl_offs = 0;
255
256   /* Attempt to match the argument.  Return just word (minus quoting) if no match. */
257   if (glob (pattern, GLOB_TILDE | GLOB_NOCHECK | GLOB_BRACE | GLOB_QUOTE, NULL, &gl) || !gl.gl_pathc)
258     return 0;
259
260   /* Allocate enough space in argv for the matched filenames. */
261   n = argc;
262   if ((argc += gl.gl_pathc) > argvlen)
263     {
264       argvlen = argc + 10;
265       argv = (char **) realloc (argv, (1 + argvlen) * sizeof (argv[0]));
266     }
267
268   /* Copy the matched filenames to argv. */
269   char **gv = gl.gl_pathv;
270   char **av = argv + n;
271   while (*gv)
272     {
273       debug_printf ("argv[%d] = '%s'", n++, *gv);
274       *av++ = *gv++;
275     }
276
277   /* Clean up after glob. */
278   free (gl.gl_pathv);
279   return 1;
280 }
281
282 /* Build argv, argc from string passed from Windows.  */
283
284 static void __stdcall
285 build_argv (char *cmd, char **&argv, int &argc, int winshell)
286 {
287   int argvlen = 0;
288   int nesting = 0;              // monitor "nesting" from insert_file
289
290   argc = 0;
291   argvlen = 0;
292   argv = NULL;
293
294   /* Scan command line until there is nothing left. */
295   while (*cmd)
296     {
297       /* Ignore spaces */
298       if (issep (*cmd))
299         {
300           cmd++;
301           continue;
302         }
303
304       /* Found the beginning of an argument. */
305       char *word = cmd;
306       char *sawquote = NULL;
307       while (*cmd)
308         {
309           if (*cmd != '"' && (!winshell || *cmd != '\''))
310             cmd++;              // Skip over this character
311           else
312             /* Skip over characters until the closing quote */
313             {
314               sawquote = cmd;
315               cmd = quoted (cmd, winshell && argc > 0);
316             }
317           if (issep (*cmd))     // End of argument if space
318             break;
319         }
320       if (*cmd)
321         *cmd++ = '\0';          // Terminate `word'
322
323       /* Possibly look for @file construction assuming that this isn't
324          the very first argument and the @ wasn't quoted */
325       if (argc && sawquote != word && *word == '@')
326         {
327           if (++nesting > MAX_AT_FILE_LEVEL)
328             api_fatal ("Too many levels of nesting for %s", word);
329           if (insert_file (word, cmd))
330               continue;                 // There's new stuff in cmd now
331         }
332
333       /* See if we need to allocate more space for argv */
334       if (argc >= argvlen)
335         {
336           argvlen = argc + 10;
337           argv = (char **) realloc (argv, (1 + argvlen) * sizeof (argv[0]));
338         }
339
340       /* Add word to argv file after (optional) wildcard expansion. */
341       if (!winshell || !argc || !globify (word, argv, argc, argvlen))
342         {
343           debug_printf ("argv[%d] = '%s'", argc, word);
344           argv[argc++] = word;
345         }
346     }
347
348   argv[argc] = NULL;
349
350   debug_printf ("argc %d", argc);
351 }
352
353 /* sanity and sync check */
354 void __stdcall
355 check_sanity_and_sync (per_process *p)
356 {
357   /* Sanity check to make sure developers didn't change the per_process    */
358   /* struct without updating SIZEOF_PER_PROCESS [it makes them think twice */
359   /* about changing it].                                                   */
360   if (sizeof (per_process) != SIZEOF_PER_PROCESS)
361     api_fatal ("per_process sanity check failed");
362
363   /* Make sure that the app and the dll are in sync. */
364
365   /* Complain if older than last incompatible change */
366   if (p->dll_major < CYGWIN_VERSION_DLL_EPOCH)
367     api_fatal ("cygwin DLL and APP are out of sync -- DLL version mismatch %d < %d",
368                p->dll_major, CYGWIN_VERSION_DLL_EPOCH);
369
370   /* magic_biscuit != 0 if using the old style version numbering scheme.  */
371   if (p->magic_biscuit != SIZEOF_PER_PROCESS)
372     api_fatal ("Incompatible cygwin .dll -- incompatible per_process info %d != %d",
373                p->magic_biscuit, SIZEOF_PER_PROCESS);
374
375   /* Complain if incompatible API changes made */
376   if (p->api_major > cygwin_version.api_major)
377     api_fatal ("cygwin DLL and APP are out of sync -- API version mismatch %d > %d",
378                p->api_major, cygwin_version.api_major);
379
380   /* This is a kludge to work around a version of _cygwin_common_crt0
381      which overwrote the cxx_malloc field with the local DLL copy.
382      Hilarity ensues if the DLL is not loaded while the process
383      is forking. */
384   __cygwin_user_data.cxx_malloc = &default_cygwin_cxx_malloc;
385 }
386
387 child_info NO_COPY *child_proc_info = NULL;
388
389 #define CYGWIN_GUARD (PAGE_READWRITE | PAGE_GUARD)
390
391 void
392 child_info_fork::alloc_stack_hard_way (volatile char *b)
393 {
394   void *stack_ptr;
395   DWORD stacksize;
396
397   /* First check if the requested stack area is part of the user heap
398      or part of a mmapped region.  If so, we have been started from a
399      pthread with an application-provided stack, and the stack has just
400      to be used as is. */
401   if ((stacktop >= cygheap->user_heap.base
402       && stackbottom <= cygheap->user_heap.max)
403       || is_mmapped_region ((caddr_t) stacktop, (caddr_t) stackbottom))
404     return;
405
406   /* First, try to reserve the entire stack. */
407   stacksize = (char *) stackbottom - (char *) stackaddr;
408   if (!VirtualAlloc (stackaddr, stacksize, MEM_RESERVE, PAGE_NOACCESS))
409     api_fatal ("fork: can't reserve memory for stack %p - %p, %E",
410                stackaddr, stackbottom);
411   stacksize = (char *) stackbottom - (char *) stacktop;
412   stack_ptr = VirtualAlloc (stacktop, stacksize, MEM_COMMIT, PAGE_READWRITE);
413   if (!stack_ptr)
414     abort ("can't commit memory for stack %p(%d), %E", stacktop, stacksize);
415   if (guardsize != (size_t) -1)
416     {
417       /* Allocate PAGE_GUARD page if it still fits. */
418       if (stack_ptr > stackaddr)
419         {
420           stack_ptr = (void *) ((LPBYTE) stack_ptr
421                                         - wincap.page_size ());
422           if (!VirtualAlloc (stack_ptr, wincap.page_size (), MEM_COMMIT,
423                              CYGWIN_GUARD))
424             api_fatal ("fork: couldn't allocate new stack guard page %p, %E",
425                        stack_ptr);
426         }
427       /* Allocate POSIX guard pages. */
428       if (guardsize > 0)
429         VirtualAlloc (stackaddr, guardsize, MEM_COMMIT, PAGE_NOACCESS);
430     }
431   b[0] = '\0';
432 }
433
434 void *getstack (void *) __attribute__ ((noinline));
435 volatile char *
436 getstack (volatile char * volatile p)
437 {
438   *p ^= 1;
439   *p ^= 1;
440   return p - 4096;
441 }
442
443 /* extend the stack prior to fork longjmp */
444
445 void
446 child_info_fork::alloc_stack ()
447 {
448   volatile char * volatile esp;
449   __asm__ volatile ("movl %%esp,%0": "=r" (esp));
450   /* Make sure not to try a hard allocation if we have been forked off from
451      the main thread of a Cygwin process which has been started from a 64 bit
452      parent.  In that case the _tlsbase of the forked child is not the same
453      as the _tlsbase of the parent (== stackbottom), but only because the
454      stack of the parent has been slightly rearranged.  See comment in
455      wow64_revert_to_original_stack for details. We check here if the
456      parent stack fits into the child stack. */
457   if (_tlsbase != stackbottom
458       && (!wincap.is_wow64 ()
459           || stacktop < (char *) NtCurrentTeb ()->DeallocationStack
460           || stackbottom > _tlsbase))
461     alloc_stack_hard_way (esp);
462   else
463     {
464       char *st = (char *) stacktop - 4096;
465       while (_tlstop >= st)
466         esp = getstack (esp);
467       stackaddr = 0;
468       /* This only affects forked children of a process started from a native
469          64 bit process, but it doesn't hurt to do it unconditionally.  Fix
470          StackBase in the child to be the same as in the parent, so that the
471          computation of _my_tls is correct. */
472       _tlsbase = (char *) stackbottom;
473     }
474 }
475
476 extern "C" void
477 break_here ()
478 {
479   static int NO_COPY sent_break;
480   if (!sent_break++)
481     DebugBreak ();
482   debug_printf ("break here");
483 }
484
485 static void
486 initial_env ()
487 {
488   if (GetEnvironmentVariableA ("CYGWIN_TESTING", NULL, 0))
489     _cygwin_testing = 1;
490
491 #ifdef DEBUGGING
492   DWORD len;
493   char buf[NT_MAX_PATH];
494   if (GetEnvironmentVariableA ("CYGWIN_DEBUG", buf, sizeof (buf) - 1))
495     {
496       char buf1[NT_MAX_PATH];
497       len = GetModuleFileName (NULL, buf1, NT_MAX_PATH);
498       strlwr (buf1);
499       strlwr (buf);
500       char *p = strpbrk (buf, ":=");
501       if (!p)
502         p = (char *) "gdb.exe -nw";
503       else
504         *p++ = '\0';
505       if (strstr (buf1, buf))
506         {
507           error_start_init (p);
508           jit_debug = true;
509           try_to_debug ();
510           console_printf ("*** Sending Break.  gdb may issue spurious SIGTRAP message.\n");
511           break_here ();
512         }
513     }
514 #endif
515 }
516
517 child_info *
518 get_cygwin_startup_info ()
519 {
520   STARTUPINFO si;
521
522   GetStartupInfo (&si);
523   child_info *res = (child_info *) si.lpReserved2;
524
525   if (si.cbReserved2 < EXEC_MAGIC_SIZE || !res
526       || res->intro != PROC_MAGIC_GENERIC || res->magic != CHILD_INFO_MAGIC)
527     {
528       strace.activate (false);
529       res = NULL;
530     }
531   else
532     {
533       if ((res->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
534         multiple_cygwin_problem ("proc intro", res->intro, 0);
535       else if (res->cygheap != (void *) &_cygheap_start)
536         multiple_cygwin_problem ("cygheap base", (DWORD) res->cygheap,
537                                  (DWORD) &_cygheap_start);
538
539       unsigned should_be_cb = 0;
540       switch (res->type)
541         {
542           case _CH_FORK:
543             in_forkee = true;
544             should_be_cb = sizeof (child_info_fork);
545             /* fall through */;
546           case _CH_SPAWN:
547           case _CH_EXEC:
548             if (!should_be_cb)
549               should_be_cb = sizeof (child_info_spawn);
550             if (should_be_cb != res->cb)
551               multiple_cygwin_problem ("proc size", res->cb, should_be_cb);
552             else if (sizeof (fhandler_union) != res->fhandler_union_cb)
553               multiple_cygwin_problem ("fhandler size", res->fhandler_union_cb, sizeof (fhandler_union));
554             if (res->isstraced ())
555               {
556                 while (!being_debugged ())
557                   yield ();
558                 strace.activate (res->type == _CH_FORK);
559               }
560             break;
561           default:
562             system_printf ("unknown exec type %d", res->type);
563             /* intentionally fall through */
564           case _CH_WHOOPS:
565             res = NULL;
566             break;
567         }
568     }
569
570   return res;
571 }
572
573 #define dll_data_start &_data_start__
574 #define dll_data_end &_data_end__
575 #define dll_bss_start &_bss_start__
576 #define dll_bss_end &_bss_end__
577
578 void
579 child_info_fork::handle_fork ()
580 {
581   cygheap_fixup_in_child (false);
582   memory_init (false);
583   myself.thisproc (NULL);
584   myself->uid = cygheap->user.real_uid;
585   myself->gid = cygheap->user.real_gid;
586
587   child_copy (parent, false,
588               "dll data", dll_data_start, dll_data_end,
589               "dll bss", dll_bss_start, dll_bss_end,
590               "user heap", cygheap->user_heap.base, cygheap->user_heap.ptr,
591               NULL);
592
593   /* Do the relocations here.  These will actually likely be overwritten by the
594      below child_copy but we do them here in case there is a read-only section
595      which does not get copied by fork. */
596   _pei386_runtime_relocator (user_data);
597
598   /* step 2 now that the dll has its heap filled in, we can fill in the
599      user's data and bss since user_data is now filled out. */
600   child_copy (parent, false,
601               "data", user_data->data_start, user_data->data_end,
602               "bss", user_data->bss_start, user_data->bss_end,
603               NULL);
604
605   if (fixup_mmaps_after_fork (parent))
606     api_fatal ("recreate_mmaps_after_fork_failed");
607 }
608
609 void
610 child_info_spawn::handle_spawn ()
611 {
612   extern void fixup_lockf_after_exec ();
613   HANDLE h;
614   cygheap_fixup_in_child (true);
615   memory_init (false);
616   if (!moreinfo->myself_pinfo ||
617       !DuplicateHandle (GetCurrentProcess (), moreinfo->myself_pinfo,
618                         GetCurrentProcess (), &h, 0,
619                         FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
620     h = NULL;
621   myself.thisproc (h);
622   __argc = moreinfo->argc;
623   __argv = moreinfo->argv;
624   envp = moreinfo->envp;
625   envc = moreinfo->envc;
626   if (!dynamically_loaded)
627     cygheap->fdtab.fixup_after_exec ();
628   if (__stdin >= 0)
629     cygheap->fdtab.move_fd (__stdin, 0);
630   if (__stdout >= 0)
631     cygheap->fdtab.move_fd (__stdout, 1);
632   cygheap->user.groups.clear_supp ();
633
634   /* If we're execing we may have "inherited" a list of children forked by the
635      previous process executing under this pid.  Reattach them here so that we
636      can wait for them.  */
637   if (type == _CH_EXEC)
638     reattach_children ();
639
640   ready (true);
641
642   /* Need to do this after debug_fixup_after_fork_exec or DEBUGGING handling of
643      handles might get confused. */
644   CloseHandle (child_proc_info->parent);
645   child_proc_info->parent = NULL;
646
647   signal_fixup_after_exec ();
648   fixup_lockf_after_exec ();
649 }
650
651 /* Retrieve and store system directory for later use.  Note that the
652    directory is stored with a trailing backslash! */
653 static void
654 init_windows_system_directory ()
655 {
656   if (!windows_system_directory_length)
657     {
658       windows_system_directory_length =
659             GetSystemDirectoryW (windows_system_directory, MAX_PATH);
660       if (windows_system_directory_length == 0)
661         api_fatal ("can't find windows system directory");
662       windows_system_directory[windows_system_directory_length++] = L'\\';
663       windows_system_directory[windows_system_directory_length] = L'\0';
664
665       system_wow64_directory_length =
666         GetSystemWow64DirectoryW (system_wow64_directory, MAX_PATH);
667       if (system_wow64_directory_length)
668         {
669           system_wow64_directory[system_wow64_directory_length++] = L'\\';
670           system_wow64_directory[system_wow64_directory_length] = L'\0';
671         }
672     }
673 }
674
675 void
676 dll_crt0_0 ()
677 {
678   child_proc_info = get_cygwin_startup_info ();
679   init_windows_system_directory ();
680   init_global_security ();
681   initial_env ();
682
683   SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
684
685   lock_process::init ();
686   _impure_ptr = _GLOBAL_REENT;
687   _impure_ptr->_stdin = &_impure_ptr->__sf[0];
688   _impure_ptr->_stdout = &_impure_ptr->__sf[1];
689   _impure_ptr->_stderr = &_impure_ptr->__sf[2];
690   _impure_ptr->_current_locale = "C";
691   user_data->impure_ptr = _impure_ptr;
692   user_data->impure_ptr_ptr = &_impure_ptr;
693
694   DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
695                    GetCurrentProcess (), &hMainThread,
696                    0, false, DUPLICATE_SAME_ACCESS);
697
698   NtOpenProcessToken (NtCurrentProcess (), MAXIMUM_ALLOWED, &hProcToken);
699   set_cygwin_privileges (hProcToken);
700
701   device::init ();
702   do_global_ctors (&__CTOR_LIST__, 1);
703   cygthread::init ();
704
705   if (!child_proc_info)
706     {
707       memory_init (true);
708       /* WOW64 process?  Check if we have been started from 64 bit process
709          and if our stack is at an unusual address.  Set wow64_has_64bit_parent
710          if so.  Problem description in wow64_test_for_64bit_parent. */
711       if (wincap.is_wow64 ())
712         wow64_has_64bit_parent = wow64_test_for_64bit_parent ();
713     }
714   else
715     {
716       cygwin_user_h = child_proc_info->user_h;
717       switch (child_proc_info->type)
718         {
719           case _CH_FORK:
720             fork_info->handle_fork ();
721             break;
722           case _CH_SPAWN:
723           case _CH_EXEC:
724             spawn_info->handle_spawn ();
725             break;
726         }
727     }
728
729   user_data->threadinterface->Init ();
730
731   _cygtls::init ();
732
733   /* Initialize events */
734   events_init ();
735   tty_list::init_session ();
736
737   _main_tls = &_my_tls;
738
739   /* Initialize signal processing here, early, in the hopes that the creation
740      of a thread early in the process will cause more predictability in memory
741      layout for the main thread. */
742   if (!dynamically_loaded)
743     sigproc_init ();
744
745   debug_printf ("finished dll_crt0_0 initialization");
746 }
747
748 /* Take over from libc's crt0.o and start the application. Note the
749    various special cases when Cygwin DLL is being runtime loaded (as
750    opposed to being link-time loaded by Cygwin apps) from a non
751    cygwin app via LoadLibrary.  */
752 void
753 dll_crt0_1 (void *)
754 {
755   extern void initial_setlocale ();
756
757   if (dynamically_loaded)
758     sigproc_init ();
759
760   check_sanity_and_sync (user_data);
761
762   /* Initialize malloc and then call user_shared_initialize since it relies
763      on a functioning malloc and it's possible that the user's program may
764      have overridden malloc.  We only know about that at this stage,
765      unfortunately. */
766   malloc_init ();
767   user_shared->initialize ();
768
769 #ifdef CYGHEAP_DEBUG
770   int i = 0;
771   const int n = 2 * 1024 * 1024;
772   while (i--)
773     {
774       void *p = cmalloc (HEAP_STR, n);
775       if (p)
776         small_printf ("cmalloc returns %p\n", cmalloc (HEAP_STR, n));
777       else
778         {
779           small_printf ("total allocated %p\n", (i - 1) * n);
780           break;
781         }
782     }
783 #endif
784
785   ProtectHandle (hMainThread);
786
787   cygheap->cwd.init ();
788
789   /* Initialize pthread mainthread when not forked and it is safe to call new,
790      otherwise it is reinitalized in fixup_after_fork */
791   if (!in_forkee)
792     {
793       pthread::init_mainthread ();
794       _pei386_runtime_relocator (user_data);
795     }
796
797 #ifdef DEBUGGING
798   strace.microseconds ();
799 #endif
800
801   create_signal_arrived (); /* FIXME: move into wait_sig? */
802
803   /* Initialize debug muto, if DLL is built with --enable-debugging.
804      Need to do this before any helper threads start. */
805   debug_init ();
806
807 #ifdef NEWVFORK
808   cygheap->fdtab.vfork_child_fixup ();
809   main_vfork = vfork_storage.create ();
810 #endif
811
812   cygbench ("pre-forkee");
813   if (in_forkee)
814     {
815       /* If we've played with the stack, stacksize != 0.  That means that
816          fork() was invoked from other than the main thread.  Make sure that
817          frame pointer is referencing the new stack so that the OS knows what
818          to do when it needs to increase the size of the stack.
819
820          NOTE: Don't do anything that involves the stack until you've completed
821          this step. */
822       if (fork_info->stackaddr)
823         {
824           _tlsbase = (char *) fork_info->stackbottom;
825           _tlstop = (char *) fork_info->stacktop;
826         }
827
828       longjmp (fork_info->jmp, true);
829     }
830
831   __sinit (_impure_ptr);
832
833 #ifdef DEBUGGING
834   {
835   extern void fork_init ();
836   fork_init ();
837   }
838 #endif
839   pinfo_init (envp, envc);
840   strace.dll_info ();
841
842   /* Allocate cygheap->fdtab */
843   dtable_init ();
844
845   uinfo_init ();        /* initialize user info */
846
847   /* Connect to tty. */
848   tty::init_session ();
849
850   /* Set internal locale to the environment settings. */
851   initial_setlocale ();
852
853   if (!__argc)
854     {
855       PWCHAR wline = GetCommandLineW ();
856       size_t size = sys_wcstombs (NULL, 0, wline);
857       char *line = (char *) alloca (size);
858       sys_wcstombs (line, size, wline);
859
860       /* Scan the command line and build argv.  Expand wildcards if not
861          called from another cygwin process. */
862       build_argv (line, __argv, __argc,
863                   NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
864
865       /* Convert argv[0] to posix rules if it's currently blatantly
866          win32 style. */
867       if ((strchr (__argv[0], ':')) || (strchr (__argv[0], '\\')))
868         {
869           char *new_argv0 = (char *) malloc (NT_MAX_PATH);
870           cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, __argv[0],
871                             new_argv0, NT_MAX_PATH);
872           __argv[0] = (char *) realloc (new_argv0, strlen (new_argv0) + 1);
873         }
874     }
875
876   __argc_safe = __argc;
877   if (user_data->premain[0])
878     for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++)
879       user_data->premain[i] (__argc, __argv, user_data);
880
881   /* Set up standard fds in file descriptor table. */
882   cygheap->fdtab.stdio_init ();
883
884   /* Set up __progname for getopt error call. */
885   if (__argv[0] && (__progname = strrchr (__argv[0], '/')))
886     ++__progname;
887   else
888     __progname = __argv[0];
889   program_invocation_name = __argv[0];
890   program_invocation_short_name = __progname;
891   if (__progname)
892     {
893       char *cp = strchr (__progname, '\0') - 4;
894       if (cp > __progname && ascii_strcasematch (cp, ".exe"))
895         *cp = '\0';
896     }
897
898   (void) xdr_set_vprintf (&cygxdr_vwarnx);
899   cygwin_finished_initializing = true;
900   /* Call init of loaded dlls. */
901   dlls.init ();
902
903   /* Execute any specified "premain" functions */
904   if (user_data->premain[PREMAIN_LEN / 2])
905     for (unsigned int i = PREMAIN_LEN / 2; i < PREMAIN_LEN; i++)
906       user_data->premain[i] (__argc, __argv, user_data);
907
908   set_errno (0);
909
910   if (dynamically_loaded)
911     {
912       _setlocale_r (_REENT, LC_CTYPE, "C");
913       return;
914     }
915
916   /* Disable case-insensitive globbing */
917   ignore_case_with_glob = false;
918
919   MALLOC_CHECK;
920   cygbench (__progname);
921
922   ld_preload ();
923   /* Per POSIX set the default application locale back to "C". */
924   _setlocale_r (_REENT, LC_CTYPE, "C");
925
926   if (user_data->main)
927     {
928       /* Create a copy of Cygwin's version of __argv so that, if the user makes
929          a change to an element of argv[] it does not affect Cygwin's argv.
930          Changing the the contents of what argv[n] points to will still
931          affect Cygwin.  This is similar (but not exactly like) Linux. */
932       char *newargv[__argc + 1];
933       char **nav = newargv;
934       char **oav = __argv;
935       while ((*nav++ = *oav++) != NULL)
936         continue;
937       cygwin_exit (user_data->main (__argc, newargv, *user_data->envptr));
938     }
939   __asm__ ("                            \n\
940         .global __cygwin_exit_return    \n\
941 __cygwin_exit_return:                   \n\
942 ");
943 }
944
945 extern "C" void __stdcall
946 _dll_crt0 ()
947 {
948   /* Handle WOW64 process started from native 64 bit process.  See comment
949      in wow64_test_for_64bit_parent for a full problem description. */
950   if (wow64_has_64bit_parent && !dynamically_loaded)
951     {
952       /* Must be static since it's referenced after the stack pointers have
953          been moved. */
954       static PVOID allocationbase = 0;
955
956       /* Check if we just move the stack.  See comment in
957          wow64_revert_to_original_stack for the gory details. */
958       PVOID stackaddr = wow64_revert_to_original_stack (allocationbase);
959       if (stackaddr)
960         {
961           /* 2nd half of the stack move.  Set stack pointers to new address. */
962           __asm__ ("\n\
963                    movl  %[ADDR], %%esp \n\
964                    movl  %%esp, %%ebp   \n"
965                    : : [ADDR] "r" (stackaddr));
966           /* Now we're back on the original stack.  Free up space taken by the
967              former main thread stack and set DeallocationStack correctly. */
968           VirtualFree (NtCurrentTeb ()->DeallocationStack, 0, MEM_RELEASE);
969           NtCurrentTeb ()->DeallocationStack = allocationbase;
970         }
971       else
972         /* Fall back to respawn if wow64_revert_to_original_stack fails. */
973         wow64_respawn_process ();
974     }
975 #ifdef __i386__
976   _feinitialise ();
977 #endif
978   main_environ = user_data->envptr;
979   if (in_forkee)
980     {
981       fork_info->alloc_stack ();
982       _main_tls = &_my_tls;
983     }
984
985   _main_tls->call ((DWORD (*) (void *, void *)) dll_crt0_1, NULL);
986 }
987
988 void
989 dll_crt0 (per_process *uptr)
990 {
991   /* Set the local copy of the pointer into the user space. */
992   if (!in_forkee && uptr && uptr != user_data)
993     {
994       memcpy (user_data, uptr, per_process_overwrite);
995       *(user_data->impure_ptr_ptr) = _GLOBAL_REENT;
996     }
997   _dll_crt0 ();
998 }
999
1000 /* This must be called by anyone who uses LoadLibrary to load cygwin1.dll.
1001    You must have CYGTLS_PADSIZE bytes reserved at the bottom of the stack
1002    calling this function, and that storage must not be overwritten until you
1003    unload cygwin1.dll, as it is used for _my_tls.  It is best to load
1004    cygwin1.dll before spawning any additional threads in your process.
1005
1006    See winsup/testsuite/cygload for an example of how to use cygwin1.dll
1007    from MSVC and non-cygwin MinGW applications.  */
1008 extern "C" void
1009 cygwin_dll_init ()
1010 {
1011   static char **envp;
1012   static int _fmode;
1013
1014   user_data->magic_biscuit = sizeof (per_process);
1015
1016   user_data->envptr = &envp;
1017   user_data->fmode_ptr = &_fmode;
1018
1019   _dll_crt0 ();
1020 }
1021
1022 extern "C" void
1023 __main (void)
1024 {
1025   /* Ordering is critical here.  DLL ctors have already been
1026      run as they were being loaded, so we should stack the
1027      queued call to DLL dtors now.  */
1028   atexit (dll_global_dtors);
1029   do_global_ctors (user_data->ctors, false);
1030   /* Now we have run global ctors, register their dtors.
1031
1032      At exit, global dtors will run first, so the app can still
1033      use shared library functions while terminating; then the
1034      DLLs will be destroyed; finally newlib will shut down stdio
1035      and terminate itself.  */
1036   atexit (do_global_dtors);
1037   sig_dispatch_pending (true);
1038 }
1039
1040 void __stdcall
1041 do_exit (int status)
1042 {
1043   syscall_printf ("do_exit (%d), exit_state %d", status, exit_state);
1044
1045 #ifdef NEWVFORK
1046   vfork_save *vf = vfork_storage.val ();
1047   if (vf != NULL && vf->pid < 0)
1048     {
1049       exit_state = ES_NOT_EXITING;
1050       vf->restore_exit (status);
1051     }
1052 #endif
1053
1054   lock_process until_exit (true);
1055
1056   if (exit_state < ES_EVENTS_TERMINATE)
1057     {
1058       exit_state = ES_EVENTS_TERMINATE;
1059       events_terminate ();
1060     }
1061
1062   if (exit_state < ES_SIGNAL)
1063     {
1064       exit_state = ES_SIGNAL;
1065       signal (SIGCHLD, SIG_IGN);
1066       signal (SIGHUP, SIG_IGN);
1067       signal (SIGINT, SIG_IGN);
1068       signal (SIGQUIT, SIG_IGN);
1069     }
1070
1071   if (exit_state < ES_CLOSEALL)
1072     {
1073       exit_state = ES_CLOSEALL;
1074       close_all_files ();
1075     }
1076
1077   UINT n = (UINT) status;
1078   if (exit_state < ES_THREADTERM)
1079     {
1080       exit_state = ES_THREADTERM;
1081       cygthread::terminate ();
1082     }
1083
1084   myself->stopsig = 0;
1085
1086   if (exit_state < ES_HUP_PGRP)
1087     {
1088       exit_state = ES_HUP_PGRP;
1089       /* Kill orphaned children on group leader exit */
1090       if (myself->has_pgid_children && myself->pid == myself->pgid)
1091         {
1092           siginfo_t si = {0};
1093           si.si_signo = -SIGHUP;
1094           si.si_code = SI_KERNEL;
1095           sigproc_printf ("%d == pgrp %d, send SIG{HUP,CONT} to stopped children",
1096                           myself->pid, myself->pgid);
1097           kill_pgrp (myself->pgid, si);
1098         }
1099     }
1100
1101   if (exit_state < ES_HUP_SID)
1102     {
1103       exit_state = ES_HUP_SID;
1104       /* Kill the foreground process group on session leader exit */
1105       if (getpgrp () > 0 && myself->pid == myself->sid && real_tty_attached (myself))
1106         {
1107           tty *tp = cygwin_shared->tty[myself->ctty];
1108           sigproc_printf ("%d == sid %d, send SIGHUP to children",
1109                           myself->pid, myself->sid);
1110
1111         /* CGF FIXME: This can't be right. */
1112           if (tp->getsid () == myself->sid)
1113             tp->kill_pgrp (SIGHUP);
1114         }
1115
1116     }
1117
1118   myself.exit (n);
1119 }
1120
1121 extern "C" int
1122 cygwin_atexit (void (*fn) (void))
1123 {
1124   int res;
1125   dll *d = dlls.find ((void *) _my_tls.retaddr ());
1126   res = d ? __cxa_atexit ((void (*) (void *)) fn, NULL, d) : atexit (fn);
1127   return res;
1128 }
1129
1130 extern "C" void
1131 cygwin_exit (int n)
1132 {
1133   exit_state = ES_EXIT_STARTING;
1134   exit (n);
1135 }
1136
1137 extern "C" void
1138 _exit (int n)
1139 {
1140   do_exit (((DWORD) n & 0xff) << 8);
1141 }
1142
1143 extern "C" void cygwin_stackdump ();
1144
1145 extern "C" void
1146 vapi_fatal (const char *fmt, va_list ap)
1147 {
1148   char buf[4096];
1149   int n = __small_sprintf (buf, "%P: *** fatal error %s- ", in_forkee ? "in forked process " : "");
1150   __small_vsprintf (buf + n, fmt, ap);
1151   va_end (ap);
1152   strace.prntf (_STRACE_SYSTEM, NULL, "%s", buf);
1153
1154 #ifdef DEBUGGING
1155   try_to_debug ();
1156 #endif
1157   cygwin_stackdump ();
1158   myself.exit (__api_fatal_exit_val);
1159 }
1160
1161 extern "C" void
1162 api_fatal (const char *fmt, ...)
1163 {
1164   va_list ap;
1165
1166   va_start (ap, fmt);
1167   vapi_fatal (fmt, ap);
1168 }
1169
1170 void
1171 multiple_cygwin_problem (const char *what, unsigned magic_version, unsigned version)
1172 {
1173   if (_cygwin_testing && (strstr (what, "proc") || strstr (what, "cygheap")))
1174     {
1175       child_proc_info->type = _CH_WHOOPS;
1176       return;
1177     }
1178
1179   if (GetEnvironmentVariableA ("CYGWIN_MISMATCH_OK", NULL, 0))
1180     return;
1181
1182   if (CYGWIN_VERSION_MAGIC_VERSION (magic_version) == version)
1183     system_printf ("%s magic number mismatch detected - %p/%p", what, magic_version, version);
1184   else
1185     api_fatal ("%s mismatch detected - %p/%p.\n\
1186 This problem is probably due to using incompatible versions of the cygwin DLL.\n\
1187 Search for cygwin1.dll using the Windows Start->Find/Search facility\n\
1188 and delete all but the most recent version.  The most recent version *should*\n\
1189 reside in x:\\cygwin\\bin, where 'x' is the drive on which you have\n\
1190 installed the cygwin distribution.  Rebooting is also suggested if you\n\
1191 are unable to find another cygwin DLL.",
1192                what, magic_version, version);
1193 }
1194
1195 #ifdef DEBUGGING
1196 void __stdcall
1197 cygbench (const char *s)
1198 {
1199   if (GetEnvironmentVariableA ("CYGWIN_BENCH", NULL, 0))
1200     small_printf ("%05d ***** %s : %10d\n", GetCurrentProcessId (), s, strace.microseconds ());
1201 }
1202 #endif