diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2011-08-17 00:08:34 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2011-08-17 00:08:34 +0400 |
commit | 833db5481f1f86745979d3ceda580c2d8fdd24a8 (patch) | |
tree | b7aca64ec232f5fd51b5a4c84187b9fb10e8ce7e /winsup/cygwin/dlfcn.cc | |
parent | 9d3b795b47430b4518e5fafb6fb29a96d4bb8f0c (diff) |
* dlfcn.cc (dlopen): Reimplement RTLD_NODELETE for Windows 2000 using
internal datastructures. Explain the code.
* ntdll.h (struct _LDR_DATA_TABLE_ENTRY): Define.
(struct _PEB_LDR_DATA): Define.
(struct _PEB): Change PVOID LoaderData to PPEB_LDR_DATA Ldr.
* fhandler_process.cc (format_process_maps): Call NtQueryVirtualMemory
with valid return length pointer. Explain why.
Diffstat (limited to 'winsup/cygwin/dlfcn.cc')
-rw-r--r-- | winsup/cygwin/dlfcn.cc | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc index 91ffc9a6c..fbcdfedfb 100644 --- a/winsup/cygwin/dlfcn.cc +++ b/winsup/cygwin/dlfcn.cc @@ -120,12 +120,27 @@ dlopen (const char *name, int flags) (HMODULE *) &ret)) { /* Windows 2000 is missing the GetModuleHandleEx call, so we - just use a trick. Call LoadLibrary 10 times more if the - RTLD_NODELETE flag has been specified. That makes it - unlikely (but not impossible) that dlclose will actually - free the library. */ - for (int i = 0; i < 10; ++i) - LoadLibraryW (path); + use a non-documented way to set the DLL to "don't free". + This is how it works: Fetch the Windows Loader data from + the PEB. Iterate backwards through the list of loaded + DLLs and compare the DllBase address with the address + returned by LoadLibrary. If they are equal we found the + right entry. Now set the LoadCount to -1, which is the + marker for a DLL which should never be free'd. */ + PPEB_LDR_DATA ldr = NtCurrentTeb ()->Peb->Ldr; + + for (PLDR_DATA_TABLE_ENTRY entry = (PLDR_DATA_TABLE_ENTRY) + ldr->InLoadOrderModuleList.Blink; + entry && entry->DllBase; + entry = (PLDR_DATA_TABLE_ENTRY) + entry->InLoadOrderLinks.Blink) + { + if (entry->DllBase == ret) + { + entry->LoadCount = (WORD) -1; + break; + } + } } } |