(_dl_close): Handle relocation dependencies of the dependencies of the
authordrepper <drepper>
Tue, 24 Oct 2000 20:17:35 +0000 (20:17 +0000)
committerdrepper <drepper>
Tue, 24 Oct 2000 20:17:35 +0000 (20:17 +0000)
object currently unloaded.

elf/dl-close.c

index 5f82922..c98a21d 100644 (file)
@@ -43,11 +43,15 @@ void
 internal_function
 _dl_close (void *_map)
 {
+  struct reldep_list
+  {
+    struct link_map **rellist;
+    unsigned int nrellist;
+    struct reldep_list *next;
+  } *reldeps = NULL;
   struct link_map **list;
-  struct link_map **rellist;
   struct link_map *map = _map;
   unsigned int nsearchlist;
-  unsigned int nrellist;
   unsigned int i;
   unsigned int *new_opencount;
 
@@ -119,9 +123,6 @@ _dl_close (void *_map)
       }
   assert (new_opencount[0] == 0);
 
-  rellist = map->l_reldeps;
-  nrellist = map->l_reldepsact;
-
   /* Call all termination functions at once.  */
   for (i = 0; i < nsearchlist; ++i)
     {
@@ -221,6 +222,20 @@ _dl_close (void *_map)
          if (imap->l_origin != NULL && imap->l_origin != (char *) -1)
            free ((char *) imap->l_origin);
 
+         /* If the object has relocation dependencies save this
+             information for latter.  */
+         if (__builtin_expect (imap->l_reldeps != NULL, 0))
+           {
+             struct reldep_list *newrel;
+
+             newrel = (struct reldep_list *) alloca (sizeof (*reldeps));
+             newrel->rellist = map->l_reldeps;
+             newrel->nrellist = map->l_reldepsact;
+             newrel->next = reldeps;
+
+             reldeps = newrel;
+           }
+
          /* This name always is allocated.  */
          free (imap->l_name);
          /* Remove the list with all the names of the shared object.  */
@@ -255,12 +270,14 @@ _dl_close (void *_map)
 
   /* Now we can perhaps also remove the modules for which we had
      dependencies because of symbol lookup.  */
-  if (__builtin_expect (rellist != NULL, 0))
+  while (__builtin_expect (reldeps != NULL, 0))
     {
-      while (nrellist-- > 0)
-       _dl_close (rellist[nrellist]);
+      while (reldeps->nrellist-- > 0)
+       _dl_close (reldeps->rellist[reldeps->nrellist]);
+
+      free (reldeps->rellist);
 
-      free (rellist);
+      reldeps = reldeps->next;
     }
 
   free (list);