Cygwin: add newgrp release notes
[newlib-cygwin.git] / winsup / cygwin / dll_init.cc
blob1a047511f8cc2475e3f29da6bfd548731857720c
1 /* dll_init.cc
3 This software is a copyrighted work licensed under the terms of the
4 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
5 details. */
7 #include "winsup.h"
8 #include "cygerrno.h"
9 #include "perprocess.h"
10 #include "sync.h"
11 #include "shared_info.h"
12 #include "dll_init.h"
13 #include "environ.h"
14 #include "security.h"
15 #include "path.h"
16 #include "fhandler.h"
17 #include "dtable.h"
18 #include "cygheap.h"
19 #include "pinfo.h"
20 #include "child_info.h"
21 #include "cygtls.h"
22 #include "exception.h"
23 #include <wchar.h>
24 #include <sys/reent.h>
25 #include <assert.h>
26 #include <tls_pbuf.h>
28 extern void check_sanity_and_sync (per_process *);
30 #define fabort fork_info->abort
32 dll_list dlls;
34 WCHAR NO_COPY dll_list::nt_max_path_buffer[NT_MAX_PATH];
36 muto dll_list::protect;
38 static bool dll_global_dtors_recorded;
40 /* We need the in_load_after_fork flag so dll_dllcrt0_1 can decide at fork
41 time if this is a linked DLL or a dynamically loaded DLL. In either case,
42 both, cygwin_finished_initializing and __in_forkee are true, so they are not
43 sufficient to discern the situation. */
44 static bool NO_COPY in_load_after_fork;
46 /* Into ntbuf with ntbufsize, prints name prefixed with "\\??\\"
47 or "\\??\\UNC" as necessary to form the native NT path name.
48 Returns the end of the resulting string in ntbuf.
49 Supports using (a substring of) ntbuf as name argument. */
50 PWCHAR dll_list::form_ntname (PWCHAR ntbuf, size_t ntbufsize, PCWCHAR name)
52 while (true)
54 /* avoid using path_conv here: cygheap might not be
55 initialized when started from non-cygwin process,
56 or still might be frozen in_forkee */
57 if (name[0] == L'\0' || ntbufsize < 8)
58 break;
59 if (name[1] == L':') /* short Win32 drive letter path name */
61 int winlen = min (ntbufsize - 5, wcslen (name));
62 if (ntbuf + 4 != name)
63 memmove (ntbuf + 4, name, sizeof (*ntbuf) * winlen);
64 wcsncpy (ntbuf, L"\\??\\", 4);
65 ntbuf += 4 + winlen;
66 break;
68 if (!wcsncmp (name, L"\\\\?\\", 4)) /* long Win32 path name */
70 int winlen = min (ntbufsize - 1, wcslen (name));
71 if (ntbuf != name)
72 memmove (ntbuf, name, sizeof (*ntbuf) * winlen);
73 ntbuf[1] = L'?';
74 ntbuf += winlen;
75 break;
77 if (!wcsncmp (name, L"\\\\", 2)) /* short Win32 UNC path name */
79 name += 1; /* skip first backslash */
80 int winlen = min (ntbufsize - 8, wcslen (name));
81 if (ntbuf + 7 != name)
82 memmove (ntbuf + 7, name, sizeof (*ntbuf) * winlen);
83 wcsncpy (ntbuf, L"\\??\\UNC", 7);
84 ntbuf += 7 + winlen;
85 break;
87 if (!wcsncmp (name, L"\\??\\", 4)) /* already a long NT path name */
89 int winlen = min (ntbufsize - 1, wcslen (name));
90 if (ntbuf != name)
91 memmove (ntbuf, name, sizeof (*ntbuf) * winlen);
92 ntbuf += winlen;
93 break;
95 system_printf ("WARNING: invalid path name '%W'", name);
96 break;
98 if (ntbufsize)
99 *ntbuf = L'\0';
100 return ntbuf;
103 /* Into shortbuf with shortbufsize, prints name with "\\??\\"
104 or "\\??\\UNC" prefix removed/modified as necessary to form
105 the short Win32 path name.
106 Returns the end of the resulting string in shortbuf.
107 Supports using (a substring of) shortbuf as name argument. */
108 PWCHAR
109 dll_list::form_shortname (PWCHAR shortbuf, size_t shortbufsize, PCWCHAR name)
111 while (true)
113 /* avoid using path_conv here: cygheap might not be
114 initialized when started from non-cygwin process,
115 or still might be frozen in_forkee */
116 if (name[0] == L'\0' || shortbufsize < 2)
117 break;
118 if (name[0] == L'\\' &&
119 (name[1] == L'\\' || name[1] == L'?') &&
120 name[2] == L'?' &&
121 name[3] == L'\\') /* long Win32 or NT path name */
122 name += 4;
123 if (name[1] == L':') /* short Win32 drive letter path name */
125 int ntlen = min (shortbufsize - 1, wcslen (name));
126 if (shortbuf != name)
127 memmove (shortbuf, name, sizeof (*shortbuf) * ntlen);
128 shortbuf += ntlen;
129 break;
131 if (!wcsncmp (name, L"UNC\\", 4)) /* UNC path name */
133 name += 3; /* skip "UNC" */
134 int winlen = min (shortbufsize - 2, wcslen (name));
135 if (shortbuf + 1 != name)
136 memmove (shortbuf + 1, name, sizeof (*shortbuf) * winlen);
137 shortbuf[0] = L'\\';
138 shortbuf += 1 + winlen;
139 break;
141 if (!wcsncmp (name, L"\\\\", 2)) /* already a short Win32 UNC path name */
143 int winlen = min (shortbufsize - 1, wcslen (name));
144 if (shortbuf != name)
145 memmove (shortbuf, name, sizeof (*shortbuf) * winlen);
146 shortbuf += winlen;
147 break;
149 system_printf ("WARNING: invalid path name '%W'", name);
150 break;
152 if (shortbufsize)
153 *shortbuf = L'\0';
154 return shortbuf;
157 /* Run destructors for all DLLs on exit. */
158 void
159 dll_global_dtors ()
161 /* Don't attempt to call destructors if we're still in fork processing
162 since that likely means fork is failing and everything will not have been
163 set up. */
164 if (__in_forkee == FORKING)
165 return;
166 int recorded = dll_global_dtors_recorded;
167 dll_global_dtors_recorded = false;
168 if (recorded && dlls.start.next)
169 for (dll *d = dlls.end; d != &dlls.start; d = d->prev)
170 d->run_dtors ();
173 /* Run all constructors associated with a dll */
174 void
175 per_module::run_ctors ()
177 void (**pfunc)() = ctors;
179 /* Run ctors backwards, so skip the first entry and find how many
180 there are, then run them. */
182 if (pfunc)
184 int i;
185 for (i = 1; pfunc[i]; i++);
187 for (int j = i - 1; j > 0; j--)
188 (pfunc[j]) ();
192 /* Run all destructors associated with a dll */
193 void
194 per_module::run_dtors ()
196 void (**pfunc)() = dtors;
197 while (*++pfunc)
198 (*pfunc) ();
201 /* Initialize an individual DLL */
203 dll::init ()
205 int ret = 1;
207 /* Don't run constructors or the "main" if we've forked. */
208 if (__in_forkee != FORKING)
210 /* global contructors */
211 p.run_ctors ();
213 /* entry point of dll (use main of per_process with null args...) */
214 if (p.main)
215 ret = p.main (0, 0, 0);
218 return ret;
221 /* Look for a dll based on the full path.
223 CV, 2012-03-04: Per MSDN, If a DLL with the same module name is already
224 loaded in memory, the system uses the loaded DLL, no matter which directory
225 it is in. The system does not search for the DLL. See
226 http://msdn.microsoft.com/en-us/library/ms682586%28v=vs.85%29.aspx
228 On 2012-02-08 I interpreted "module name" as "basename". So the assumption
229 was that the Windows Loader does not load another DLL with the same basename,
230 if one such DLL is already loaded. Consequentially I changed the code so
231 that DLLs are only compared by basename.
233 This assumption was obviously wrong, as the perl dynaloader proves. It
234 loads multiple DLLs with the same basename into memory, just from different
235 locations. This mechanism is broken when only comparing basenames in the
236 below code.
238 However, the original problem reported on 2012-02-07 was a result of
239 a subtil difference between the paths returned by different calls to
240 GetModuleFileNameW: Sometimes the path is a plain DOS path, sometimes
241 it's preceeded by the long pathname prefix "\\?\".
243 So I reverted the original change from 2012-02-08 and only applied the
244 following fix: Check if the path is preceeded by a long pathname prefix,
245 and, if so, drop it forthwith so that subsequent full path comparisons
246 work as expected.
248 At least that was the original idea. In fact there are two case, linked
249 and runtime loaded DLLs, which have to be distinguished:
251 - Linked DLLs are loaded by only specifying the basename of the DLL and
252 searching it using the system DLL search order as given in the
253 aforementioned MSDN URL.
255 - Runtime loaded DLLs are specified with the full path since that's how
256 dlopen works.
258 In effect, we have to be careful not to mix linked and loaded DLLs.
259 For more info how this gets accomplished, see the comments at the start
260 of dll_list::alloc, as well as the comment preceeding the definition of
261 the in_load_after_fork bool later in the file. */
262 dll *
263 dll_list::operator[] (PCWCHAR ntname)
265 dll *d = &start;
266 while ((d = d->next) != NULL)
267 if (!wcscasecmp (ntname, d->ntname))
268 return d;
270 return NULL;
273 /* Look for a dll based on the basename. */
274 dll *
275 dll_list::find_by_modname (PCWCHAR modname)
277 dll *d = &start;
278 while ((d = d->next) != NULL)
279 if (!wcscasecmp (modname, d->modname))
280 return d;
282 return NULL;
285 /* Look for a dll based on the ntname used
286 to dynamically reload in forked child. */
287 dll *
288 dll_list::find_by_forkedntname (PCWCHAR ntname)
290 dll *d = &start;
291 while ((d = d->next) != NULL)
292 if (!wcscasecmp (ntname, d->forkedntname ()))
293 return d;
295 return NULL;
298 #define RETRIES 1000
300 /* Allocate space for a dll struct. */
301 dll *
302 dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
304 /* Called under loader lock conditions so this function can't be called
305 multiple times in parallel. The static buffer is safe. */
306 PWCHAR ntname = nt_max_path_buf ();
307 GetModuleFileNameW (h, ntname, NT_MAX_PATH);
308 PWCHAR modname = form_ntname (ntname, NT_MAX_PATH, ntname);
309 DWORD ntnamelen = modname - ntname;
310 while (modname > ntname && *(modname - 1) != L'\\')
311 --modname;
313 guard (true);
314 /* Already loaded? For linked DLLs, only compare the basenames. Linked
315 DLLs are loaded using just the basename and the default DLL search path.
316 The Windows loader picks up the first one it finds.
317 This also applies to cygwin1.dll and the main-executable (DLL_SELF).
318 When in_load_after_fork, dynamically loaded dll's are reloaded
319 using their parent's forkable_ntname, if available. */
320 dll *d = (type != DLL_LOAD) ? dlls.find_by_modname (modname) :
321 in_load_after_fork ? dlls.find_by_forkedntname (ntname) : dlls[ntname];
322 if (d)
324 /* We only get here in the forkee. */
325 if (d->handle != h)
326 fabort ("%W: Loaded to different address: parent(%p) != child(%p)",
327 ntname, d->handle, h);
328 /* If this DLL has been linked against, and the full path differs, try
329 to sanity check if this is the same DLL, just in another path. */
330 else if (type == DLL_LINK && wcscasecmp (ntname, d->ntname)
331 && (d->p.data_start != p->data_start
332 || d->p.data_start != p->data_start
333 || d->p.bss_start != p->bss_start
334 || d->p.bss_end != p->bss_end
335 || d->p.ctors != p->ctors
336 || d->p.dtors != p->dtors))
337 fabort ("\nLoaded different DLL with same basename in forked child,\n"
338 "parent loaded: %W\n"
339 " child loaded: %W\n"
340 "The DLLs differ, so it's not safe to run the forked child.\n"
341 "Make sure to remove the offending DLL before trying again.",
342 d->ntname, ntname);
343 d->p = p;
345 else
347 size_t forkntsize = forkable_ntnamesize (type, ntname, modname);
349 /* FIXME: Change this to new at some point. */
350 d = (dll *) cmalloc (HEAP_2_DLL, sizeof (*d)
351 + ((ntnamelen + forkntsize) * sizeof (*ntname)));
353 /* Now we've allocated a block of information. Fill it in with the
354 supplied info about this DLL. */
355 wcscpy (d->ntname, ntname);
356 d->modname = d->ntname + (modname - ntname);
357 d->handle = h;
358 d->count = 0; /* Reference counting performed in dlopen/dlclose. */
359 /* DLL_SELF dtors (main-executable, cygwin1.dll) are run elsewhere */
360 d->has_dtors = type != DLL_SELF;
361 d->p = p;
362 d->ndeps = 0;
363 d->deps = NULL;
364 d->image_size = ((pefile*)h)->optional_hdr ()->SizeOfImage;
365 d->preferred_base = (void*) ((pefile*)h)->optional_hdr()->ImageBase;
366 d->type = type;
367 d->fii.IndexNumber.QuadPart = -1LL;
368 if (!forkntsize)
369 d->forkable_ntname = NULL;
370 else
372 d->forkable_ntname = d->ntname + ntnamelen + 1;
373 *d->forkable_ntname = L'\0';
375 if (forkables_supported ())
376 d->stat_real_file_once ();
377 append (d);
378 if (type == DLL_LOAD)
379 loaded_dlls++;
381 guard (false);
382 return d;
385 void
386 dll_list::append (dll* d)
388 if (end == NULL)
389 end = &start; /* Point to "end" of dll chain. */
390 end->next = d; /* Standard linked list stuff. */
391 d->next = NULL;
392 d->prev = end;
393 end = d;
396 void dll_list::populate_deps (dll* d)
398 tmp_pathbuf tp;
400 PWCHAR wmodname = tp.w_get ();
401 pefile* pef = (pefile*) d->handle;
402 PIMAGE_DATA_DIRECTORY dd = pef->idata_dir (IMAGE_DIRECTORY_ENTRY_IMPORT);
403 /* Annoyance: calling crealloc with a NULL pointer will use the
404 wrong heap and crash, so we have to replicate some code */
405 long maxdeps;
406 if (!d->ndeps)
408 maxdeps = 4;
409 d->deps = (dll**) cmalloc (HEAP_2_DLL, maxdeps*sizeof (dll*));
411 else
413 maxdeps = d->ndeps;
415 for (PIMAGE_IMPORT_DESCRIPTOR id=
416 (PIMAGE_IMPORT_DESCRIPTOR) pef->rva (dd->VirtualAddress);
417 dd->Size && id->Name;
418 id++)
420 char* modname = pef->rva (id->Name);
421 sys_mbstowcs (wmodname, NT_MAX_PATH, modname);
422 if (dll* dep = find_by_modname (wmodname))
424 if (d->ndeps >= maxdeps)
426 maxdeps = 2*(1+maxdeps);
427 d->deps = (dll**) crealloc (d->deps, maxdeps*sizeof (dll*));
429 d->deps[d->ndeps++] = dep;
433 /* add one to differentiate no deps from unknown */
434 d->ndeps++;
438 void
439 dll_list::topsort ()
441 /* Anything to do? */
442 if (!end || end == &start)
443 return;
445 /* make sure we have all the deps available */
446 dll* d = &start;
447 dll** dlopen_deps = NULL;
448 long maxdeps = 4;
449 long dlopen_ndeps = 0;
451 if (loaded_dlls > 0)
452 dlopen_deps = (dll**) cmalloc (HEAP_2_DLL, maxdeps*sizeof (dll*));
454 while ((d = d->next))
456 if (!d->ndeps)
458 /* Ensure that all dlopen'd DLLs depend on previously dlopen'd DLLs.
459 This prevents topsort from reversing the order of dlopen'd DLLs on
460 calls to fork. */
461 if (d->type == DLL_LOAD)
463 /* Initialise d->deps with all previously dlopen'd DLLs. */
464 if (dlopen_ndeps)
466 d->ndeps = dlopen_ndeps;
467 d->deps = (dll**) cmalloc (HEAP_2_DLL,
468 dlopen_ndeps*sizeof (dll*));
469 memcpy (d->deps, dlopen_deps, dlopen_ndeps*sizeof (dll*));
471 /* Add this DLL to the list of previously dlopen'd DLLs. */
472 if (dlopen_ndeps >= maxdeps)
474 maxdeps = 2*(1+maxdeps);
475 dlopen_deps = (dll**) crealloc (dlopen_deps,
476 maxdeps*sizeof (dll*));
478 dlopen_deps[dlopen_ndeps++] = d;
480 populate_deps (d);
484 if (loaded_dlls > 0)
485 cfree (dlopen_deps);
487 /* unlink head and tail pointers so the sort can rebuild the list */
488 d = start.next;
489 start.next = end = NULL;
490 topsort_visit (d, true);
492 /* clear node markings made by the sort */
493 d = &start;
494 while ((d = d->next))
496 #ifdef DEBUGGING
497 paranoid_printf ("%W", d->modname);
498 for (int i = 1; i < -d->ndeps; i++)
499 paranoid_printf ("-> %W", d->deps[i - 1]->modname);
500 #endif
502 /* It would be really nice to be able to keep this information
503 around for next time, but we don't have an easy way to
504 invalidate cached dependencies when a module unloads. */
505 d->ndeps = 0;
506 cfree (d->deps);
507 d->deps = NULL;
511 /* A recursive in-place topological sort. The result is ordered so that
512 dependencies of a dll appear before it in the list.
514 NOTE: this algorithm is guaranteed to terminate with a "partial
515 order" of dlls but does not do anything smart about cycles: an
516 arbitrary dependent dll will necessarily appear first. Perhaps not
517 surprisingly, Windows ships several dlls containing dependency
518 cycles, including SspiCli/RPCRT4.dll and a lovely tangle involving
519 USP10/LPK/GDI32/USER32.dll). Fortunately, we don't care about
520 Windows DLLs here, and cygwin dlls should behave better */
521 void
522 dll_list::topsort_visit (dll* d, bool seek_tail)
524 /* Recurse to the end of the dll chain, then visit nodes as we
525 unwind. We do this because once we start visiting nodes we can no
526 longer trust any _next_ pointers.
528 We "mark" visited nodes (to avoid revisiting them) by negating
529 ndeps (undone once the sort completes). */
530 if (seek_tail && d->next)
531 topsort_visit (d->next, true);
533 if (d->ndeps > 0)
535 d->ndeps = -d->ndeps;
536 for (long i = 1; i < -d->ndeps; i++)
537 topsort_visit (d->deps[i - 1], false);
539 append (d);
544 dll *
545 dll_list::find (void *retaddr)
547 MEMORY_BASIC_INFORMATION m;
548 if (!VirtualQuery (retaddr, &m, sizeof m))
549 return NULL;
550 HMODULE h = (HMODULE) m.AllocationBase;
552 dll *d = &start;
553 while ((d = d->next))
554 if (d->type != DLL_SELF && d->handle == h)
555 break;
556 return d;
559 /* Detach a DLL from the chain. */
560 void
561 dll_list::detach (void *retaddr)
563 dll *d;
564 /* Don't attempt to call destructors if we're still in fork processing
565 since that likely means fork is failing and everything will not have been
566 set up. */
567 if (!myself || __in_forkee == FORKING)
568 return;
569 guard (true);
570 if ((d = find (retaddr)))
572 /* Ensure our exception handler is enabled for destructors */
573 exception protect;
574 /* Call finalize function if we are not already exiting */
575 if (!exit_state)
576 __cxa_finalize (d->handle);
577 d->run_dtors ();
578 d->prev->next = d->next;
579 if (d->next)
580 d->next->prev = d->prev;
581 if (d->type == DLL_LOAD)
582 loaded_dlls--;
583 if (end == d)
584 end = d->prev;
585 cfree (d);
587 guard (false);
590 /* Initialization for all linked DLLs, called by dll_crt0_1. */
591 void
592 dll_list::init ()
594 track_self ();
596 /* Walk the dll chain, initializing each dll */
597 dll *d = &start;
598 dll_global_dtors_recorded = d->next != NULL;
599 while ((d = d->next))
600 if (d->type != DLL_SELF) /* linked and early loaded dlls */
601 d->init ();
604 void
605 dll_list::track_self ()
607 /* for cygwin1.dll and main-executable: maintain hardlinks only */
608 alloc (cygwin_hmodule, user_data, DLL_SELF);
609 main_executable = alloc (GetModuleHandle (NULL), user_data, DLL_SELF);
612 #define A64K (64 * 1024)
615 /* Reserve the chunk of free address space starting _here_ and (usually)
616 covering at least _dll_size_ bytes. However, we must take care not
617 to clobber the dll's target address range because it often overlaps.
619 static PVOID
620 reserve_at (PCWCHAR name, PVOID here, PVOID dll_base, DWORD dll_size)
622 DWORD size;
623 MEMORY_BASIC_INFORMATION mb;
625 if (!VirtualQuery (here, &mb, sizeof (mb)))
626 fabort ("couldn't examine memory at %p while mapping %W, %E", here, name);
627 if (mb.State != MEM_FREE)
628 return 0;
630 size = mb.RegionSize;
632 // don't clobber the space where we want the dll to land
633 caddr_t end = (caddr_t) here + size;
634 caddr_t dll_end = (caddr_t) dll_base + dll_size;
635 if (dll_base < here && dll_end > (caddr_t) here)
636 here = (PVOID) dll_end; // the dll straddles our left edge
637 else if (dll_base >= here && (caddr_t) dll_base < end)
638 end = (caddr_t) dll_base; // the dll overlaps partly or fully to our right
640 size = end - (caddr_t) here;
641 if (!VirtualAlloc (here, size, MEM_RESERVE, PAGE_NOACCESS))
642 fabort ("couldn't allocate memory %p(%d) for '%W' alignment, %E\n",
643 here, size, name);
644 return here;
647 /* Release the memory previously allocated by "reserve_at" above. */
648 static void
649 release_at (PCWCHAR name, PVOID here)
651 if (!VirtualFree (here, 0, MEM_RELEASE))
652 fabort ("couldn't release memory %p for '%W' alignment, %E\n",
653 here, name);
656 /* Step 1: Reserve memory for all DLL_LOAD dlls. This is to prevent
657 anything else from taking their spot as we compensate for Windows
658 randomly relocating things.
660 NOTE: because we can't depend on LoadLibraryExW to do the right
661 thing, we have to do a vanilla VirtualAlloc instead. One possible
662 optimization might attempt a LoadLibraryExW first, in case it lands
663 in the right place, but then we have to find a way of tracking
664 which dlls ended up needing VirtualAlloc after all. */
665 void
666 dll_list::reserve_space ()
668 for (dll* d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
669 if (!VirtualAlloc (d->handle, d->image_size, MEM_RESERVE, PAGE_NOACCESS))
670 fabort ("address space needed by '%W' (%p) is already occupied",
671 d->modname, d->handle);
674 /* Reload DLLs after a fork. Iterates over the list of dynamically loaded
675 DLLs and attempts to load them in the same place as they were loaded in the
676 parent. Updates main-executable and cygwin1.dll tracking. */
677 void
678 dll_list::load_after_fork (HANDLE parent)
680 release_forkables ();
682 // moved to frok::child for performance reasons:
683 // dll_list::reserve_space();
685 in_load_after_fork = true;
686 if (reload_on_fork)
687 load_after_fork_impl (parent, dlls.istart (DLL_LOAD), 0);
688 track_self ();
689 in_load_after_fork = false;
692 static int const DLL_RETRY_MAX = 6;
693 void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
695 /* Step 2: For each dll which did not map at its preferred base
696 address in the parent, try to coerce it to land at the same spot
697 as before. If not, unload it, reserve the memory around it, and
698 try again. Use recursion to remember blocked regions address
699 space so we can release them later.
701 We DONT_RESOLVE_DLL_REFERENCES at first in case the DLL lands in
702 the wrong spot;
704 NOTE: This step skips DLLs which loaded at their preferred address in
705 the parent because they should behave (we already verified that their
706 preferred address in the child is available). However, this may fail
707 with ASLR active, because the ASLR base address will usually not equal
708 the preferred base recorded in the dll. In this case, we should make
709 the LoadLibraryExW call unconditional.
711 for ( ; d; d = dlls.inext ())
712 if (d->handle != d->preferred_base)
714 /* See if the DLL will load in proper place. If not, unload it,
715 reserve the memory around it, and try again.
717 If this is the first attempt, we need to release the
718 dll's protective reservation from step 1
720 if (!retries && !VirtualFree (d->handle, 0, MEM_RELEASE))
721 fabort ("unable to release protective reservation (%p) for %W, %E",
722 d->handle, d->ntname);
724 HMODULE h = LoadLibraryExW (buffered_shortname (d->forkedntname ()),
725 NULL, DONT_RESOLVE_DLL_REFERENCES);
726 if (!h)
727 fabort ("unable to create interim mapping for %W (using %W), %E",
728 d->ntname, buffered_shortname (d->forkedntname ()));
729 if (h != d->handle)
731 sigproc_printf ("%W (using %W) loaded in wrong place: %p != %p",
732 d->ntname, buffered_shortname (d->forkedntname ()),
733 h, d->handle);
734 FreeLibrary (h);
735 PVOID reservation = reserve_at (d->ntname, h,
736 d->handle, d->image_size);
737 if (!reservation)
738 fabort ("unable to block off %p to prevent %W from loading there",
739 h, d->ntname);
741 if (retries < DLL_RETRY_MAX)
742 load_after_fork_impl (parent, d, retries+1);
743 else
744 fabort ("unable to remap %W (using %W) to same address as parent (%p) - try running rebaseall",
745 d->ntname, buffered_shortname (d->forkedntname ()), d->handle);
747 /* once the above returns all the dlls are mapped; release
748 the reservation and continue unwinding */
749 sigproc_printf ("releasing blocked space at %p", reservation);
750 release_at (d->ntname, reservation);
751 return;
755 /* Step 3: try to load each dll for real after either releasing the
756 protective reservation (for well-behaved dlls) or unloading the
757 interim mapping (for rebased dlls) . The dll list is sorted in
758 dependency order, so we shouldn't pull in any additional dlls
759 outside our control. */
760 for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
762 if (d->handle == d->preferred_base)
764 if (!VirtualFree (d->handle, 0, MEM_RELEASE))
765 fabort ("unable to release protective reservation for %W (%p), %E",
766 d->ntname, d->handle);
768 else
770 /* Free the library using our parent's handle: it's identical
771 to ours or we wouldn't have gotten this far */
772 if (!FreeLibrary (d->handle))
773 fabort ("unable to unload interim mapping of %W (using %W), %E",
774 d->ntname, buffered_shortname (d->forkedntname ()));
776 /* cygwin1.dll - as linked dependency - may reuse the shortname
777 buffer, even in case of failure: don't reuse shortname later */
778 HMODULE h = LoadLibraryW (buffered_shortname (d->forkedntname ()));
779 if (!h)
780 fabort ("unable to map %W (using %W), %E",
781 d->ntname, buffered_shortname (d->forkedntname ()));
782 if (h != d->handle)
783 fabort ("unable to map %W (using %W) to same address as parent: %p != %p",
784 d->ntname, buffered_shortname (d->forkedntname ()), d->handle, h);
785 /* Fix OS reference count. */
786 for (int cnt = 1; cnt < d->count; ++cnt)
787 LoadLibraryW (buffered_shortname (d->forkedntname ()));
791 struct dllcrt0_info
793 HMODULE h;
794 per_process *p;
795 PVOID res;
796 dllcrt0_info (HMODULE h0, per_process *p0): h (h0), p (p0) {}
799 extern "C" PVOID
800 dll_dllcrt0 (HMODULE h, per_process *p)
802 if (dynamically_loaded)
803 return (PVOID) 1;
804 dllcrt0_info x (h, p);
805 dll_dllcrt0_1 (&x);
806 return x.res;
809 void
810 dll_dllcrt0_1 (VOID *x)
812 HMODULE& h = ((dllcrt0_info *) x)->h;
813 per_process*& p = ((dllcrt0_info *) x)->p;
814 PVOID& res = ((dllcrt0_info *) x)->res;
816 if (p == NULL)
817 p = &__cygwin_user_data;
818 else
820 *(p->impure_ptr_ptr) = __cygwin_user_data.impure_ptr;
821 _pei386_runtime_relocator (p);
824 bool linked = !cygwin_finished_initializing && !in_load_after_fork;
826 /* Broken DLLs built against Cygwin versions 1.7.0-49 up to 1.7.0-57
827 override the cxx_malloc pointer in their DLL initialization code,
828 when loaded either statically or dynamically. Because this leaves
829 a stale pointer into demapped memory space if the DLL is unloaded
830 by a call to dlclose, we prevent this happening for dynamically
831 loaded DLLs in dlopen by saving and restoring cxx_malloc around
832 the call to LoadLibrary, which invokes the DLL's startup sequence.
833 Modern DLLs won't even attempt to override the pointer when loaded
834 statically, but will write their overrides directly into the
835 struct it points to. With all modern DLLs, this will remain the
836 default_cygwin_cxx_malloc struct in cxx.cc, but if any broken DLLs
837 are in the mix they will have overridden the pointer and subsequent
838 overrides will go into their embedded cxx_malloc structs. This is
839 almost certainly not a problem as they can never be unloaded, but
840 if we ever did want to do anything about it, we could check here to
841 see if the pointer had been altered in the early parts of the DLL's
842 startup, and if so copy back the new overrides and reset it here.
843 However, that's just a note for the record; at the moment, we can't
844 see any need to worry about this happening. */
846 check_sanity_and_sync (p);
848 dll_type type;
850 /* If this function is called before cygwin has finished
851 initializing, then the DLL must be a cygwin-aware DLL
852 that was explicitly linked into the program rather than
853 a dlopened DLL. */
854 if (linked)
855 type = DLL_LINK;
856 else
858 type = DLL_LOAD;
859 dlls.reload_on_fork = 1;
862 /* Allocate and initialize space for the DLL. */
863 dll *d = dlls.alloc (h, p, type);
865 /* If d == NULL, then something is broken.
866 Otherwise, if we've finished initializing, it's ok to
867 initialize the DLL. If we haven't finished initializing,
868 it may not be safe to call the dll's "main" since not
869 all of cygwin's internal structures may have been set up. */
870 if (!d || (!linked && !d->init ()))
871 res = (PVOID) -1;
872 else
873 res = (PVOID) d;
876 extern "C" void
877 cygwin_detach_dll (dll *)
879 HANDLE retaddr;
880 if (_my_tls.isinitialized ())
881 retaddr = (void *) _my_tls.retaddr ();
882 else
883 retaddr = __builtin_return_address (0);
884 dlls.detach (retaddr);
887 extern "C" void
888 dlfork (int val)
890 dlls.reload_on_fork = val;