From ceb579a3f8b7698868817f4fb0a36742f0494b28 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 21 Oct 2000 00:02:39 +0000 Subject: Update. 2000-10-19 H.J. Lu * elf/Makefile (distribute): Add neededtest.c, neededobj1.c, neededobj2.c and neededobj3.c. (tests): Add neededtest. (modules-names): Add neededobj1, neededobj2 and neededobj3. ($(objpfx)neededobj1.so): New target. ($(objpfx)neededobj2.so): Likewise. ($(objpfx)neededobj3.so): Likewise. ($(objpfx)neededtest): Likewise. ($(objpfx)neededtest.out): Likewise. * elf/neededtest.c: New. Based on the bug report from Allen Bauer . * elf/neededobj1.c: Likewise. * elf/neededobj2.c: Likewise. * elf/neededobj3.c: Likewise. 2000-10-20 Ulrich Drepper * elf/dl-close.c (_dl_close): Decrement reference counter for all dependencies even if the DSO does not get unloaded. * elf/dl-load.c (_dl_map_object_from_fd): Pass pointer to ELF header to elf_machine_matches_host. * sysdeps/alpha/dl-machine.h (elf_machine_matches_host): Parameter is now pointer to ELF header. * sysdeps/arm/dl-machine.h: Likewise. * sysdeps/generic/dl-machine.h: Likewise. * sysdeps/hppa/dl-machine.h: Likewise. * sysdeps/i386/dl-machine.h: Likewise. * sysdeps/ia64/dl-machine.h: Likewise. * sysdeps/m68k/dl-machine.h: Likewise. * sysdeps/mips/dl-machine.h: Likewise. * sysdeps/mips/mips64/dl-machine.h: Likewise. * sysdeps/powerpc/dl-machine.h: Likewise. * sysdeps/s390/dl-machine.h: Likewise. * sysdeps/sh/dl-machine.h: Likewise. * sysdeps/sparc/sparc32/dl-machine.h: Likewise. * sysdeps/sparc/sparc64/dl-machine.h: Likewise. Patch by Martin Schwidefsksy . 2000-10-20 Jakub Jelinek * include/limits.h: Include bits/wordsize.h, use #if __WORDSIZE == 64 check instead of #ifdef __alpha__. * include/bits/xopen_lim.h (WORD_BIT, LONG_BIT): Don't count on INT_MAX, __INT_MAX__, LONG_MAX or __LONG_MAX__ being defined when this is included. * posix/wordexp-tst.sh (testout): Place output file in build directory. Patch by Joseph S. Myers . --- elf/Makefile | 17 +++++++-- elf/dl-close.c | 14 +++++--- elf/dl-load.c | 2 +- elf/neededobj1.c | 4 +++ elf/neededobj2.c | 7 ++++ elf/neededobj3.c | 9 +++++ elf/neededtest.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 elf/neededobj1.c create mode 100644 elf/neededobj2.c create mode 100644 elf/neededobj3.c create mode 100644 elf/neededtest.c (limited to 'elf') diff --git a/elf/Makefile b/elf/Makefile index 917a745146..d38524d040 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -53,7 +53,8 @@ distribute := $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \ nodlopenmod.c nodelete.c nodelmod1.c nodelmod2.c \ nodelmod3.c nodelmod4.c nodlopen.c dl-osinfo.h \ reldepmod1.c reldepmod2.c reldepmod3.c reldepmod4.c \ - nextmod1.c nextmod2.c + nextmod1.c nextmod2.c \ + neededtest.c neededobj1.c neededobj2.c neededobj3.c include ../Makeconfig @@ -95,7 +96,7 @@ ifeq (yes,$(build-shared)) 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)) + $(tests-nodlopen-$(have-z-nodlopen)) neededtest tests-vis-yes = vismain tests-nodelete-yes = nodelete tests-nodlopen-yes = nodlopen @@ -105,7 +106,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ dep1 dep2 dep3 dep4 $(modules-vis-$(have-protected)) \ $(modules-nodelete-$(have-z-nodelete)) \ $(modules-nodlopen-$(have-z-nodlopen)) filtmod1 filtmod2 \ - reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 + reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \ + neededobj1 neededobj2 neededobj3 modules-vis-yes = vismod1 vismod2 vismod3 modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4 modules-nodlopen-yes = nodlopenmod @@ -249,6 +251,10 @@ $(objpfx)dep4.so: $(objpfx)dep3.so $(objpfx)nodelmod3.so: $(objpfx)nodelmod4.so $(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) + # filtmod1.so has a special rule $(filter-out $(objpfx)filtmod1.so, $(test-modules)): $(objpfx)%.so: $(objpfx)%.os $(build-module) @@ -258,6 +264,11 @@ LDFLAGS-loadtest = -rdynamic $(objpfx)loadtest.out: $(test-modules) +$(objpfx)neededtest: $(libdl) + +$(objpfx)neededtest.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \ + $(objpfx)neededobj3.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 8426e73ec9..03c38d906f 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -61,6 +61,9 @@ _dl_close (void *_map) /* Acquire the lock. */ __libc_lock_lock (_dl_load_lock); + list = map->l_searchlist.r_list; + nsearchlist = map->l_searchlist.r_nlist; + /* Decrement the reference count. */ if (map->l_opencount > 1 || map->l_type != lt_loaded) { @@ -78,14 +81,17 @@ _dl_close (void *_map) "\n", NULL); } - --map->l_opencount; + /* Even if we don't unload it now, we still have to decrement + `l_opencount' of the dependencies. Otherwise, they may not + get unloaded later. */ + for (i = 0; i < nsearchlist; ++i) + if (! (list[i]->l_flags_1 & DF_1_NODELETE)) + --list[i]->l_opencount; + __libc_lock_unlock (_dl_load_lock); return; } - list = map->l_searchlist.r_list; - nsearchlist = map->l_searchlist.r_nlist; - rellist = map->l_reldeps; nrellist = map->l_reldepsact; diff --git a/elf/dl-load.c b/elf/dl-load.c index 81ac23371b..b2f5ad7a1c 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -851,7 +851,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname, if (__builtin_expect (header->e_version, EV_CURRENT) != EV_CURRENT) LOSE (0, N_("ELF file version does not match current one")); - if (! __builtin_expect (elf_machine_matches_host (header->e_machine), 1)) + if (! __builtin_expect (elf_machine_matches_host (header), 1)) LOSE (0, N_("ELF file machine architecture does not match")); if (__builtin_expect (header->e_phentsize, sizeof (ElfW(Phdr))) != sizeof (ElfW(Phdr))) diff --git a/elf/neededobj1.c b/elf/neededobj1.c new file mode 100644 index 0000000000..12c5184cc8 --- /dev/null +++ b/elf/neededobj1.c @@ -0,0 +1,4 @@ +void +c_function (void) +{ +} diff --git a/elf/neededobj2.c b/elf/neededobj2.c new file mode 100644 index 0000000000..22b0e4c794 --- /dev/null +++ b/elf/neededobj2.c @@ -0,0 +1,7 @@ +extern void c_function (void); + +void +b_function (void) +{ + c_function(); +} diff --git a/elf/neededobj3.c b/elf/neededobj3.c new file mode 100644 index 0000000000..0fc94e2112 --- /dev/null +++ b/elf/neededobj3.c @@ -0,0 +1,9 @@ +extern void b_function (void); +extern void c_function (void); + +void +a_function (void) +{ + b_function (); + c_function (); +} diff --git a/elf/neededtest.c b/elf/neededtest.c new file mode 100644 index 0000000000..053d5528aa --- /dev/null +++ b/elf/neededtest.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include + +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\n", lm->l_name); + 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; + const char *loaded[] = { NULL, NULL, NULL, NULL }; + int errors = 0; + + printf ("\nThis is what is in memory now:\n"); + 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); + } + printf ("And this is what is now in memory\n"); + loaded[0] = "neededobj1.so"; + loaded[1] = "neededobj2.so"; + loaded[2] = "neededobj3.so"; + 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); + } + printf ("Again, this is what is in memory\n"); + errors += check_loaded_objects (loaded); + printf ("Closing neededobj2.so\n"); + dlclose (obj2); + errors += check_loaded_objects (loaded); + printf ("Closing neededobj3.so\n"); + dlclose (obj3); + loaded[0] = NULL; + errors += check_loaded_objects (loaded); + if (errors != 0) + printf ("%d errorss found\n", errors); + return errors; +} -- cgit v1.2.3