Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 21 Oct 2000 02:07:22 +0000 (02:07 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 21 Oct 2000 02:07:22 +0000 (02:07 +0000)
* elf/Makefile: Add rules to build and run unload2.
* elf/unload2.c: New file.
* elf/unload2mod.c: New file.
* elf/unload2dep.c: New file.

* intl/libintl.h (ngettext macro): Add missing parameter.
(dngettext macro): Likewise.

ChangeLog
elf/Makefile
elf/dl-close.c
elf/unload2.c [new file with mode: 0644]
elf/unload2dep.c [new file with mode: 0644]
elf/unload2mod.c [new file with mode: 0644]

index a7c5b4e..a42615d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,12 @@
 2000-10-20  Ulrich Drepper  <drepper@redhat.com>
 
-       * intl/libintl.h (ngettext): Add missing parameter.
-       (dngettext): Likewise.
+       * elf/Makefile: Add rules to build and run unload2.
+       * elf/unload2.c: New file.
+       * elf/unload2mod.c: New file.
+       * elf/unload2dep.c: New file.
+
+       * intl/libintl.h (ngettext macro): Add missing parameter.
+       (dngettext macro): Likewise.
 
 2000-10-19  H.J. Lu  <hjl@gnu.org>
 
@@ -22,9 +27,6 @@
 
 2000-10-20  Ulrich Drepper  <drepper@redhat.com>
 
-       * 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
index d38524d..033b0dc 100644 (file)
@@ -54,7 +54,8 @@ distribute    := $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
                   nodelmod3.c nodelmod4.c nodlopen.c dl-osinfo.h \
                   reldepmod1.c reldepmod2.c reldepmod3.c reldepmod4.c \
                   nextmod1.c nextmod2.c \
-                  neededtest.c neededobj1.c neededobj2.c neededobj3.c
+                  neededobj1.c neededobj2.c neededobj3.c \
+                  unload2mod.c unload2dep.c
 
 include ../Makeconfig
 
@@ -96,7 +97,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)) neededtest
+       $(tests-nodlopen-$(have-z-nodlopen)) neededtest unload2
 tests-vis-yes = vismain
 tests-nodelete-yes = nodelete
 tests-nodlopen-yes = nodlopen
@@ -107,7 +108,7 @@ 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
+               neededobj1 neededobj2 neededobj3 unload2mod unload2dep
 modules-vis-yes = vismod1 vismod2 vismod3
 modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4
 modules-nodlopen-yes = nodlopenmod
@@ -250,10 +251,10 @@ $(objpfx)dep2.so: $(objpfx)dep3.so $(objpfx)dep4.so
 $(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)
+$(objpfx)unload2mod.so: $(objpfx)unload2dep.so
 
 # filtmod1.so has a special rule
 $(filter-out $(objpfx)filtmod1.so, $(test-modules)): $(objpfx)%.so: $(objpfx)%.os
@@ -352,3 +353,6 @@ $(objpfx)reldep3: $(libdl)
 $(objpfx)reldep3.out: $(objpfx)reldepmod1.so $(objpfx)reldepmod4.so
 
 $(objpfx)next: $(objpfx)nextmod1.so $(objpfx)nextmod2.so $(libdl)
+
+$(objpfx)unload2: $(libdl)
+$(objpfx)unload2.out: $(objpfx)unload2mod.so $(objpfx)unload2dep.so
index 03c38d9..8426e73 100644 (file)
@@ -61,9 +61,6 @@ _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)
     {
@@ -81,17 +78,14 @@ _dl_close (void *_map)
                             "\n", NULL);
        }
 
-      /* 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;
-
+      --map->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/unload2.c b/elf/unload2.c
new file mode 100644 (file)
index 0000000..b544e79
--- /dev/null
@@ -0,0 +1,56 @@
+#include <dlfcn.h>
+#include <elf.h>
+#include <errno.h>
+#include <error.h>
+#include <link.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define OUT \
+  for (map = _r_debug.r_map; map != NULL; map = map->l_next)                 \
+    if (map->l_type == lt_loaded)                                            \
+      printf ("name = \"%s\", opencount = %d\n",                             \
+             map->l_name, (int) map->l_opencount)
+
+int
+main (void)
+{
+  void *h[3];
+  struct link_map *map;
+  void (*fp) (void);
+
+  h[0] = dlopen ("unload2mod.so", RTLD_LAZY);
+  h[1] = dlopen ("unload2mod.so", RTLD_LAZY);
+  if (h[0] == NULL || h[1] == NULL)
+    error (EXIT_FAILURE, errno, "cannot load \"unload2mod.so\"");
+  h[2] = dlopen ("unload2dep.so", RTLD_LAZY);
+  if (h[2] == NULL)
+    error (EXIT_FAILURE, errno, "cannot load \"unload2dep.so\"");
+
+  puts ("\nAfter loading everything:");
+  OUT;
+
+  dlclose (h[0]);
+
+  puts ("\nAfter unloading \"unload2mod.so\" once:");
+  OUT;
+
+  dlclose (h[1]);
+
+  puts ("\nAfter unloading \"unload2mod.so\" twice:");
+  OUT;
+
+  fp = dlsym (h[2], "foo");
+  puts ("\nnow calling `foo'");
+  fflush (stdout);
+  fp ();
+  puts ("managed to call `foo'");
+  fflush (stdout);
+
+  dlclose (h[2]);
+
+  puts ("\nAfter unloading \"unload2dep.so\":");
+  OUT;
+
+  return 0;
+}
diff --git a/elf/unload2dep.c b/elf/unload2dep.c
new file mode 100644 (file)
index 0000000..cd0130c
--- /dev/null
@@ -0,0 +1,4 @@
+void
+foo (void)
+{
+}
diff --git a/elf/unload2mod.c b/elf/unload2mod.c
new file mode 100644 (file)
index 0000000..eae278d
--- /dev/null
@@ -0,0 +1,7 @@
+extern void foo (void);
+
+void
+bar (void)
+{
+  foo ();
+}