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
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2011-05-29 00:41:51 +0400
committerChristopher Faylor <me@cgf.cx>2011-05-29 00:41:51 +0400
commit07f89f85dbae1e891e8d45b5477db24c66f774b4 (patch)
treec8f31468bc92438229be72cef33c990d8f069c4d /winsup
parent17a5c8c36ec36849772073b2cfa027aa347b48f2 (diff)
Revert previous checkins as they introduced a bug when running zsh.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog38
-rw-r--r--winsup/cygwin/dll_init.cc164
-rw-r--r--winsup/cygwin/dll_init.h30
-rw-r--r--winsup/cygwin/fork.cc8
4 files changed, 15 insertions, 225 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 82851aa4a..1670f7f8f 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,41 +1,5 @@
2011-05-28 Christopher Faylor <me.cygwin2011@cgf.cx>
-
- * dll_init.cc (reserve_upto): Remove.
- (release_upto): Ditto.
- (dll_list::reserve_space): New function to reserve space needed by
- DLL_LOAD dlls early in the fork process.
- (dll_list::load_after_fork): Rewrite to use recursion for tracking
- reservations made while trying to make dlls land where they belong.
- (dll_list::load_after_fork_impl): Ditto.
- (dll_list::alloc): Initialize image base field.
- * dll_init.h (struct dll_list): declare new functions.
- (dll::image_size): New member.
-
-2011-05-28 Ryan Johnson <ryan.johnson@cs.utoronto.ca>
-
- * dll_init.cc (dll_list::find_by_modname): New function to search the
- dll list for a module name only (no path).
- (dll_list::alloc): Initialize newly-added members of struct dll.
- (dll_list::append): New function to factor out the append operation
- (used by dll_list::topsort).
- (dll_list::populate_deps): New function to identify dll dependencies.
- (dll_list::topsort): New function to sort the dll list topologically by
- dependencies.
- (dll_list::topsort_visit): New helper function for the above.
- * dll_init.h (dll::ndeps): New class member.
- (dll::deps): Ditto.
- (dll::modname): Ditto.
- (dll_list::find_by_modname): New function related to topsort.
- (dll_list::populate_all_deps): Ditto.
- (dll_list::populate_deps): Ditto.
- (dll_list::topsort): Ditto.
- (dll_list::topsort_visit): Ditto.
- (dll_list::append): Ditto.
- (pefile): New struct allowing simple introspection of dll images.
- * fork.cc (fork): Topologically sort the dll list before forking.
-
-2011-05-28 Christopher Faylor <me.cygwin2011@cgf.cx>
-
+ Ryan Johnson <ryan.johnson@cs.utoronto.ca>
* dll_init.c (dll_list::load_after_fork): Don't clear in_forkee here.
* fork.cc (frok::errmsg): Rename from 'error'.
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index 7882ed65f..68a974b7b 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -116,18 +116,6 @@ dll_list::operator[] (const PWCHAR name)
return NULL;
}
-/* Look for a dll based on is short name only (no path) */
-dll *
-dll_list::find_by_modname (const PWCHAR name)
-{
- dll *d = &start;
- while ((d = d->next) != NULL)
- if (!wcscasecmp (name, d->modname))
- return d;
-
- return NULL;
-}
-
#define RETRIES 1000
/* Allocate space for a dll struct. */
@@ -173,14 +161,14 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
d->handle = h;
d->has_dtors = true;
d->p = p;
- d->image_size = ((pefile*)h)->optional_hdr ()->SizeOfImage;
- d->ndeps = 0;
- d->deps = NULL;
- d->modname = wcsrchr (d->name, L'\\');
- if (d->modname)
- d->modname++;
d->type = type;
- append (d);
+ if (end == NULL)
+ end = &start; /* Point to "end" of dll chain. */
+ end->next = d; /* Standard linked list stuff. */
+ d->next = NULL;
+ d->prev = end;
+ end = d;
+ tot++;
if (type == DLL_LOAD)
loaded_dlls++;
}
@@ -189,119 +177,6 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
return d;
}
-void
-dll_list::append (dll* d)
-{
- if (end == NULL)
- end = &start; /* Point to "end" of dll chain. */
- end->next = d; /* Standard linked list stuff. */
- d->next = NULL;
- d->prev = end;
- end = d;
- tot++;
-}
-
-void dll_list::populate_deps (dll* d)
-{
- WCHAR wmodname[NT_MAX_PATH];
- pefile* pef = (pefile*) d->handle;
- 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;
- for (PIMAGE_IMPORT_DESCRIPTOR id=
- (PIMAGE_IMPORT_DESCRIPTOR) pef->rva (dd->VirtualAddress);
- dd->Size && id->Name;
- id++)
- {
- char* modname = pef->rva (id->Name);
- sys_mbstowcs (wmodname, NT_MAX_PATH, modname);
- if (dll* dep = find_by_modname (wmodname))
- {
- if (d->ndeps >= maxdeps)
- {
- maxdeps = 2*(1+maxdeps);
- d->deps = (dll**) crealloc (d->deps, maxdeps*sizeof (dll*));
- }
- d->deps[d->ndeps++] = dep;
- }
- }
-
- /* add one to differentiate no deps from unknown */
- d->ndeps++;
-}
-
-
-void
-dll_list::topsort ()
-{
- /* Anything to do? */
- if (!end)
- return;
-
- /* make sure we have all the deps available */
- dll* d = &start;
- while ((d = d->next))
- if (!d->ndeps)
- populate_deps (d);
-
- /* unlink head and tail pointers so the sort can rebuild the list */
- d = start.next;
- start.next = end = NULL;
- topsort_visit (d, true);
-
- /* clear node markings made by the sort */
- d = &start;
- while ((d = d->next))
- {
- debug_printf ("%W", d->modname);
- for (int i=1; i < -d->ndeps; i++)
- debug_printf ("-> %W", d->deps[i-1]->modname);
-
- /* It would be really nice to be able to keep this information
- around for next time, but we don't have an easy way to
- invalidate cached dependencies when a module unloads. */
- d->ndeps = 0;
- cfree (d->deps);
- d->deps = NULL;
- }
-}
-
-/* A recursive in-place topological sort. The result is ordered so that
- dependencies of a dll appear before it in the list.
-
- NOTE: this algorithm is guaranteed to terminate with a "partial
- order" of dlls but does not do anything smart about cycles: an
- arbitrary dependent dll will necessarily appear first. Perhaps not
- surprisingly, Windows ships several dlls containing dependency
- cycles, including SspiCli/RPCRT4.dll and a lovely tangle involving
- USP10/LPK/GDI32/USER32.dll). Fortunately, we don't care about
- Windows DLLs here, and cygwin dlls should behave better */
-void
-dll_list::topsort_visit (dll* d, bool seek_tail)
-{
- /* Recurse to the end of the dll chain, then visit nodes as we
- unwind. We do this because once we start visiting nodes we can no
- longer trust any _next_ pointers.
-
- We "mark" visited nodes (to avoid revisiting them) by negating
- ndeps (undone once the sort completes). */
- if (seek_tail && d->next)
- topsort_visit (d->next, true);
-
- if (d->ndeps > 0)
- {
- d->ndeps = -d->ndeps;
- for (long i=1; i < -d->ndeps; i++)
- topsort_visit (d->deps[i-1], false);
-
- append (d);
- }
-}
-
-
dll *
dll_list::find (void *retaddr)
{
@@ -417,33 +292,21 @@ release_upto (const PWCHAR name, DWORD here)
}
}
-/* Reserve the chunk of free address space starting _here_ and (usually)
- covering at least _dll_size_ bytes. However, we must take care not
- to clobber the dll's target address range because it often overlaps.
- */
+/* Mark one page at "here" as reserved. This may force
+ Windows NT to load a DLL elsewhere. */
static DWORD
-reserve_at (const PWCHAR name, DWORD here, DWORD dll_base, DWORD dll_size)
+reserve_at (const PWCHAR name, DWORD here)
{
DWORD size;
MEMORY_BASIC_INFORMATION mb;
if (!VirtualQuery ((void *) here, &mb, sizeof (mb)))
- api_fatal ("couldn't examine memory at %08lx while mapping %W, %E",
- here, name);
+ size = 64 * 1024;
+
if (mb.State != MEM_FREE)
return 0;
size = mb.RegionSize;
-
- // don't clobber the space where we want the dll to land
- DWORD end = here + size;
- DWORD dll_end = dll_base + dll_size;
- if (dll_base < here && dll_end > here)
- here = dll_end; // the dll straddles our left edge
- else if (dll_base >= here && dll_base < end)
- end = dll_base; // the dll overlaps partly or fully to our right
-
- size = end - here;
if (!VirtualAlloc ((void *) here, size, MEM_RESERVE, PAGE_NOACCESS))
api_fatal ("couldn't allocate memory %p(%d) for '%W' alignment, %E\n",
here, size, name);
@@ -521,8 +384,7 @@ dll_list::load_after_fork (HANDLE parent)
can in the child, due to differences in the load ordering.
Block memory at it's preferred address and try again. */
if ((DWORD) h > (DWORD) d->handle)
- preferred_block = reserve_at (d->name, (DWORD) h,
- (DWORD) d->handle, d->image_size);
+ preferred_block = reserve_at (d->name, (DWORD) h);
}
}
diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h
index 3fbe8760f..d14cc6cb9 100644
--- a/winsup/cygwin/dll_init.h
+++ b/winsup/cygwin/dll_init.h
@@ -52,10 +52,6 @@ struct dll
int count;
bool has_dtors;
dll_type type;
- DWORD image_size;
- long ndeps;
- dll** deps;
- PWCHAR modname;
WCHAR name[1];
void detach ();
int init ();
@@ -88,13 +84,6 @@ public:
void detach (void *);
void init ();
void load_after_fork (HANDLE);
- dll *find_by_modname (const PWCHAR name);
- void populate_all_deps ();
- void populate_deps (dll* d);
- void topsort ();
- void topsort_visit (dll* d, bool goto_tail);
- void append (dll* d);
-
dll *inext ()
{
while ((hold = hold->next))
@@ -120,25 +109,6 @@ public:
dll_list () { protect.init ("dll_list"); }
};
-/* References:
- http://msdn.microsoft.com/en-us/windows/hardware/gg463125
- http://msdn.microsoft.com/en-us/library/ms809762.aspx
-*/
-/* FIXME: Integrate with other similar uses in source. */
-struct pefile
-{
- IMAGE_DOS_HEADER dos_hdr;
-
- char* rva (long offset) { return (char*) this + offset; }
- PIMAGE_NT_HEADERS32 pe_hdr () { return (PIMAGE_NT_HEADERS32) rva (dos_hdr.e_lfanew); }
- PIMAGE_OPTIONAL_HEADER32 optional_hdr () { return &pe_hdr ()->OptionalHeader; }
- PIMAGE_DATA_DIRECTORY idata_dir (DWORD which)
- {
- PIMAGE_OPTIONAL_HEADER32 oh = optional_hdr ();
- return (which < oh->NumberOfRvaAndSizes)? oh->DataDirectory + which : 0;
- }
-};
-
extern dll_list dlls;
void dll_global_dtors ();
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 1ac2b8a45..3ec7fa8c5 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -625,7 +625,7 @@ fork ()
the thread-local storage. A process forking too deeply will run into
the problem to be out of temporary TLS path buffers. */
tmp_pathbuf tp;
-
+
if (!held_everything)
{
if (exit_state)
@@ -634,12 +634,6 @@ fork ()
return -1;
}
- /* Put the dll list in topological dependency ordering, in
- hopes that the child will have a better shot at loading dlls
- properly if it only has to deal with one at a time.
- */
- dlls.topsort ();
-
ischild = !!setjmp (grouped.ch.jmp);
volatile char * volatile esp;