From 39dd69dfb9b8948720f05455df6775b70238803f Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Wed, 24 Aug 2011 09:32:13 +0200 Subject: [PATCH] Fix scope handling during dl_close --- ChangeLog | 12 ++++++++++++ elf/Makefile | 10 +++++++++- elf/dl-close.c | 7 +++++++ elf/unload8.c | 33 +++++++++++++++++++++++++++++++++ elf/unload8mod1.c | 7 +++++++ elf/unload8mod1x.c | 1 + elf/unload8mod2.c | 7 +++++++ elf/unload8mod3.c | 27 +++++++++++++++++++++++++++ 8 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 elf/unload8.c create mode 100644 elf/unload8mod1.c create mode 100644 elf/unload8mod1x.c create mode 100644 elf/unload8mod2.c create mode 100644 elf/unload8mod3.c diff --git a/ChangeLog b/ChangeLog index 5399dcfeb0..4fde8c2579 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-08-24 Andreas Schwab + + * elf/Makefile: Add rules to build and run unload8 test. + * elf/unload8.c: New file. + * elf/unload8mod1.c: New file. + * elf/unload8mod1x.c: New file. + * elf/unload8mod2.c: New file. + * elf/unload8mod3.c: New file. + + * elf/dl-close.c (_dl_close_worker): Reset private search list if + it wasn't used. + 2011-08-23 David S. Miller * sysdeps/sparc/sparc64/dl-machine.h (DL_STACK_END): Do not diff --git a/elf/Makefile b/elf/Makefile index aeb63936af..bb46601a3a 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 4cf98c3b99..8fb55d0fbc 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 0000000000..f984a38098 --- /dev/null +++ b/elf/unload8.c @@ -0,0 +1,33 @@ +#include +#include + +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 0000000000..fe7e81c1c3 --- /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 0000000000..835b634914 --- /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 0000000000..2fd8b6768a --- /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 0000000000..d49e22b24c --- /dev/null +++ b/elf/unload8mod3.c @@ -0,0 +1,27 @@ +#include +#include +#include + +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); +}