OSDN Git Service

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