Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/CONTRIBUTORS1
-rw-r--r--winsup/cygwin/dll_init.cc53
-rw-r--r--winsup/cygwin/release/2.7.12
3 files changed, 51 insertions, 5 deletions
diff --git a/winsup/CONTRIBUTORS b/winsup/CONTRIBUTORS
index 84b4fa85f..635d8f5f4 100644
--- a/winsup/CONTRIBUTORS
+++ b/winsup/CONTRIBUTORS
@@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
Individuals submitting their patches under 2-clause BSD:
+David Allsopp David.Allsopp@cl.cam.ac.uk
Erik M. Bray erik.bray@lri.fr
=========================================================================
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index 0fe5714ab..86776f2ce 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -271,9 +271,16 @@ void dll_list::populate_deps (dll* d)
PIMAGE_DATA_DIRECTORY dd = pef->idata_dir (IMAGE_DIRECTORY_ENTRY_IMPORT);
/* Annoyance: calling crealloc with a NULL pointer will use the
wrong heap and crash, so we have to replicate some code */
- long maxdeps = 4;
- d->deps = (dll**) cmalloc (HEAP_2_DLL, maxdeps*sizeof (dll*));
- d->ndeps = 0;
+ long maxdeps;
+ if (!d->ndeps)
+ {
+ maxdeps = 4;
+ d->deps = (dll**) cmalloc (HEAP_2_DLL, maxdeps*sizeof (dll*));
+ }
+ else
+ {
+ maxdeps = d->ndeps;
+ }
for (PIMAGE_IMPORT_DESCRIPTOR id=
(PIMAGE_IMPORT_DESCRIPTOR) pef->rva (dd->VirtualAddress);
dd->Size && id->Name;
@@ -306,9 +313,45 @@ dll_list::topsort ()
/* make sure we have all the deps available */
dll* d = &start;
+ dll** dlopen_deps = NULL;
+ long maxdeps = 4;
+ long dlopen_ndeps = 0;
+
+ if (loaded_dlls > 0)
+ dlopen_deps = (dll**) cmalloc (HEAP_2_DLL, maxdeps*sizeof (dll*));
+
while ((d = d->next))
- if (!d->ndeps)
- populate_deps (d);
+ {
+ if (!d->ndeps)
+ {
+ /* Ensure that all dlopen'd DLLs depend on previously dlopen'd DLLs.
+ This prevents topsort from reversing the order of dlopen'd DLLs on
+ calls to fork. */
+ if (d->type == DLL_LOAD)
+ {
+ /* Initialise d->deps with all previously dlopen'd DLLs. */
+ if (dlopen_ndeps)
+ {
+ d->ndeps = dlopen_ndeps;
+ d->deps = (dll**) cmalloc (HEAP_2_DLL,
+ dlopen_ndeps*sizeof (dll*));
+ memcpy (d->deps, dlopen_deps, dlopen_ndeps*sizeof (dll*));
+ }
+ /* Add this DLL to the list of previously dlopen'd DLLs. */
+ if (dlopen_ndeps >= maxdeps)
+ {
+ maxdeps = 2*(1+maxdeps);
+ dlopen_deps = (dll**) crealloc (dlopen_deps,
+ maxdeps*sizeof (dll*));
+ }
+ dlopen_deps[dlopen_ndeps++] = d;
+ }
+ populate_deps (d);
+ }
+ }
+
+ if (loaded_dlls > 0)
+ cfree (dlopen_deps);
/* unlink head and tail pointers so the sort can rebuild the list */
d = start.next;
diff --git a/winsup/cygwin/release/2.7.1 b/winsup/cygwin/release/2.7.1
index 54e110050..411a0ae6b 100644
--- a/winsup/cygwin/release/2.7.1
+++ b/winsup/cygwin/release/2.7.1
@@ -8,6 +8,8 @@ What changed:
- cygcheck and strace now always generate output with Unix LF line endings,
rather than with DOS/Windows CR LF line endings.
+- fork now preserves the load order of unrelated dlopen'd modules.
+
Bug Fixes
---------