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:
authorCorinna Vinschen <corinna@vinschen.de>2011-05-11 17:25:27 +0400
committerCorinna Vinschen <corinna@vinschen.de>2011-05-11 17:25:27 +0400
commit31ddf45dd8694ffb1c995000cf8600d00eee57e9 (patch)
treec5bcbcee169333bcc79287690731bc0e3c64ff2d /winsup/cygwin/dlfcn.cc
parentb27800ad458c51698e3f265ae980c958f74ad592 (diff)
* 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.cc52
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);