aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@redhat.com>2011-08-24 09:32:13 +0200
committerAndreas Schwab <schwab@redhat.com>2011-08-24 09:32:13 +0200
commit39dd69dfb9b8948720f05455df6775b70238803f (patch)
treeef705bd72d5de79844f371004cb96f372212bc6e /elf
parent22044b48baa8a3c3fe67ab912e9f34a80c97880b (diff)
downloadglibc-39dd69dfb9b8948720f05455df6775b70238803f.zip
glibc-39dd69dfb9b8948720f05455df6775b70238803f.tar.gz
glibc-39dd69dfb9b8948720f05455df6775b70238803f.tar.bz2
Fix scope handling during dl_close
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile10
-rw-r--r--elf/dl-close.c7
-rw-r--r--elf/unload8.c33
-rw-r--r--elf/unload8mod1.c7
-rw-r--r--elf/unload8mod1x.c1
-rw-r--r--elf/unload8mod2.c7
-rw-r--r--elf/unload8mod3.c27
7 files changed, 91 insertions, 1 deletions
diff --git a/elf/Makefile b/elf/Makefile
index aeb6393..bb46601 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -90,6 +90,7 @@ distribute := rtld-Rules \
unload4mod1.c unload4mod2.c unload4mod3.c unload4mod4.c \
unload6mod1.c unload6mod2.c unload6mod3.c \
unload7mod1.c unload7mod2.c \
+ unload8mod1.c unload8mod1x.c unload8mod2.c unload8mod3.c \
tst-audit1.c tst-audit2.c tst-audit3.c tst-audit4.c \
tst-auditmod1.c tst-auditmod3a.c tst-auditmod3b.c \
tst-auditmod4a.c tst-auditmod4b.c \
@@ -224,7 +225,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
tst-dlmodcount tst-dlopenrpath tst-deep1 \
tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
- unload3 unload4 unload5 unload6 unload7 tst-global1 order2 \
+ unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
tst-audit1 tst-audit2 \
tst-stackguard1 tst-addr1 tst-thrlock \
tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
@@ -282,6 +283,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
unload4mod1 unload4mod2 unload4mod3 unload4mod4 \
unload6mod1 unload6mod2 unload6mod3 \
unload7mod1 unload7mod2 \
+ unload8mod1 unload8mod1x unload8mod2 unload8mod3 \
order2mod1 order2mod2 order2mod3 order2mod4 \
tst-unique1mod1 tst-unique1mod2 \
tst-unique2mod1 tst-unique2mod2 \
@@ -570,6 +572,9 @@ $(objpfx)unload6mod2.so: $(libdl)
$(objpfx)unload6mod3.so: $(libdl)
$(objpfx)unload7mod1.so: $(libdl)
$(objpfx)unload7mod2.so: $(objpfx)unload7mod1.so
+$(objpfx)unload8mod1.so: $(objpfx)unload8mod2.so
+$(objpfx)unload8mod2.so: $(objpfx)unload8mod3.so
+$(objpfx)unload8mod3.so: $(libdl)
$(objpfx)tst-initordera2.so: $(objpfx)tst-initordera1.so
$(objpfx)tst-initorderb2.so: $(objpfx)tst-initorderb1.so $(objpfx)tst-initordera2.so
$(objpfx)tst-initordera3.so: $(objpfx)tst-initorderb2.so $(objpfx)tst-initorderb1.so
@@ -883,6 +888,9 @@ $(objpfx)unload7: $(libdl)
$(objpfx)unload7.out: $(objpfx)unload7mod1.so $(objpfx)unload7mod2.so
unload7-ENV = MALLOC_PERTURB_=85
+$(objpfx)unload8: $(libdl)
+$(objpfx)unload8.out: $(objpfx)unload8mod1.so $(objpfx)unload8mod1x.so
+
ifdef libdl
$(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a
$(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 4cf98c3..8fb55d0 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -430,6 +430,13 @@ _dl_close_worker (struct link_map *map)
imap->l_scope_max = new_size;
}
+ else if (new_list != NULL)
+ {
+ /* We didn't change the scope array, so reset the search
+ list. */
+ imap->l_searchlist.r_list = NULL;
+ imap->l_searchlist.r_nlist = 0;
+ }
/* The loader is gone, so mark the object as not having one.
Note: l_idx != IDX_STILL_USED -> object will be removed. */
diff --git a/elf/unload8.c b/elf/unload8.c
new file mode 100644
index 0000000..f984a38
--- /dev/null
+++ b/elf/unload8.c
@@ -0,0 +1,33 @@
+#include <dlfcn.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+ void *h = dlopen ("$ORIGIN/unload8mod1.so", RTLD_LAZY);
+ if (h == NULL)
+ {
+ puts ("dlopen unload8mod1.so failed");
+ return 1;
+ }
+
+ void *h2 = dlopen ("$ORIGIN/unload8mod1x.so", RTLD_LAZY);
+ if (h2 == NULL)
+ {
+ puts ("dlopen unload8mod1x.so failed");
+ return 1;
+ }
+ dlclose (h2);
+
+ int (*mod1) (void) = dlsym (h, "mod1");
+ if (mod1 == NULL)
+ {
+ puts ("dlsym failed");
+ return 1;
+ }
+
+ mod1 ();
+ dlclose (h);
+
+ return 0;
+}
diff --git a/elf/unload8mod1.c b/elf/unload8mod1.c
new file mode 100644
index 0000000..fe7e81c
--- /dev/null
+++ b/elf/unload8mod1.c
@@ -0,0 +1,7 @@
+extern void mod2 (void);
+
+void
+mod1 (void)
+{
+ mod2 ();
+}
diff --git a/elf/unload8mod1x.c b/elf/unload8mod1x.c
new file mode 100644
index 0000000..835b634
--- /dev/null
+++ b/elf/unload8mod1x.c
@@ -0,0 +1 @@
+int mod1x;
diff --git a/elf/unload8mod2.c b/elf/unload8mod2.c
new file mode 100644
index 0000000..2fd8b67
--- /dev/null
+++ b/elf/unload8mod2.c
@@ -0,0 +1,7 @@
+extern void mod3 (void);
+
+void
+mod2 (void)
+{
+ mod3 ();
+}
diff --git a/elf/unload8mod3.c b/elf/unload8mod3.c
new file mode 100644
index 0000000..d49e22b
--- /dev/null
+++ b/elf/unload8mod3.c
@@ -0,0 +1,27 @@
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+mod3_fini2 (void)
+{
+}
+
+void
+mod3_fini (void)
+{
+ mod3_fini2 ();
+}
+
+void
+mod3 (void)
+{
+ void *h = dlopen ("$ORIGIN/unload8mod2.so", RTLD_LAZY);
+ if (h == NULL)
+ {
+ puts ("dlopen unload8mod2.so failed");
+ exit (1);
+ }
+
+ atexit (mod3_fini);
+}