OSDN Git Service

* exceptions.cc (set_signal_mask): Remove useless debugging output.
[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.  First set stack pointers to
962              our new address. */
963           __asm__ ("\n\
964                    movl  %[ADDR], %%esp \n\
965                    movl  %%esp, %%ebp   \n"
966                    : : [ADDR] "r" (stackaddr));
967           /* Now we're back on the original stack.  Free up space taken by the
968              former main thread stack and... */
969           VirtualFree (NtCurrentTeb ()->DeallocationStack,
970                        0, MEM_RELEASE);
971           /* ...set DeallocationStack correctly. */
972           NtCurrentTeb ()->DeallocationStack = allocationbase;
973         }
974       else
975         /* Fall back to respawn if wow64_revert_to_original_stack fails. */
976         wow64_respawn_process ();
977     }
978 #ifdef __i386__
979   _feinitialise ();
980 #endif
981   main_environ = user_data->envptr;
982   if (in_forkee)
983     {
984       fork_info->alloc_stack ();
985       _main_tls = &_my_tls;
986     }
987
988   _main_tls->call ((DWORD (*) (void *, void *)) dll_crt0_1, NULL);
989 }
990
991 void
992 dll_crt0 (per_process *uptr)
993 {
994   /* Set the local copy of the pointer into the user space. */
995   if (!in_forkee && uptr && uptr != user_data)
996     {
997       memcpy (user_data, uptr, per_process_overwrite);
998       *(user_data->impure_ptr_ptr) = _GLOBAL_REENT;
999     }
1000   _dll_crt0 ();
1001 }
1002
1003 /* This must be called by anyone who uses LoadLibrary to load cygwin1.dll.
1004    You must have CYGTLS_PADSIZE bytes reserved at the bottom of the stack
1005    calling this function, and that storage must not be overwritten until you
1006    unload cygwin1.dll, as it is used for _my_tls.  It is best to load
1007    cygwin1.dll before spawning any additional threads in your process.
1008
1009    See winsup/testsuite/cygload for an example of how to use cygwin1.dll
1010    from MSVC and non-cygwin MinGW applications.  */
1011 extern "C" void
1012 cygwin_dll_init ()
1013 {
1014   static char **envp;
1015   static int _fmode;
1016
1017   user_data->magic_biscuit = sizeof (per_process);
1018
1019   user_data->envptr = &envp;
1020   user_data->fmode_ptr = &_fmode;
1021
1022   _dll_crt0 ();
1023 }
1024
1025 extern "C" void
1026 __main (void)
1027 {
1028   /* Ordering is critical here.  DLL ctors have already been
1029      run as they were being loaded, so we should stack the
1030      queued call to DLL dtors now.  */
1031   atexit (dll_global_dtors);
1032   do_global_ctors (user_data->ctors, false);
1033   /* Now we have run global ctors, register their dtors.
1034
1035      At exit, global dtors will run first, so the app can still
1036      use shared library functions while terminating; then the
1037      DLLs will be destroyed; finally newlib will shut down stdio
1038      and terminate itself.  */
1039   atexit (do_global_dtors);
1040   sig_dispatch_pending (true);
1041 }
1042
1043 void __stdcall
1044 do_exit (int status)
1045 {
1046   syscall_printf ("do_exit (%d), exit_state %d", status, exit_state);
1047
1048 #ifdef NEWVFORK
1049   vfork_save *vf = vfork_storage.val ();
1050   if (vf != NULL && vf->pid < 0)
1051     {
1052       exit_state = ES_NOT_EXITING;
1053       vf->restore_exit (status);
1054     }
1055 #endif
1056
1057   lock_process until_exit (true);
1058
1059   if (exit_state < ES_EVENTS_TERMINATE)
1060     {
1061       exit_state = ES_EVENTS_TERMINATE;
1062       events_terminate ();
1063     }
1064
1065   if (exit_state < ES_SIGNAL)
1066     {
1067       exit_state = ES_SIGNAL;
1068       signal (SIGCHLD, SIG_IGN);
1069       signal (SIGHUP, SIG_IGN);
1070       signal (SIGINT, SIG_IGN);
1071       signal (SIGQUIT, SIG_IGN);
1072     }
1073
1074   if (exit_state < ES_CLOSEALL)
1075     {
1076       exit_state = ES_CLOSEALL;
1077       close_all_files ();
1078     }
1079
1080   UINT n = (UINT) status;
1081   if (exit_state < ES_THREADTERM)
1082     {
1083       exit_state = ES_THREADTERM;
1084       cygthread::terminate ();
1085     }
1086
1087   myself->stopsig = 0;
1088
1089   if (exit_state < ES_HUP_PGRP)
1090     {
1091       exit_state = ES_HUP_PGRP;
1092       /* Kill orphaned children on group leader exit */
1093       if (myself->has_pgid_children && myself->pid == myself->pgid)
1094         {
1095           siginfo_t si = {0};
1096           si.si_signo = -SIGHUP;
1097           si.si_code = SI_KERNEL;
1098           sigproc_printf ("%d == pgrp %d, send SIG{HUP,CONT} to stopped children",
1099                           myself->pid, myself->pgid);
1100           kill_pgrp (myself->pgid, si);
1101         }
1102     }
1103
1104   if (exit_state < ES_HUP_SID)
1105     {
1106       exit_state = ES_HUP_SID;
1107       /* Kill the foreground process group on session leader exit */
1108       if (getpgrp () > 0 && myself->pid == myself->sid && real_tty_attached (myself))
1109         {
1110           tty *tp = cygwin_shared->tty[myself->ctty];
1111           sigproc_printf ("%d == sid %d, send SIGHUP to children",
1112                           myself->pid, myself->sid);
1113
1114         /* CGF FIXME: This can't be right. */
1115           if (tp->getsid () == myself->sid)
1116             tp->kill_pgrp (SIGHUP);
1117         }
1118
1119     }
1120
1121   myself.exit (n);
1122 }
1123
1124 extern "C" int
1125 cygwin_atexit (void (*fn) (void))
1126 {
1127   int res;
1128   dll *d = dlls.find ((void *) _my_tls.retaddr ());
1129   res = d ? __cxa_atexit ((void (*) (void *)) fn, NULL, d) : atexit (fn);
1130   return res;
1131 }
1132
1133 extern "C" void
1134 cygwin_exit (int n)
1135 {
1136   exit_state = ES_EXIT_STARTING;
1137   exit (n);
1138 }
1139
1140 extern "C" void
1141 _exit (int n)
1142 {
1143   do_exit (((DWORD) n & 0xff) << 8);
1144 }
1145
1146 extern "C" void cygwin_stackdump ();
1147
1148 extern "C" void
1149 vapi_fatal (const char *fmt, va_list ap)
1150 {
1151   char buf[4096];
1152   int n = __small_sprintf (buf, "%P: *** fatal error %s- ", in_forkee ? "in forked process " : "");
1153   __small_vsprintf (buf + n, fmt, ap);
1154   va_end (ap);
1155   strace.prntf (_STRACE_SYSTEM, NULL, "%s", buf);
1156
1157 #ifdef DEBUGGING
1158   try_to_debug ();
1159 #endif
1160   cygwin_stackdump ();
1161   myself.exit (__api_fatal_exit_val);
1162 }
1163
1164 extern "C" void
1165 api_fatal (const char *fmt, ...)
1166 {
1167   va_list ap;
1168
1169   va_start (ap, fmt);
1170   vapi_fatal (fmt, ap);
1171 }
1172
1173 void
1174 multiple_cygwin_problem (const char *what, unsigned magic_version, unsigned version)
1175 {
1176   if (_cygwin_testing && (strstr (what, "proc") || strstr (what, "cygheap")))
1177     {
1178       child_proc_info->type = _CH_WHOOPS;
1179       return;
1180     }
1181
1182   if (GetEnvironmentVariableA ("CYGWIN_MISMATCH_OK", NULL, 0))
1183     return;
1184
1185   if (CYGWIN_VERSION_MAGIC_VERSION (magic_version) == version)
1186     system_printf ("%s magic number mismatch detected - %p/%p", what, magic_version, version);
1187   else
1188     api_fatal ("%s mismatch detected - %p/%p.\n\
1189 This problem is probably due to using incompatible versions of the cygwin DLL.\n\
1190 Search for cygwin1.dll using the Windows Start->Find/Search facility\n\
1191 and delete all but the most recent version.  The most recent version *should*\n\
1192 reside in x:\\cygwin\\bin, where 'x' is the drive on which you have\n\
1193 installed the cygwin distribution.  Rebooting is also suggested if you\n\
1194 are unable to find another cygwin DLL.",
1195                what, magic_version, version);
1196 }
1197
1198 #ifdef DEBUGGING
1199 void __stdcall
1200 cygbench (const char *s)
1201 {
1202   if (GetEnvironmentVariableA ("CYGWIN_BENCH", NULL, 0))
1203     small_printf ("%05d ***** %s : %10d\n", GetCurrentProcessId (), s, strace.microseconds ());
1204 }
1205 #endif