diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2011-05-11 13:25:27 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2011-05-11 13:25:27 +0000 |
commit | 31ddf45dd8694ffb1c995000cf8600d00eee57e9 (patch) | |
tree | c5bcbcee169333bcc79287690731bc0e3c64ff2d /winsup/cygwin/dlfcn.cc | |
parent | b27800ad458c51698e3f265ae980c958f74ad592 (diff) | |
download | cygnal-31ddf45dd8694ffb1c995000cf8600d00eee57e9.tar.gz cygnal-31ddf45dd8694ffb1c995000cf8600d00eee57e9.tar.bz2 cygnal-31ddf45dd8694ffb1c995000cf8600d00eee57e9.zip |
* autoload.cc (EnumProcessModules): Remove.
* dlfcn.cc (dlopen): Make sure errno is set if an error occurs.
(dlsym): Rewrite using RtlQueryProcessDebugInformation instead of
EnumProcessModules.
* ntdll.h (struct _DEBUG_MODULE_ARRAY): Define.
(RtlCreateQueryDebugBuffer): Declare.
(RtlDestroyQueryDebugBuffer): Declare.
(RtlQueryProcessDebugInformation): Declare.
Diffstat (limited to 'winsup/cygwin/dlfcn.cc')
-rw-r--r-- | winsup/cygwin/dlfcn.cc | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc index fb3df2c5f..6d4580e9e 100644 --- a/winsup/cygwin/dlfcn.cc +++ b/winsup/cygwin/dlfcn.cc @@ -1,6 +1,7 @@ /* dlfcn.cc - Copyright 1998, 2000, 2001, 2002, 2003, 2004, 2008, 2009, 2010 Red Hat, Inc. + Copyright 1998, 2000, 2001, 2002, 2003, 2004, 2008, 2009, 2010, + 2011 Red Hat, Inc. This file is part of Cygwin. @@ -17,6 +18,7 @@ details. */ #include "dlfcn.h" #include "cygtls.h" #include "tls_pbuf.h" +#include "ntdll.h" static void __stdcall set_dl_error (const char *str) @@ -71,7 +73,11 @@ dlopen (const char *name, int) void *ret; if (name == NULL) - ret = (void *) GetModuleHandle (NULL); /* handle for the current module */ + { + ret = (void *) GetModuleHandle (NULL); /* handle for the current module */ + if (!ret) + __seterrno (); + } else { /* handle for the named library */ @@ -112,7 +118,7 @@ dlopen (const char *name, int) /* Restore original cxx_malloc pointer. */ __cygwin_user_data.cxx_malloc = tmp_malloc; - if (ret == NULL) + if (!ret) __seterrno (); } } @@ -128,26 +134,42 @@ void * dlsym (void *handle, const char *name) { void *ret = NULL; + if (handle == RTLD_DEFAULT) { /* search all modules */ - HANDLE cur_proc = GetCurrentProcess (); - HMODULE *modules; - DWORD needed, i; - if (!EnumProcessModules (cur_proc, NULL, 0, &needed)) + PDEBUG_BUFFER buf; + NTSTATUS status; + + buf = RtlCreateQueryDebugBuffer (0, FALSE); + if (!buf) { - dlsym_fail: + set_errno (ENOMEM); set_dl_error ("dlsym"); return NULL; } - modules = (HMODULE*) alloca (needed); - if (!EnumProcessModules (cur_proc, modules, needed, &needed)) - goto dlsym_fail; - for (i = 0; i < needed / sizeof (HMODULE); i++) - if ((ret = (void *) GetProcAddress (modules[i], name))) - break; + status = RtlQueryProcessDebugInformation (GetCurrentProcessId (), + PDI_MODULES, buf); + if (!NT_SUCCESS (status)) + __seterrno_from_nt_status (status); + else + { + PDEBUG_MODULE_ARRAY mods = (PDEBUG_MODULE_ARRAY) + buf->ModuleInformation; + for (ULONG i = 0; i < mods->Count; ++i) + if ((ret = (void *) + GetProcAddress ((HMODULE) mods->Modules[i].Base, name))) + break; + if (!ret) + set_errno (ENOENT); + } + RtlDestroyQueryDebugBuffer (buf); } else - ret = (void *) GetProcAddress ((HMODULE)handle, name); + { + ret = (void *) GetProcAddress ((HMODULE) handle, name); + if (!ret) + __seterrno (); + } if (!ret) set_dl_error ("dlsym"); debug_printf ("ret %p", ret); |