OSDN Git Service

* fhandler_process.cc: Drop unneeded includes.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / dll_init.cc
1 /* dll_init.cc
2
3    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4    2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
5
6 This software is a copyrighted work licensed under the terms of the
7 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
8 details. */
9
10 #include "winsup.h"
11 #include "cygerrno.h"
12 #include "perprocess.h"
13 #include "sync.h"
14 #include "dll_init.h"
15 #include "environ.h"
16 #include "security.h"
17 #include "path.h"
18 #include "fhandler.h"
19 #include "dtable.h"
20 #include "cygheap.h"
21 #include "pinfo.h"
22 #include "child_info.h"
23 #include "cygtls.h"
24 #include "exception.h"
25 #include <wchar.h>
26 #include <sys/reent.h>
27 #include <assert.h>
28
29 extern void __stdcall check_sanity_and_sync (per_process *);
30
31 #define fabort fork_info->abort
32
33 dll_list dlls;
34
35 muto dll_list::protect;
36
37 static bool dll_global_dtors_recorded;
38
39 /* Run destructors for all DLLs on exit. */
40 void
41 dll_global_dtors ()
42 {
43   /* Don't attempt to call destructors if we're still in fork processing
44      since that likely means fork is failing and everything will not have been
45      set up.  */
46   if (in_forkee)
47     return;
48   int recorded = dll_global_dtors_recorded;
49   dll_global_dtors_recorded = false;
50   if (recorded && dlls.start.next)
51     for (dll *d = dlls.end; d != &dlls.start; d = d->prev)
52       d->run_dtors ();
53 }
54
55 /* Run all constructors associated with a dll */
56 void
57 per_module::run_ctors ()
58 {
59   void (**pfunc)() = ctors;
60
61   /* Run ctors backwards, so skip the first entry and find how many
62     there are, then run them.  */
63
64   if (pfunc)
65     {
66       int i;
67       for (i = 1; pfunc[i]; i++);
68
69       for (int j = i - 1; j > 0; j--)
70         (pfunc[j]) ();
71     }
72 }
73
74 /* Run all destructors associated with a dll */
75 void
76 per_module::run_dtors ()
77 {
78   void (**pfunc)() = dtors;
79   while (*++pfunc)
80     (*pfunc) ();
81 }
82
83 /* Initialize an individual DLL */
84 int
85 dll::init ()
86 {
87   int ret = 1;
88
89   /* This should be a no-op.  Why didn't we just import this variable? */
90   if (!p.envptr)
91     p.envptr = &__cygwin_environ;
92   else if (*(p.envptr) != __cygwin_environ)
93     *(p.envptr) = __cygwin_environ;
94
95   /* Don't run constructors or the "main" if we've forked. */
96   if (!in_forkee)
97     {
98       /* global contructors */
99       p.run_ctors ();
100
101       /* entry point of dll (use main of per_process with null args...) */
102       if (p.main)
103         ret = p.main (0, 0, 0);
104     }
105
106   return ret;
107 }
108
109 /* Look for a dll based on name */
110 dll *
111 dll_list::operator[] (const PWCHAR name)
112 {
113   dll *d = &start;
114   while ((d = d->next) != NULL)
115     if (!wcscasecmp (name, d->name))
116       return d;
117
118   return NULL;
119 }
120
121 /* Look for a dll based on is short name only (no path) */
122 dll *
123 dll_list::find_by_modname (const PWCHAR name)
124 {
125   dll *d = &start;
126   while ((d = d->next) != NULL)
127     if (!wcscasecmp (name, d->modname))
128       return d;
129
130   return NULL;
131 }
132
133 #define RETRIES 1000
134
135 /* Allocate space for a dll struct. */
136 dll *
137 dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
138 {
139   WCHAR name[NT_MAX_PATH];
140   DWORD namelen = GetModuleFileNameW (h, name, sizeof (name));
141
142   guard (true);
143   /* Already loaded? */
144   dll *d = dlls[name];
145   if (d)
146     {
147       if (!in_forkee)
148         d->count++;     /* Yes.  Bump the usage count. */
149       else
150         {
151           if (d->p.data_start != p->data_start)
152             fabort ("data segment start: parent(%p) != child(%p)",
153                     d->p.data_start, p->data_start);
154           else if (d->p.data_end != p->data_end)
155             fabort ("data segment end: parent(%p) != child(%p)",
156                     d->p.data_end, p->data_end);
157           else if (d->p.bss_start != p->bss_start)
158             fabort ("data segment start: parent(%p) != child(%p)",
159                     d->p.bss_start, p->bss_start);
160           else if (d->p.bss_end != p->bss_end)
161             fabort ("bss segment end: parent(%p) != child(%p)",
162                     d->p.bss_end, p->bss_end);
163         }
164       d->p = p;
165     }
166   else
167     {
168       /* FIXME: Change this to new at some point. */
169       d = (dll *) cmalloc (HEAP_2_DLL, sizeof (*d) + (namelen * sizeof (*name)));
170
171       /* Now we've allocated a block of information.  Fill it in with the supplied
172          info about this DLL. */
173       d->count = 1;
174       wcscpy (d->name, name);
175       d->handle = h;
176       d->has_dtors = true;
177       d->p = p;
178       d->ndeps = 0;
179       d->deps = NULL;
180       d->modname = wcsrchr (d->name, L'\\');
181       if (d->modname)
182        d->modname++;
183       d->image_size = ((pefile*)h)->optional_hdr ()->SizeOfImage;
184       d->preferred_base = (void*) ((pefile*)h)->optional_hdr()->ImageBase;
185       d->type = type;
186       append (d);
187       if (type == DLL_LOAD)
188         loaded_dlls++;
189     }
190   guard (false);
191   assert (p->envptr != NULL);
192   return d;
193 }
194
195 void
196 dll_list::append (dll* d)
197 {
198   if (end == NULL)
199     end = &start;       /* Point to "end" of dll chain. */
200   end->next = d;        /* Standard linked list stuff. */
201   d->next = NULL;
202   d->prev = end;
203   end = d;
204 }
205
206 void dll_list::populate_deps (dll* d)
207 {
208   WCHAR wmodname[NT_MAX_PATH];
209   pefile* pef = (pefile*) d->handle;
210   PIMAGE_DATA_DIRECTORY dd = pef->idata_dir (IMAGE_DIRECTORY_ENTRY_IMPORT);
211   /* Annoyance: calling crealloc with a NULL pointer will use the
212      wrong heap and crash, so we have to replicate some code */
213   long maxdeps = 4;
214   d->deps = (dll**) cmalloc (HEAP_2_DLL, maxdeps*sizeof (dll*));
215   d->ndeps = 0;
216   for (PIMAGE_IMPORT_DESCRIPTOR id=
217         (PIMAGE_IMPORT_DESCRIPTOR) pef->rva (dd->VirtualAddress);
218       dd->Size && id->Name;
219       id++)
220     {
221       char* modname = pef->rva (id->Name);
222       sys_mbstowcs (wmodname, NT_MAX_PATH, modname);
223       if (dll* dep = find_by_modname (wmodname))
224         {
225           if (d->ndeps >= maxdeps)
226             {
227               maxdeps = 2*(1+maxdeps);
228               d->deps = (dll**) crealloc (d->deps, maxdeps*sizeof (dll*));
229             }
230           d->deps[d->ndeps++] = dep;
231         }
232     }
233
234   /* add one to differentiate no deps from unknown */
235   d->ndeps++;
236 }
237
238
239 void
240 dll_list::topsort ()
241 {
242   /* Anything to do? */
243   if (!end)
244     return;
245
246   /* make sure we have all the deps available */
247   dll* d = &start;
248   while ((d = d->next))
249     if (!d->ndeps)
250       populate_deps (d);
251
252   /* unlink head and tail pointers so the sort can rebuild the list */
253   d = start.next;
254   start.next = end = NULL;
255   topsort_visit (d, true);
256
257   /* clear node markings made by the sort */
258   d = &start;
259   while ((d = d->next))
260     {
261 #ifdef DEBUGGING
262       paranoid_printf ("%W", d->modname);
263       for (int i = 1; i < -d->ndeps; i++)
264         paranoid_printf ("-> %W", d->deps[i - 1]->modname);
265 #endif
266
267       /* It would be really nice to be able to keep this information
268          around for next time, but we don't have an easy way to
269          invalidate cached dependencies when a module unloads. */
270       d->ndeps = 0;
271       cfree (d->deps);
272       d->deps = NULL;
273     }
274 }
275
276 /* A recursive in-place topological sort. The result is ordered so that
277    dependencies of a dll appear before it in the list.
278
279    NOTE: this algorithm is guaranteed to terminate with a "partial
280    order" of dlls but does not do anything smart about cycles: an
281    arbitrary dependent dll will necessarily appear first. Perhaps not
282    surprisingly, Windows ships several dlls containing dependency
283    cycles, including SspiCli/RPCRT4.dll and a lovely tangle involving
284    USP10/LPK/GDI32/USER32.dll). Fortunately, we don't care about
285    Windows DLLs here, and cygwin dlls should behave better */
286 void
287 dll_list::topsort_visit (dll* d, bool seek_tail)
288 {
289   /* Recurse to the end of the dll chain, then visit nodes as we
290      unwind. We do this because once we start visiting nodes we can no
291      longer trust any _next_ pointers.
292
293      We "mark" visited nodes (to avoid revisiting them) by negating
294      ndeps (undone once the sort completes). */
295   if (seek_tail && d->next)
296     topsort_visit (d->next, true);
297
298   if (d->ndeps > 0)
299     {
300       d->ndeps = -d->ndeps;
301       for (long i = 1; i < -d->ndeps; i++)
302         topsort_visit (d->deps[i - 1], false);
303
304       append (d);
305     }
306 }
307
308
309 dll *
310 dll_list::find (void *retaddr)
311 {
312   MEMORY_BASIC_INFORMATION m;
313   if (!VirtualQuery (retaddr, &m, sizeof m))
314     return NULL;
315   HMODULE h = (HMODULE) m.AllocationBase;
316
317   dll *d = &start;
318   while ((d = d->next))
319     if (d->handle == h)
320       break;
321   return d;
322 }
323
324 /* Detach a DLL from the chain. */
325 void
326 dll_list::detach (void *retaddr)
327 {
328   dll *d;
329   /* Don't attempt to call destructors if we're still in fork processing
330      since that likely means fork is failing and everything will not have been
331      set up.  */
332   if (!myself || in_forkee)
333     return;
334   guard (true);
335   if ((d = find (retaddr)))
336     {
337       if (d->count <= 0)
338         system_printf ("WARNING: trying to detach an already detached dll ...");
339       if (--d->count == 0)
340         {
341           /* Ensure our exception handler is enabled for destructors */
342           exception protect;
343           /* Call finalize function if we are not already exiting */
344           if (!exit_state)
345             __cxa_finalize (d);
346           d->run_dtors ();
347           d->prev->next = d->next;
348           if (d->next)
349             d->next->prev = d->prev;
350           if (d->type == DLL_LOAD)
351             loaded_dlls--;
352           if (end == d)
353             end = d->prev;
354           cfree (d);
355         }
356     }
357   guard (false);
358 }
359
360 /* Initialization for all linked DLLs, called by dll_crt0_1. */
361 void
362 dll_list::init ()
363 {
364   /* Walk the dll chain, initializing each dll */
365   dll *d = &start;
366   dll_global_dtors_recorded = d->next != NULL;
367   while ((d = d->next))
368     d->init ();
369 }
370
371 #define A64K (64 * 1024)
372
373
374 /* Reserve the chunk of free address space starting _here_ and (usually)
375    covering at least _dll_size_ bytes. However, we must take care not
376    to clobber the dll's target address range because it often overlaps.
377  */
378 static DWORD
379 reserve_at (const PWCHAR name, DWORD here, DWORD dll_base, DWORD dll_size)
380 {
381   DWORD size;
382   MEMORY_BASIC_INFORMATION mb;
383
384   if (!VirtualQuery ((void *) here, &mb, sizeof (mb)))
385     fabort ("couldn't examine memory at %08lx while mapping %W, %E",
386             here, name);
387   if (mb.State != MEM_FREE)
388     return 0;
389
390   size = mb.RegionSize;
391
392   // don't clobber the space where we want the dll to land
393   DWORD end = here + size;
394   DWORD dll_end = dll_base + dll_size;
395   if (dll_base < here && dll_end > here)
396       here = dll_end; // the dll straddles our left edge
397   else if (dll_base >= here && dll_base < end)
398       end = dll_base; // the dll overlaps partly or fully to our right
399
400   size = end - here;
401   if (!VirtualAlloc ((void *) here, size, MEM_RESERVE, PAGE_NOACCESS))
402     fabort ("couldn't allocate memory %p(%d) for '%W' alignment, %E\n",
403             here, size, name);
404   return here;
405 }
406
407 /* Release the memory previously allocated by "reserve_at" above. */
408 static void
409 release_at (const PWCHAR name, DWORD here)
410 {
411   if (!VirtualFree ((void *) here, 0, MEM_RELEASE))
412     fabort ("couldn't release memory %p for '%W' alignment, %E\n",
413             here, name);
414 }
415
416 /* Step 1: Reserve memory for all DLL_LOAD dlls. This is to prevent
417    anything else from taking their spot as we compensate for Windows
418    randomly relocating things.
419
420    NOTE: because we can't depend on LoadLibraryExW to do the right
421    thing, we have to do a vanilla VirtualAlloc instead. One possible
422    optimization might attempt a LoadLibraryExW first, in case it lands
423    in the right place, but then we have to find a way of tracking
424    which dlls ended up needing VirtualAlloc after all.  */
425 void
426 dll_list::reserve_space ()
427 {
428   for (dll* d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
429     if (!VirtualAlloc (d->handle, d->image_size, MEM_RESERVE, PAGE_NOACCESS))
430       fabort ("address space needed by '%W' (%p) is already occupied",
431               d->modname, d->handle);
432 }
433
434 /* Reload DLLs after a fork.  Iterates over the list of dynamically loaded
435    DLLs and attempts to load them in the same place as they were loaded in the
436    parent. */
437 void
438 dll_list::load_after_fork (HANDLE parent)
439 {
440   // moved to frok::child for performance reasons:
441   // dll_list::reserve_space();
442
443   load_after_fork_impl (parent, dlls.istart (DLL_LOAD), 0);
444 }
445
446 static int const DLL_RETRY_MAX = 6;
447 void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
448 {
449   /* Step 2: For each dll which did not map at its preferred base
450      address in the parent, try to coerce it to land at the same spot
451      as before. If not, unload it, reserve the memory around it, and
452      try again. Use recursion to remember blocked regions address
453      space so we can release them later.
454
455      We DONT_RESOLVE_DLL_REFERENCES at first in case the DLL lands in
456      the wrong spot;
457
458      NOTE: This step skips DLLs which loaded at their preferred
459      address in the parent because they should behave (we already
460      verified that their preferred address in the child is
461      available). However, this may fail on a Vista/Win7 machine with
462      ASLR active, because the ASLR base address will usually not equal
463      the preferred base recorded in the dll. In this case, we should
464      make the LoadLibraryExW call unconditional.
465    */
466   for ( ; d; d = dlls.inext ())
467     if (d->handle != d->preferred_base)
468       {
469         /* See if the DLL will load in proper place. If not, unload it,
470            reserve the memory around it, and try again.
471
472            If this is the first attempt, we need to release the
473            dll's protective reservation from step 1
474          */
475         if (!retries && !VirtualFree (d->handle, 0, MEM_RELEASE))
476           fabort ("unable to release protective reservation for %W (%08lx), %E",
477                   d->modname, d->handle);
478
479         HMODULE h = LoadLibraryExW (d->name, NULL, DONT_RESOLVE_DLL_REFERENCES);
480         if (!h)
481           fabort ("unable to create interim mapping for %W, %E",
482                   d->name);
483         if (h != d->handle)
484           {
485             sigproc_printf ("%W loaded in wrong place: %08lx != %08lx",
486                             d->modname, h, d->handle);
487             FreeLibrary (h);
488             DWORD reservation = reserve_at (d->modname, (DWORD) h,
489                                             (DWORD) d->handle, d->image_size);
490             if (!reservation)
491               fabort ("unable to block off %p to prevent %W from loading there",
492                       h, d->modname);
493
494             if (retries < DLL_RETRY_MAX)
495               load_after_fork_impl (parent, d, retries+1);
496             else
497                fabort ("unable to remap %W to same address as parent (%08lx) - try running rebaseall",
498                        d->modname, d->handle);
499
500             /* once the above returns all the dlls are mapped; release
501                the reservation and continue unwinding */
502             sigproc_printf ("releasing blocked space at %08lx", reservation);
503             release_at (d->modname, reservation);
504             return;
505           }
506       }
507
508   /* Step 3: try to load each dll for real after either releasing the
509      protective reservation (for well-behaved dlls) or unloading the
510      interim mapping (for rebased dlls) . The dll list is sorted in
511      dependency order, so we shouldn't pull in any additional dlls
512      outside our control.  */
513   for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
514     {
515       if (d->handle == d->preferred_base)
516         {
517           if (!VirtualFree (d->handle, 0, MEM_RELEASE))
518             fabort ("unable to release protective reservation for %W (%08lx), %E",
519                     d->modname, d->handle);
520         }
521       else
522         {
523           /* Free the library using our parent's handle: it's identical
524              to ours or we wouldn't have gotten this far */
525           if (!FreeLibrary (d->handle))
526             fabort ("unable to unload interim mapping of %W, %E",
527                     d->modname);
528         }
529       HMODULE h = LoadLibraryW (d->name);
530       if (!h)
531         fabort ("unable to map %W, %E", d->name);
532       if (h != d->handle)
533         fabort ("unable to map %W to same address as parent: %p != %p",
534                 d->modname, d->handle, h);
535     }
536 }
537
538 struct dllcrt0_info
539 {
540   HMODULE h;
541   per_process *p;
542   int res;
543   dllcrt0_info (HMODULE h0, per_process *p0): h (h0), p (p0) {}
544 };
545
546 extern "C" int
547 dll_dllcrt0 (HMODULE h, per_process *p)
548 {
549   if (dynamically_loaded)
550     return 1;
551   dllcrt0_info x (h, p);
552   dll_dllcrt0_1 (&x);
553   return x.res;
554 }
555
556 void
557 dll_dllcrt0_1 (VOID *x)
558 {
559   HMODULE& h = ((dllcrt0_info *) x)->h;
560   per_process*& p = ((dllcrt0_info *) x)->p;
561   int& res = ((dllcrt0_info *) x)->res;
562
563   if (p == NULL)
564     p = &__cygwin_user_data;
565   else
566     {
567       *(p->impure_ptr_ptr) = __cygwin_user_data.impure_ptr;
568       _pei386_runtime_relocator (p);
569     }
570
571   bool linked = !in_forkee && !cygwin_finished_initializing;
572
573   /* Broken DLLs built against Cygwin versions 1.7.0-49 up to 1.7.0-57
574      override the cxx_malloc pointer in their DLL initialization code,
575      when loaded either statically or dynamically.  Because this leaves
576      a stale pointer into demapped memory space if the DLL is unloaded
577      by a call to dlclose, we prevent this happening for dynamically
578      loaded DLLS in dlopen by saving and restoring cxx_malloc around
579      the call to LoadLibrary, which invokes the DLL's startup sequence.
580      Modern DLLs won't even attempt to override the pointer when loaded
581      statically, but will write their overrides directly into the
582      struct it points to.  With all modern DLLs, this will remain the
583      default_cygwin_cxx_malloc struct in cxx.cc, but if any broken DLLs
584      are in the mix they will have overridden the pointer and subsequent
585      overrides will go into their embedded cxx_malloc structs.  This is
586      almost certainly not a problem as they can never be unloaded, but
587      if we ever did want to do anything about it, we could check here to
588      see if the pointer had been altered in the early parts of the DLL's
589      startup, and if so copy back the new overrides and reset it here.
590      However, that's just a note for the record; at the moment, we can't
591      see any need to worry about this happening.  */
592
593   check_sanity_and_sync (p);
594
595   dll_type type;
596
597   /* If this function is called before cygwin has finished
598      initializing, then the DLL must be a cygwin-aware DLL
599      that was explicitly linked into the program rather than
600      a dlopened DLL. */
601   if (linked)
602     type = DLL_LINK;
603   else
604     {
605       type = DLL_LOAD;
606       dlls.reload_on_fork = 1;
607     }
608
609   /* Allocate and initialize space for the DLL. */
610   dll *d = dlls.alloc (h, p, type);
611
612   /* If d == NULL, then something is broken.
613      Otherwise, if we've finished initializing, it's ok to
614      initialize the DLL.  If we haven't finished initializing,
615      it may not be safe to call the dll's "main" since not
616      all of cygwin's internal structures may have been set up. */
617   if (!d || (!linked && !d->init ()))
618     res = -1;
619   else
620     res = (DWORD) d;
621 }
622
623 /* OBSOLETE: This function is obsolete and will go away in the
624    future.  Cygwin can now handle being loaded from a noncygwin app
625    using the same entry point. */
626
627 extern "C" int
628 dll_noncygwin_dllcrt0 (HMODULE h, per_process *p)
629 {
630   return dll_dllcrt0 (h, p);
631 }
632
633 extern "C" void
634 cygwin_detach_dll (dll *)
635 {
636   HANDLE retaddr;
637   if (_my_tls.isinitialized ())
638     retaddr = (void *) _my_tls.retaddr ();
639   else
640     retaddr = __builtin_return_address (0);
641   dlls.detach (retaddr);
642 }
643
644 extern "C" void
645 dlfork (int val)
646 {
647   dlls.reload_on_fork = val;
648 }
649
650 /* Called from various places to update all of the individual
651    ideas of the environ block.  Explain to me again why we didn't
652    just import __cygwin_environ? */
653 void __stdcall
654 update_envptrs ()
655 {
656   for (dll *d = dlls.istart (DLL_ANY); d; d = dlls.inext ())
657     if (*(d->p.envptr) != __cygwin_environ)
658       *(d->p.envptr) = __cygwin_environ;
659   *main_environ = __cygwin_environ;
660 }