aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2011-08-16 14:44:26 +0000
committerCorinna Vinschen <corinna@vinschen.de>2011-08-16 14:44:26 +0000
commit6bc64eac26739db38c9ecc99ab26599bd4b4310e (patch)
treef90d5e7fa987e46c3f43a831913048ddd5099730
parent56c387b1b32a36204de6071cc4d192561bb359ed (diff)
downloadnewlib-6bc64eac26739db38c9ecc99ab26599bd4b4310e.zip
newlib-6bc64eac26739db38c9ecc99ab26599bd4b4310e.tar.gz
newlib-6bc64eac26739db38c9ecc99ab26599bd4b4310e.tar.bz2
* autoload.cc (GetModuleHandleExW): Define.
* dlfcn.cc: Throughout mark exported symbols as extern "C". (dlopen): Unignore flags argument. Define ret to NULL. Fix typo in comment. Support Glibc flags RTLD_NOLOAD and RTLD_NODELETE. * include/dlfcn.h: Clean up comments. (RTLD_NODELETE): Define. (RTLD_NOLOAD): Define. (RTLD_DEEPBIND): Define.
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/autoload.cc1
-rw-r--r--winsup/cygwin/dlfcn.cc36
-rw-r--r--winsup/cygwin/include/dlfcn.h18
4 files changed, 50 insertions, 16 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 2c97801..c4d0290 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,14 @@
+2011-08-16 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc (GetModuleHandleExW): Define.
+ * dlfcn.cc: Throughout mark exported symbols as extern "C".
+ (dlopen): Unignore flags argument. Define ret to NULL. Fix typo in
+ comment. Support Glibc flags RTLD_NOLOAD and RTLD_NODELETE.
+ * include/dlfcn.h: Clean up comments.
+ (RTLD_NODELETE): Define.
+ (RTLD_NOLOAD): Define.
+ (RTLD_DEEPBIND): Define.
+
2011-08-15 Corinna Vinschen <corinna@vinschen.de>
* pipe.cc (pipe): Just call _pipe with O_BINARY mode. Move code to
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 63355b4..f8a7a0c 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -390,6 +390,7 @@ LoadDLLfunc (GetNetworkParams, 8, iphlpapi)
LoadDLLfunc (GetUdpTable, 12, iphlpapi)
LoadDLLfuncEx (AttachConsole, 4, kernel32, 1)
+LoadDLLfuncEx (GetModuleHandleExW, 12, kernel32, 1)
LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1)
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
index ff1be8d..91ffc9a 100644
--- a/winsup/cygwin/dlfcn.cc
+++ b/winsup/cygwin/dlfcn.cc
@@ -67,10 +67,10 @@ get_full_path_of_dll (const char* str, path_conv &real_filename)
return false;
}
-void *
-dlopen (const char *name, int)
+extern "C" void *
+dlopen (const char *name, int flags)
{
- void *ret;
+ void *ret = NULL;
if (name == NULL)
{
@@ -82,16 +82,14 @@ dlopen (const char *name, int)
{
/* handle for the named library */
path_conv pc;
- if (!get_full_path_of_dll (name, pc))
- ret = NULL;
- else
+ if (get_full_path_of_dll (name, pc))
{
tmp_pathbuf tp;
wchar_t *path = tp.w_get ();
pc.get_wide_win32_path (path);
/* Check if the last path component contains a dot. If so,
- leave the filename alone. Otherwise add a traiing dot
+ leave the filename alone. Otherwise add a trailing dot
to override LoadLibrary's automatic adding of a ".dll" suffix. */
wchar_t *last_bs = wcsrchr (path, L'\\');
if (last_bs && !wcschr (last_bs, L'.'))
@@ -113,7 +111,23 @@ dlopen (const char *name, int)
struct per_process_cxx_malloc *tmp_malloc;
tmp_malloc = __cygwin_user_data.cxx_malloc;
- ret = (void *) LoadLibraryW (path);
+ if (!(flags & RTLD_NOLOAD)
+ || (ret = GetModuleHandleW (path)) != NULL)
+ {
+ ret = (void *) LoadLibraryW (path);
+ if (ret && (flags & RTLD_NODELETE)
+ && !GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN, path,
+ (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);
+ }
+ }
/* Restore original cxx_malloc pointer. */
__cygwin_user_data.cxx_malloc = tmp_malloc;
@@ -130,7 +144,7 @@ dlopen (const char *name, int)
return ret;
}
-void *
+extern "C" void *
dlsym (void *handle, const char *name)
{
void *ret = NULL;
@@ -176,7 +190,7 @@ dlsym (void *handle, const char *name)
return ret;
}
-int
+extern "C" int
dlclose (void *handle)
{
int ret;
@@ -191,7 +205,7 @@ dlclose (void *handle)
return ret;
}
-char *
+extern "C" char *
dlerror ()
{
char *res;
diff --git a/winsup/cygwin/include/dlfcn.h b/winsup/cygwin/include/dlfcn.h
index 56a7fb4..9ffbdb3 100644
--- a/winsup/cygwin/include/dlfcn.h
+++ b/winsup/cygwin/include/dlfcn.h
@@ -1,6 +1,6 @@
/* dlfcn.h
- Copyright 1998, 1999, 2000, 2001, 2010 Red Hat, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2010, 2011 Red Hat, Inc.
This file is part of Cygwin.
@@ -31,10 +31,18 @@ extern void dlfork (int);
#define RTLD_DEFAULT NULL
/* valid values for mode argument to dlopen */
-#define RTLD_LOCAL 0 /* symbols in this dlopen'ed obj are not visible to other dlopen'ed objs */
-#define RTLD_LAZY 1 /* lazy function call binding */
-#define RTLD_NOW 2 /* immediate function call binding */
-#define RTLD_GLOBAL 4 /* symbols in this dlopen'ed obj are visible to other dlopen'ed objs */
+#define RTLD_LOCAL 0 /* Symbols in this dlopen'ed obj are not */
+ /* visible to other dlopen'ed objs. */
+#define RTLD_LAZY 1 /* Lazy function call binding. */
+#define RTLD_NOW 2 /* Immediate function call binding. */
+#define RTLD_GLOBAL 4 /* Symbols in this dlopen'ed obj are visible */
+ /* to other dlopen'ed objs. */
+/* Non-standard GLIBC extensions */
+#define RTLD_NODELETE 8 /* Don't unload lib in dlcose. */
+#define RTLD_NOLOAD 16 /* Don't load lib, just return handle if lib */
+ /* is already loaded, NULL otherwise. */
+#define RTLD_DEEPBIND 32 /* Place lookup scope so that this lib is */
+ /* preferred over global scope. */
#ifdef __cplusplus
}