* dll_init.h (struct dll): Re-add modname.
* dll_init.cc: Throughout, use modname where it was used before. (dll_list::operator[]): Use modname. Move comment from dll_list::alloc here and remove hint about GetModuleBaseNameW. (dll_list::alloc): Store full path in name, pointer to basename in modname. Search dll using modname.
This commit is contained in:
		| @@ -1,3 +1,12 @@ | |||||||
|  | 2012-02-09  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* dll_init.h (struct dll): Re-add modname. | ||||||
|  | 	* dll_init.cc: Throughout, use modname where it was used before. | ||||||
|  | 	(dll_list::operator[]): Use modname.  Move comment from dll_list::alloc | ||||||
|  | 	here and remove hint about GetModuleBaseNameW. | ||||||
|  | 	(dll_list::alloc): Store full path in name, pointer to basename in | ||||||
|  | 	modname.  Search dll using modname. | ||||||
|  |  | ||||||
| 2012-02-08  Christopher Faylor  <me.cygwin2012@cgf.cx> | 2012-02-08  Christopher Faylor  <me.cygwin2012@cgf.cx> | ||||||
|  |  | ||||||
| 	* dtable.cc (dtable::init_std_file_from_handle): Reinstate opening tty | 	* dtable.cc (dtable::init_std_file_from_handle): Reinstate opening tty | ||||||
|   | |||||||
| @@ -106,13 +106,17 @@ dll::init () | |||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Look for a dll based on name */ | /* Look for a dll based on the basename. | ||||||
|  |    Only compare basenames for DLLs.  Per MSDN, the Windows loader re-uses | ||||||
|  |    the already loaded DLL, if the new DLL has the same basename as the | ||||||
|  |    already loaded DLL.  It will not try to load the new DLL at all.  See | ||||||
|  |    http://msdn.microsoft.com/en-us/library/ms682586%28v=vs.85%29.aspx */ | ||||||
| dll * | dll * | ||||||
| dll_list::operator[] (const PWCHAR name) | dll_list::operator[] (const PWCHAR modname) | ||||||
| { | { | ||||||
|   dll *d = &start; |   dll *d = &start; | ||||||
|   while ((d = d->next) != NULL) |   while ((d = d->next) != NULL) | ||||||
|     if (!wcscasecmp (name, d->name)) |     if (!wcscasecmp (modname, d->modname)) | ||||||
|       return d; |       return d; | ||||||
|  |  | ||||||
|   return NULL; |   return NULL; | ||||||
| @@ -124,27 +128,21 @@ dll_list::operator[] (const PWCHAR name) | |||||||
| dll * | dll * | ||||||
| dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) | dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) | ||||||
| { | { | ||||||
|   /* Only use and compare basenames for DLLs.  Per MSDN, the Windows loader |   WCHAR name[NT_MAX_PATH]; | ||||||
|      re-uses the already loaded DLL, if the new DLL has the same basename |   GetModuleFileNameW (h, name, sizeof (name)); | ||||||
|      as the already loaded DLL.  It will not try to load the new DLL at all. |  | ||||||
|      See http://msdn.microsoft.com/en-us/library/ms682586%28v=vs.85%29.aspx |  | ||||||
|      Use GetModuleFileNameW + wcsrchr rather than GetModuleBaseNameW since |  | ||||||
|      it's faster per MSDN, and it doesn't require to link against psapi. */ |  | ||||||
|   WCHAR buf[NT_MAX_PATH]; |  | ||||||
|   GetModuleFileNameW (h, buf, sizeof (buf)); |  | ||||||
|   PWCHAR name = wcsrchr (buf, L'\\') + 1; |  | ||||||
|   DWORD namelen = wcslen (name); |   DWORD namelen = wcslen (name); | ||||||
|  |   PWCHAR modname = wcsrchr (name, L'\\') + 1; | ||||||
|  |  | ||||||
|   guard (true); |   guard (true); | ||||||
|   /* Already loaded? */ |   /* Already loaded? */ | ||||||
|   dll *d = dlls[name]; |   dll *d = dlls[modname]; | ||||||
|   if (d) |   if (d) | ||||||
|     { |     { | ||||||
|       if (!in_forkee) |       if (!in_forkee) | ||||||
| 	d->count++;	/* Yes.  Bump the usage count. */ | 	d->count++;	/* Yes.  Bump the usage count. */ | ||||||
|       else if (d->handle != h) |       else if (d->handle != h) | ||||||
| 	fabort ("%W: Loaded to different address: parent(%p) != child(%p)", | 	fabort ("%W: Loaded to different address: parent(%p) != child(%p)", | ||||||
| 		name, d->handle, h); | 		modname, d->handle, h); | ||||||
|       d->p = p; |       d->p = p; | ||||||
|     } |     } | ||||||
|   else |   else | ||||||
| @@ -156,6 +154,7 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) | |||||||
| 	 supplied info about this DLL. */ | 	 supplied info about this DLL. */ | ||||||
|       d->count = 1; |       d->count = 1; | ||||||
|       wcscpy (d->name, name); |       wcscpy (d->name, name); | ||||||
|  |       d->modname = d->name + (modname - name); | ||||||
|       d->handle = h; |       d->handle = h; | ||||||
|       d->has_dtors = true; |       d->has_dtors = true; | ||||||
|       d->p = p; |       d->p = p; | ||||||
| @@ -240,9 +239,9 @@ dll_list::topsort () | |||||||
|   while ((d = d->next)) |   while ((d = d->next)) | ||||||
|     { |     { | ||||||
| #ifdef DEBUGGING | #ifdef DEBUGGING | ||||||
|       paranoid_printf ("%W", d->name); |       paranoid_printf ("%W", d->modname); | ||||||
|       for (int i = 1; i < -d->ndeps; i++) |       for (int i = 1; i < -d->ndeps; i++) | ||||||
| 	paranoid_printf ("-> %W", d->deps[i - 1]->name); | 	paranoid_printf ("-> %W", d->deps[i - 1]->modname); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|       /* It would be really nice to be able to keep this information |       /* It would be really nice to be able to keep this information | ||||||
| @@ -409,7 +408,7 @@ dll_list::reserve_space () | |||||||
|   for (dll* d = dlls.istart (DLL_LOAD); d; d = dlls.inext ()) |   for (dll* d = dlls.istart (DLL_LOAD); d; d = dlls.inext ()) | ||||||
|     if (!VirtualAlloc (d->handle, d->image_size, MEM_RESERVE, PAGE_NOACCESS)) |     if (!VirtualAlloc (d->handle, d->image_size, MEM_RESERVE, PAGE_NOACCESS)) | ||||||
|       fabort ("address space needed by '%W' (%p) is already occupied", |       fabort ("address space needed by '%W' (%p) is already occupied", | ||||||
| 	      d->name, d->handle); | 	      d->modname, d->handle); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Reload DLLs after a fork.  Iterates over the list of dynamically loaded | /* Reload DLLs after a fork.  Iterates over the list of dynamically loaded | ||||||
| @@ -455,33 +454,32 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries) | |||||||
| 	 */ | 	 */ | ||||||
| 	if (!retries && !VirtualFree (d->handle, 0, MEM_RELEASE)) | 	if (!retries && !VirtualFree (d->handle, 0, MEM_RELEASE)) | ||||||
| 	  fabort ("unable to release protective reservation for %W (%08lx), %E", | 	  fabort ("unable to release protective reservation for %W (%08lx), %E", | ||||||
| 		  d->name, d->handle); | 		  d->modname, d->handle); | ||||||
|  |  | ||||||
| 	HMODULE h = LoadLibraryExW (d->name, NULL, DONT_RESOLVE_DLL_REFERENCES); | 	HMODULE h = LoadLibraryExW (d->name, NULL, DONT_RESOLVE_DLL_REFERENCES); | ||||||
| 	if (!h) | 	if (!h) | ||||||
| 	  fabort ("unable to create interim mapping for %W, %E", | 	  fabort ("unable to create interim mapping for %W, %E", d->name); | ||||||
| 		  d->name); |  | ||||||
| 	if (h != d->handle) | 	if (h != d->handle) | ||||||
| 	  { | 	  { | ||||||
| 	    sigproc_printf ("%W loaded in wrong place: %08lx != %08lx", | 	    sigproc_printf ("%W loaded in wrong place: %08lx != %08lx", | ||||||
| 			    d->name, h, d->handle); | 			    d->modname, h, d->handle); | ||||||
| 	    FreeLibrary (h); | 	    FreeLibrary (h); | ||||||
| 	    DWORD reservation = reserve_at (d->name, (DWORD) h, | 	    DWORD reservation = reserve_at (d->modname, (DWORD) h, | ||||||
| 					    (DWORD) d->handle, d->image_size); | 					    (DWORD) d->handle, d->image_size); | ||||||
| 	    if (!reservation) | 	    if (!reservation) | ||||||
| 	      fabort ("unable to block off %p to prevent %W from loading there", | 	      fabort ("unable to block off %p to prevent %W from loading there", | ||||||
| 		      h, d->name); | 		      h, d->modname); | ||||||
|  |  | ||||||
| 	    if (retries < DLL_RETRY_MAX) | 	    if (retries < DLL_RETRY_MAX) | ||||||
| 	      load_after_fork_impl (parent, d, retries+1); | 	      load_after_fork_impl (parent, d, retries+1); | ||||||
| 	    else | 	    else | ||||||
| 	       fabort ("unable to remap %W to same address as parent (%08lx) - try running rebaseall", | 	       fabort ("unable to remap %W to same address as parent (%08lx) - try running rebaseall", | ||||||
| 		       d->name, d->handle); | 		       d->modname, d->handle); | ||||||
|  |  | ||||||
| 	    /* once the above returns all the dlls are mapped; release | 	    /* once the above returns all the dlls are mapped; release | ||||||
| 	       the reservation and continue unwinding */ | 	       the reservation and continue unwinding */ | ||||||
| 	    sigproc_printf ("releasing blocked space at %08lx", reservation); | 	    sigproc_printf ("releasing blocked space at %08lx", reservation); | ||||||
| 	    release_at (d->name, reservation); | 	    release_at (d->modname, reservation); | ||||||
| 	    return; | 	    return; | ||||||
| 	  } | 	  } | ||||||
|       } |       } | ||||||
| @@ -497,7 +495,7 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries) | |||||||
| 	{ | 	{ | ||||||
| 	  if (!VirtualFree (d->handle, 0, MEM_RELEASE)) | 	  if (!VirtualFree (d->handle, 0, MEM_RELEASE)) | ||||||
| 	    fabort ("unable to release protective reservation for %W (%08lx), %E", | 	    fabort ("unable to release protective reservation for %W (%08lx), %E", | ||||||
| 		    d->name, d->handle); | 		    d->modname, d->handle); | ||||||
| 	} | 	} | ||||||
|       else |       else | ||||||
| 	{ | 	{ | ||||||
| @@ -505,14 +503,14 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries) | |||||||
| 	     to ours or we wouldn't have gotten this far */ | 	     to ours or we wouldn't have gotten this far */ | ||||||
| 	  if (!FreeLibrary (d->handle)) | 	  if (!FreeLibrary (d->handle)) | ||||||
| 	    fabort ("unable to unload interim mapping of %W, %E", | 	    fabort ("unable to unload interim mapping of %W, %E", | ||||||
| 		    d->name); | 		    d->modname); | ||||||
| 	} | 	} | ||||||
|       HMODULE h = LoadLibraryW (d->name); |       HMODULE h = LoadLibraryW (d->name); | ||||||
|       if (!h) |       if (!h) | ||||||
| 	fabort ("unable to map %W, %E", d->name); | 	fabort ("unable to map %W, %E", d->name); | ||||||
|       if (h != d->handle) |       if (h != d->handle) | ||||||
| 	fabort ("unable to map %W to same address as parent: %p != %p", | 	fabort ("unable to map %W to same address as parent: %p != %p", | ||||||
| 		d->name, d->handle, h); | 		d->modname, d->handle, h); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -56,6 +56,7 @@ struct dll | |||||||
|   dll** deps; |   dll** deps; | ||||||
|   DWORD image_size; |   DWORD image_size; | ||||||
|   void* preferred_base; |   void* preferred_base; | ||||||
|  |   PWCHAR modname; | ||||||
|   WCHAR name[1]; |   WCHAR name[1]; | ||||||
|   void detach (); |   void detach (); | ||||||
|   int init (); |   int init (); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user