diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | elf/Makefile | 16 | ||||
-rw-r--r-- | elf/dl-close.c | 14 | ||||
-rw-r--r-- | elf/neededtest3.c | 127 |
4 files changed, 155 insertions, 12 deletions
@@ -1,3 +1,13 @@ +2000-10-24 Ulrich Drepper <drepper@redhat.com> + + * elf/dl-close.c (_dl_close): Use correct list (l_initfini) when + computing new opencounts. + * elf/Makefile: Add rules to build and run neededtest3. + * neededtest3.c: New file. + * neededobj4.c: New file. + + * elf/neededtest.c (main): Correct tests for failing dlopen. + 2000-10-24 Andreas Jaeger <aj@suse.de> * elf/dl-lookup.c (add_dependency): Remove unused variable j. diff --git a/elf/Makefile b/elf/Makefile index ad89103..4441692 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -98,7 +98,7 @@ tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ constload1 order $(tests-vis-$(have-protected)) noload filter unload \ reldep reldep2 reldep3 next $(tests-nodelete-$(have-z-nodelete)) \ $(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \ - unload2 lateglobal + neededtest3 unload2 lateglobal tests-vis-yes = vismain tests-nodelete-yes = nodelete tests-nodlopen-yes = nodlopen @@ -109,8 +109,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ $(modules-nodelete-$(have-z-nodelete)) \ $(modules-nodlopen-$(have-z-nodlopen)) filtmod1 filtmod2 \ reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \ - neededobj1 neededobj2 neededobj3 unload2mod unload2dep \ - ltglobmod1 ltglobmod2 + neededobj1 neededobj2 neededobj3 neededobj4 \ + unload2mod unload2dep ltglobmod1 ltglobmod2 modules-vis-yes = vismod1 vismod2 vismod3 modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4 modules-nodlopen-yes = nodlopenmod @@ -256,6 +256,8 @@ $(objpfx)nextmod1.so: $(libdl) $(objpfx)neededobj1.so: $(libdl) $(objpfx)neededobj2.so: $(objpfx)neededobj1.so $(libdl) $(objpfx)neededobj3.so: $(objpfx)neededobj1.so $(objpfx)neededobj2.so $(libdl) +$(objpfx)neededobj4.so: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \ + $(objpfx)neededobj3.so $(libdl) $(objpfx)unload2mod.so: $(objpfx)unload2dep.so $(objpfx)ltglobmod2.so: $(libdl) @@ -270,11 +272,15 @@ $(objpfx)loadtest.out: $(test-modules) $(objpfx)neededtest: $(libdl) $(objpfx)neededtest.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \ - $(objpfx)neededobj3.so + $(objpfx)neededobj3.so $(objpfx)neededtest2: $(libdl) $(objpfx)neededtest2.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \ - $(objpfx)neededobj3.so + $(objpfx)neededobj3.so + +$(objpfx)neededtest3: $(libdl) +$(objpfx)neededtest3.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \ + $(objpfx)neededobj3.so $(objpfx)neededobj4.so $(objpfx)restest1: $(objpfx)testobj1.so $(objpfx)testobj1_1.so $(libdl) LDFLAGS-restest1 = -rdynamic diff --git a/elf/dl-close.c b/elf/dl-close.c index 2130540..4ee5c1b 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -94,23 +94,23 @@ _dl_close (void *_map) * sizeof (unsigned int)); for (i = 0; i < nsearchlist; ++i) { - list[i]->l_idx = i; - new_opencount[i] = list[i]->l_opencount; + map->l_initfini[i]->l_idx = i; + new_opencount[i] = map->l_initfini[i]->l_opencount; } --new_opencount[0]; for (i = 1; i < nsearchlist; ++i) - if (! (list[i]->l_flags_1 & DF_1_NODELETE) + if (! (map->l_initfini[i]->l_flags_1 & DF_1_NODELETE) /* Decrement counter. */ && --new_opencount[i] == 0 /* Test whether this object was also loaded directly. */ - && list[i]->l_searchlist.r_list != NULL) + && map->l_initfini[i]->l_searchlist.r_list != NULL) { /* In this case we have the decrement all the dependencies of this object. They are all in MAP's dependency list. */ unsigned int j; - struct link_map **dep_list = list[i]->l_searchlist.r_list; + struct link_map **dep_list = map->l_initfini[i]->l_searchlist.r_list; - for (j = 1; j < list[i]->l_searchlist.r_nlist; ++j) + for (j = 1; j < map->l_initfini[i]->l_searchlist.r_nlist; ++j) if (! (dep_list[j]->l_flags_1 & DF_1_NODELETE)) { assert (dep_list[j]->l_idx < nsearchlist); @@ -238,7 +238,7 @@ _dl_close (void *_map) { if (imap->l_searchlist.r_list != NULL) free (imap->l_searchlist.r_list); - else if (imap->l_initfini != NULL) + else free (imap->l_initfini); } diff --git a/elf/neededtest3.c b/elf/neededtest3.c new file mode 100644 index 0000000..38b3c6c --- /dev/null +++ b/elf/neededtest3.c @@ -0,0 +1,127 @@ +#include <dlfcn.h> +#include <libintl.h> +#include <link.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static int +check_loaded_objects (const char **loaded) +{ + struct link_map *lm; + int n; + int *found = NULL; + int errors = 0; + + for (n = 0; loaded[n]; n++) + /* NOTHING */; + + if (n) + { + found = (int *) alloca (sizeof (int) * n); + memset (found, 0, sizeof (int) * n); + } + + printf(" Name\n"); + printf(" --------------------------------------------------------\n"); + for (lm = _r_debug.r_map; lm; lm = lm->l_next) + { + if (lm->l_name && lm->l_name[0]) + printf(" %s, count = %d\n", lm->l_name, (int) lm->l_opencount); + if (lm->l_type == lt_loaded && lm->l_name) + { + int match = 0; + for (n = 0; loaded[n] != NULL; n++) + { + if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0) + { + found[n] = 1; + match = 1; + break; + } + } + + if (match == 0) + { + ++errors; + printf ("ERRORS: %s is not unloaded\n", lm->l_name); + } + } + } + + for (n = 0; loaded[n] != NULL; n++) + { + if (found[n] == 0) + { + ++errors; + printf ("ERRORS: %s is not loaded\n", loaded[n]); + } + } + + return errors; +} + +int +main (void) +{ + void *obj2; + void *obj3; + void *obj4; + const char *loaded[] = { NULL, NULL, NULL, NULL, NULL }; + int errors = 0; + + printf ("\nThis is what is in memory now:\n"); + errors += check_loaded_objects (loaded); + + printf ("Now loading shared object neededobj2.so\n"); + obj2 = dlopen ("neededobj2.so", RTLD_LAZY); + if (obj2 == NULL) + { + printf ("%s\n", dlerror ()); + exit (1); + } + loaded[0] = "neededobj1.so"; + loaded[1] = "neededobj2.so"; + errors += check_loaded_objects (loaded); + + printf( "Loading shared object neededobj3.so\n"); + obj3 = dlopen( "neededobj3.so", RTLD_LAZY); + if (obj3 == NULL) + { + printf ("%s\n", dlerror ()); + exit (1); + } + loaded[2] = "neededobj3.so"; + errors += check_loaded_objects (loaded); + + + printf( "Loading shared object neededobj4.so\n"); + obj4 = dlopen( "neededobj4.so", RTLD_LAZY); + if (obj4 == NULL) + { + printf ("%s\n", dlerror ()); + exit (1); + } + loaded[3] = "neededobj4.so"; + errors += check_loaded_objects (loaded); + + printf ("Closing neededobj2.so\n"); + dlclose (obj2); + errors += check_loaded_objects (loaded); + + printf ("Closing neededobj3.so\n"); + dlclose (obj3); + errors += check_loaded_objects (loaded); + + printf ("Closing neededobj4.so\n"); + dlclose (obj4); + loaded[0] = NULL; + loaded[1] = NULL; + loaded[2] = NULL; + loaded[3] = NULL; + errors += check_loaded_objects (loaded); + + if (errors != 0) + printf ("%d errors found\n", errors); + return errors; +} |