about summary refs log tree commit diff
path: root/elf/dl-deps.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-09-08 16:27:08 +0000
committerUlrich Drepper <drepper@redhat.com>2001-09-08 16:27:08 +0000
commitc4bb124a75b23d1a82cee232005dc7e8c43a4276 (patch)
tree070153ee7d895708e4e1b8c69b0d05093c19f17d /elf/dl-deps.c
parent5a21d307c518c911f81848b6c0056fcc39e3ddcd (diff)
downloadglibc-c4bb124a75b23d1a82cee232005dc7e8c43a4276.tar.gz
glibc-c4bb124a75b23d1a82cee232005dc7e8c43a4276.tar.xz
glibc-c4bb124a75b23d1a82cee232005dc7e8c43a4276.zip
Update.
2001-09-08  Ulrich Drepper  <drepper@redhat.com>

	* elf/dl-close.c (_dl_close): If object has no r_list (i.e., wasn't
	loaded directly) determine length if l_initfini list by iterating
	over its elements.  Minor optimizations.
	* elf/dl-deps.c (_dl_map_object_deps): Always add own map to l_initfini
	for dependency objects.
	If object was already loaded check whether any of the dependencies
	is already on the relocation dependency list.  If yes, remove the
	latter.  Minor optimizations.
	* elf/dl-lookup.c (add_dependency): Add check for self reference of
	maps here.  Search l_initfini list only if the object was loaded
	directly and not only as a dependency.
	(_dl_lookup_symbol): Add relocation dependency also if object
	is not in global scope.  Remove test for self-reference here.
	(_dl_lookup_versioned_symbol): Likewise.
	* elf/dl-object (_dl_new_object): Cleanup.  Initialize dont_free
	element of first name record.
	* elf/loadtest.c: Add some more test to recognize early if an object
	wasn't unloaded.
	* elf/Makefile: Add rules to build and run reldep5.
	* elf/reldep5.c: New file.
	* elf/reldepmod5.c: New file.
	* elf/reldepmod6.c: New file.

	* elf/reldep2.c: Fix typo.

	* elf/dl-object.c (_dl_new_object): Initialize l_scope and l_scope_max.
Diffstat (limited to 'elf/dl-deps.c')
-rw-r--r--elf/dl-deps.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index c4bc9874cc..9d91d5ef00 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -448,11 +448,13 @@ _dl_map_object_deps (struct link_map *map,
 	{
 	  needed[nneeded++] = NULL;
 
-	  l->l_initfini = malloc (nneeded * sizeof needed[0]);
+	  l->l_initfini = (struct link_map **)
+	    malloc ((nneeded + 1) * sizeof needed[0]);
 	  if (l->l_initfini == NULL)
 	    _dl_signal_error (ENOMEM, map->l_name, NULL,
 			      N_("cannot allocate dependency list"));
-	  memcpy (l->l_initfini, needed, nneeded * sizeof needed[0]);
+	  l->l_initfini[0] = l;
+	  memcpy (&l->l_initfini[1], needed, nneeded * sizeof needed[0]);
 	}
 
       /* If we have no auxiliary objects just go on to the next map.  */
@@ -462,7 +464,7 @@ _dl_map_object_deps (struct link_map *map,
 	while (runp != NULL && runp->done);
     }
 
-out:
+ out:
   if (errno == 0 && errno_saved != 0)
     __set_errno (errno_saved);
 
@@ -489,7 +491,7 @@ out:
 
   for (nlist = 0, runp = known; runp; runp = runp->next)
     {
-      if (trace_mode && runp->map->l_faked)
+      if (__builtin_expect (trace_mode, 0) && runp->map->l_faked)
 	/* This can happen when we trace the loading.  */
 	--map->l_searchlist.r_nlist;
       else
@@ -500,6 +502,30 @@ out:
       runp->map->l_reserved = 0;
     }
 
+  /* Maybe we can remove some relocation dependencies now.  */
+  assert (map->l_searchlist.r_list[0] == map);
+  for (i = 0; i < map->l_reldepsact; ++i)
+    {
+      unsigned int j;
+
+      for (j = 1; j < nlist; ++j)
+	if (map->l_searchlist.r_list[j] == map->l_reldeps[i])
+	  {
+	    /* A direct or transitive dependency is also on the list
+	       of relocation dependencies.  Remove the latter.  */
+	    --map->l_reldeps[i]->l_opencount;
+
+	    for (j = i + 1; j < map->l_reldepsact; ++j)
+	      map->l_reldeps[j - 1] = map->l_reldeps[j];
+
+	    --map->l_reldepsact;
+
+	    /* Account for the '++i' performed by the 'for'.  */
+	    --i;
+	    break;
+	  }
+    }
+
   /* Now determine the order in which the initialization has to happen.  */
   memcpy (map->l_initfini, map->l_searchlist.r_list,
 	  nlist * sizeof (struct link_map *));