aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2025-03-30 20:09:02 +0200
committerCorinna Vinschen <corinna@vinschen.de>2025-03-30 20:52:34 +0200
commit82b31085f6ad23c3aaf5a928bd56fe06cbe63df5 (patch)
treeb3b64eaa1a641d272a506ad4da0e5ec760c2af0a
parent6c5537c0298e9135ff27119c6a18dcc6f94459f5 (diff)
downloadnewlib-82b31085f6ad23c3aaf5a928bd56fe06cbe63df5.zip
newlib-82b31085f6ad23c3aaf5a928bd56fe06cbe63df5.tar.gz
newlib-82b31085f6ad23c3aaf5a928bd56fe06cbe63df5.tar.bz2
Cygwin: dlfcn: avoid ENOENT on dlcose after dlopen(cygwin1.dll)
When dlopen'ing the Cygwin DLL, refcounting the number of dlopen calls fails because dll_list::find returns NULL if the address resolves to the Cygwin DLL. Fix this by adding a bool parameter to dll_list::find which allows find to return the dll entry for the Cygwin DLL for the sake of dlopen/dlclose/fork. Fixes: 33297d810d90 ("Cygwin: dlfcn: Fix reference counting") Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/dlfcn.cc4
-rw-r--r--winsup/cygwin/dll_init.cc4
-rw-r--r--winsup/cygwin/local_includes/dll_init.h2
-rw-r--r--winsup/cygwin/release/3.6.13
4 files changed, 8 insertions, 5 deletions
diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
index fb70524..f98c7db 100644
--- a/winsup/cygwin/dlfcn.cc
+++ b/winsup/cygwin/dlfcn.cc
@@ -276,7 +276,7 @@ dlopen (const char *name, int flags)
/* reference counting */
if (ret)
{
- dll *d = dlls.find (ret);
+ dll *d = dlls.find (ret, true);
if (d)
++d->count;
}
@@ -349,7 +349,7 @@ dlclose (void *handle)
if (handle != GetModuleHandle (NULL))
{
/* reference counting */
- dll *d = dlls.find (handle);
+ dll *d = dlls.find (handle, true);
if (!d || d->count <= 0)
{
errno = ENOENT;
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index 1a04751..c6fb94a 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -542,7 +542,7 @@ dll_list::topsort_visit (dll* d, bool seek_tail)
dll *
-dll_list::find (void *retaddr)
+dll_list::find (void *retaddr, bool find_self)
{
MEMORY_BASIC_INFORMATION m;
if (!VirtualQuery (retaddr, &m, sizeof m))
@@ -551,7 +551,7 @@ dll_list::find (void *retaddr)
dll *d = &start;
while ((d = d->next))
- if (d->type != DLL_SELF && d->handle == h)
+ if ((d->type != DLL_SELF || find_self) && d->handle == h)
break;
return d;
}
diff --git a/winsup/cygwin/local_includes/dll_init.h b/winsup/cygwin/local_includes/dll_init.h
index 65f4213..f79b157 100644
--- a/winsup/cygwin/local_includes/dll_init.h
+++ b/winsup/cygwin/local_includes/dll_init.h
@@ -131,7 +131,7 @@ public:
int reload_on_fork;
dll *operator [] (PCWCHAR ntname);
dll *alloc (HINSTANCE, per_process *, dll_type);
- dll *find (void *);
+ dll *find (void *, bool = false);
void detach (void *);
void init ();
void load_after_fork (HANDLE);
diff --git a/winsup/cygwin/release/3.6.1 b/winsup/cygwin/release/3.6.1
index 95c2c05..85c3f6c 100644
--- a/winsup/cygwin/release/3.6.1
+++ b/winsup/cygwin/release/3.6.1
@@ -15,3 +15,6 @@ Fixes:
in the SA_ONSTACK case, because locally-copied context on the normal
stack area is not accessible from the signal handler.
Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257714.html
+
+- Fix reference counting when dlopen/dlclose is called on the Cygwin DLL.
+ Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257783.html