about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--elf/dl-close.c11
-rw-r--r--elf/dl-deps.c18
-rw-r--r--elf/dl-load.c15
-rw-r--r--elf/dl-lookup.c8
-rw-r--r--elf/loadtest.c14
-rw-r--r--elf/neededtest.c9
-rw-r--r--elf/unload2.c3
8 files changed, 71 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index a42615d10e..ba79bf8855 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2000-10-20  Ulrich Drepper  <drepper@redhat.com>
 
+	* elf/dl-close.c: Decrement opencount for all dependencies which can
+	be removed even if the object is not yet unloaded.
+	* elf/dl-deps.c (_dl_map_object_deps): If dependency is already in
+	the list decrement opencount of all dependencies.
+	* elf/dl-load.c (_dl_map_object_from_fd): Increment object of object
+	and all dependencies.
+	(_dl_map_object): Likewise.
+	* elf/dl-lookup.c (add_dependency): Likewise.
+
+	* elf/loadtest.c: Add debug when with more output.
+
 	* elf/Makefile: Add rules to build and run unload2.
 	* elf/unload2.c: New file.
 	* elf/unload2mod.c: New file.
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 8426e73ec9..cb6b6fc381 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,14 @@ _dl_close (void *_map)
 			     "\n", NULL);
 	}
 
-      --map->l_opencount;
+      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-deps.c b/elf/dl-deps.c
index 44838d6208..566073eb7a 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -244,11 +244,16 @@ _dl_map_object_deps (struct link_map *map,
 		++nduplist;
 
 		if (dep->l_reserved)
-		  /* This object is already in the search list we are
-		     building.  Don't add a duplicate pointer.
-		     Release the reference just added by
-		     _dl_map_object.  */
-		  --dep->l_opencount;
+		  {
+		    /* This object is already in the search list we are
+		       building.  Don't add a duplicate pointer.
+		       Release the reference just added by
+		       _dl_map_object.  */
+		    if (dep->l_initfini != NULL)
+		      for (i = 1; dep->l_initfini[i] != NULL; ++i)
+			--dep->l_initfini[i]->l_opencount;
+		    --dep->l_opencount;
+		  }
 		else
 		  {
 		    /* Append DEP to the unique list.  */
@@ -360,6 +365,9 @@ _dl_map_object_deps (struct link_map *map,
 		       are building.  Don't add a duplicate pointer.
 		       Release the reference just added by
 		       _dl_map_object.  */
+		    if (args.aux->l_initfini != NULL)
+		      for (i = 1; args.aux->l_initfini[i] != NULL; ++i)
+			--args.aux->l_initfini[i]->l_opencount;
 		    --args.aux->l_opencount;
 
 		    for (late = newp; late->unique; late = late->unique)
diff --git a/elf/dl-load.c b/elf/dl-load.c
index b2f5ad7a1c..55725c3cb3 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -777,6 +777,8 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
   for (l = _dl_loaded; l; l = l->l_next)
     if (l->l_ino == st.st_ino && l->l_dev == st.st_dev)
       {
+	unsigned int i;
+
 	/* The object is already loaded.
 	   Just bump its reference count and return it.  */
 	__close (fd);
@@ -785,6 +787,10 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 	   it.  */
 	free (realname);
 	add_name_to_object (l, name);
+
+	if (l->l_initfini != NULL)
+	  for (i = 1; l->l_initfini[i] != NULL; ++i)
+	    ++l->l_initfini[i]->l_opencount;
 	++l->l_opencount;
 	return l;
       }
@@ -1396,6 +1402,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
   /* Look for this name among those already loaded.  */
   for (l = _dl_loaded; l; l = l->l_next)
     {
+      unsigned int i;
+
       /* If the requested name matches the soname of a loaded object,
 	 use that object.  Elide this check for names that have not
 	 yet been opened.  */
@@ -1408,8 +1416,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 	  if (l->l_info[DT_SONAME] == NULL)
 	    continue;
 
-	  soname = (const void *) (D_PTR (l, l_info[DT_STRTAB])
-				   + l->l_info[DT_SONAME]->d_un.d_val);
+	  soname = ((const char *) D_PTR (l, l_info[DT_STRTAB])
+		    + l->l_info[DT_SONAME]->d_un.d_val);
 	  if (strcmp (name, soname) != 0)
 	    continue;
 
@@ -1418,6 +1426,9 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 	}
 
       /* We have a match -- bump the reference count and return it.  */
+      if (l->l_initfini != NULL)
+	for (i = 1; l->l_initfini[i] != NULL; ++i)
+	  ++l->l_initfini[i]->l_opencount;
       ++l->l_opencount;
       return l;
     }
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 581c6a6c2b..d9476817c3 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -129,6 +129,8 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
 
 	  if (runp != NULL)
 	    {
+	      unsigned int j;
+
 	      /* The object is still available.  Add the reference now.  */
 	      if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
 		{
@@ -158,7 +160,11 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
 	      if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
 		undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
 
-	      /* And increment the counter in the referenced object.  */
+	      /* And increment the counter in the referenced object
+                 and its dependencies.  */
+	      if (map->l_initfini != NULL)
+		for (j = 1; map->l_initfini[j] != NULL; ++j)
+		  ++map->l_initfini[j]->l_opencount;
 	      ++map->l_opencount;
 
 	      /* Display information if we are debugging.  */
diff --git a/elf/loadtest.c b/elf/loadtest.c
index 80f99607ec..4a3c4c08be 100644
--- a/elf/loadtest.c
+++ b/elf/loadtest.c
@@ -69,10 +69,18 @@ static const struct
 
 #include <include/link.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);			      \
+  fflush (stdout)
+
 
 int
-main (void)
+main (int argc, char *argv[])
 {
+  int debug = argc > 1 && argv[1][0] != '\0';
   int count = TEST_ROUNDS;
   int result = 0;
 
@@ -85,6 +93,7 @@ main (void)
     {
       int nr = random () % NTESTS;
       int index = tests[nr].index;
+      struct link_map *map;
 
       printf ("%4d: %4d: ", count + 1, nr);
       fflush (stdout);
@@ -125,6 +134,9 @@ main (void)
 
 	  testobjs[index].handle = NULL;
 	}
+
+      if (debug)
+	OUT;
     }
 
   /* Unload all loaded modules.  */
diff --git a/elf/neededtest.c b/elf/neededtest.c
index 053d5528aa..98f69a3185 100644
--- a/elf/neededtest.c
+++ b/elf/neededtest.c
@@ -1,8 +1,9 @@
+#include <dlfcn.h>
+#include <libintl.h>
+#include <link.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <dlfcn.h>
-#include <link.h>
 
 static int
 check_loaded_objects (const char **loaded)
@@ -26,7 +27,7 @@ check_loaded_objects (const char **loaded)
   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);
+	printf(" %s, count = %d\n", lm->l_name, (int) lm->l_opencount);
       if (lm->l_type == lt_loaded && lm->l_name)
 	{
 	  int match = 0;
@@ -99,6 +100,6 @@ main (void)
   loaded[0] = NULL;
   errors += check_loaded_objects (loaded);
   if (errors != 0)
-    printf ("%d errorss found\n", errors);
+    printf ("%d errors found\n", errors);
   return errors;
 }
diff --git a/elf/unload2.c b/elf/unload2.c
index b544e794c8..7a38053433 100644
--- a/elf/unload2.c
+++ b/elf/unload2.c
@@ -10,7 +10,8 @@
   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)
+	      map->l_name, (int) map->l_opencount);			      \
+  fflush (stdout)
 
 int
 main (void)