Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 19 Aug 2000 07:17:09 +0000 (07:17 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 19 Aug 2000 07:17:09 +0000 (07:17 +0000)
2000-08-19  Ulrich Drepper  <drepper@redhat.com>

* elf/Versions [ld] (GLIBC_2.2): Export _dl_check_map_versions.
* elf/dl-deps.c (_dl_map_object_deps): If object was dependency of
a dynamically loaded object remove old l_initfini list.
* elf/dl-libc.c (free_mem): Used as __libc_subfreeres callback to
remove some dynamically allocated memory blocks in the dynamic
loading data structures.
* elf/dl-load.c (add_name_to_object): Initialize dont_free to 0.
* elf/dl-open.c (dl_open_workder): Don't call _dl_check_all_versions.
Instead call _dl_check_map_versions only for the dependencies.
* elf/rtld.c: Avoid unneccessary initializations.  Mark l_libname
information of initial objects as not free-able.
* sysdeps/generic/ldsodefs.h (struct libname_list): Add dont_free
element.

* elf/filter.c: Call mtrace.
* elf/restest1.c: Likewise.  Close the objects.
* elf/loadtest.c: Call mtrace.  Check result of dlclose.  Print more
debug information.

* elf/constload1.c: Add comment explaining not freed memory.

ChangeLog
elf/constload1.c
elf/dl-deps.c
elf/dl-libc.c
elf/dl-load.c
elf/dl-open.c
elf/filter.c
elf/loadtest.c
elf/restest1.c
elf/rtld.c
sysdeps/generic/ldsodefs.h

index 50bd2c7..31f3463 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2000-08-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/Versions [ld] (GLIBC_2.2): Export _dl_check_map_versions.
+       * elf/dl-deps.c (_dl_map_object_deps): If object was dependency of
+       a dynamically loaded object remove old l_initfini list.
+       * elf/dl-libc.c (free_mem): Used as __libc_subfreeres callback to
+       remove some dynamically allocated memory blocks in the dynamic
+       loading data structures.
+       * elf/dl-load.c (add_name_to_object): Initialize dont_free to 0.
+       * elf/dl-open.c (dl_open_workder): Don't call _dl_check_all_versions.
+       Instead call _dl_check_map_versions only for the dependencies.
+       * elf/rtld.c: Avoid unneccessary initializations.  Mark l_libname
+       information of initial objects as not free-able.
+       * sysdeps/generic/ldsodefs.h (struct libname_list): Add dont_free
+       element.
+
+       * elf/filter.c: Call mtrace.
+       * elf/restest1.c: Likewise.  Close the objects.
+       * elf/loadtest.c: Call mtrace.  Check result of dlclose.  Print more
+       debug information.
+
+       * elf/constload1.c: Add comment explaining not freed memory.
+
 2000-08-18  Andreas Jaeger  <aj@suse.de>
 
        * sysdeps/unix/sysv/linux/mips/bits/stat.h: Add pads to show
index 4640b77..e0ddae9 100644 (file)
@@ -18,6 +18,10 @@ main (void)
     error (EXIT_FAILURE, errno, "cannot load module \"constload2.so\"");
   foo = dlsym (h, "foo");
   ret = foo ();
+  /* Note that the following dlclose() call cannot unload the objects.
+     Due to the introduced relocation dependency constload2.so depends
+     on constload3.so and the dependencies of constload2.so on constload3.so
+     is not visible to ld.so since it's done using dlopen().  */
   if (dlclose (h) != 0)
     {
       puts ("failed to close");
index 4fc2943..44838d6 100644 (file)
@@ -467,6 +467,14 @@ _dl_map_object_deps (struct link_map *map,
        while (runp != NULL && runp->done);
     }
 
+  if (map->l_initfini != NULL && map->l_type == lt_loaded)
+    {
+      /* This object was previously loaded as a dependency and we have
+        a separate l_initfini list.  We don't need it anymore.  */
+      assert (map->l_searchlist.r_list == NULL);
+      free (map->l_initfini);
+    }
+
   /* Store the search list we built in the object.  It will be used for
      searches in the scope of this object.  */
   map->l_searchlist.r_list = malloc ((2 * nlist + 1
index 992a52e..8518909 100644 (file)
@@ -120,3 +120,27 @@ __libc_dlclose (void *__map)
 {
   return dlerror_run (do_dlclose, __map);
 }
+
+
+static void
+free_mem (void)
+{
+  struct link_map *l;
+
+  /* Remove all additional names added to the objects.  */
+  for (l = _dl_loaded; l != NULL; l = l->l_next)
+    {
+      struct libname_list *lnp = l->l_libname->next;
+
+      l->l_libname->next = NULL;
+
+      while (lnp != NULL)
+       {
+         struct libname_list *old = lnp;
+         lnp = lnp->next;
+         if (! old->dont_free)
+           free (old);
+       }
+    }
+}
+text_set_element (__libc_subfreeres, free_mem);
index adeb7dc..ea3c928 100644 (file)
@@ -322,6 +322,7 @@ add_name_to_object (struct link_map *l, const char *name)
 
   newname->name = memcpy (newname + 1, name, name_len);
   newname->next = NULL;
+  newname->dont_free = 0;
   lastp->next = newname;
 }
 
index 60a8f1a..b07ede1 100644 (file)
@@ -88,6 +88,7 @@ dl_open_worker (void *a)
   struct link_map *new, *l;
   const char *dst;
   int lazy;
+  unsigned int i;
 
   /* Maybe we have to expand a DST.  */
   dst = strchr (file, '$');
@@ -163,7 +164,9 @@ dl_open_worker (void *a)
   _dl_map_object_deps (new, NULL, 0, 0);
 
   /* So far, so good.  Now check the versions.  */
-  (void) _dl_check_all_versions (new, 0, 0);
+  for (i = 0; i < new->l_searchlist.r_nlist; ++i)
+    if (new->l_searchlist.r_list[i]->l_versions == NULL)
+      (void) _dl_check_map_versions (new->l_searchlist.r_list[i], 0, 0);
 
 #ifdef SCOPE_DEBUG
   show_scope (new);
index 76bc91a..46aa15b 100644 (file)
@@ -1,3 +1,4 @@
+#include <mcheck.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -6,7 +7,11 @@ extern const char *foo (void);
 int
 main (void)
 {
-  const char *s = foo ();
+  const char *s;
+
+  mtrace ();
+
+  s = foo ();
 
   printf ("called `foo' from `%s'\n", s);
 
index 5b9e116..80f9960 100644 (file)
@@ -2,6 +2,7 @@
 #include <dlfcn.h>
 #include <errno.h>
 #include <error.h>
+#include <mcheck.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -66,10 +67,16 @@ static const struct
 #define NTESTS (sizeof (tests) / sizeof (tests[0]))
 
 
+#include <include/link.h>
+
+
 int
 main (void)
 {
   int count = TEST_ROUNDS;
+  int result = 0;
+
+  mtrace ();
 
   /* Just a seed.  */
   srandom (TEST_ROUNDS);
@@ -102,23 +109,38 @@ main (void)
 
          fct (10);
 
-         printf ("successfully loaded `%s'\n", testobjs[index].name);
+         printf ("successfully loaded `%s', handle %p\n",
+                 testobjs[index].name, testobjs[index].handle);
        }
       else
        {
-         dlclose (testobjs[index].handle);
-         testobjs[index].handle = NULL;
+         if (dlclose (testobjs[index].handle) != 0)
+           {
+             printf ("failed to close %s\n", testobjs[index].name);
+             result = 1;
+           }
+         else
+           printf ("successfully unloaded `%s', handle %p\n",
+                   testobjs[index].name, testobjs[index].handle);
 
-         printf ("successfully unloaded `%s'\n", testobjs[index].name);
+         testobjs[index].handle = NULL;
        }
     }
 
   /* Unload all loaded modules.  */
   for (count = 0; count < NOBJS; ++count)
     if (testobjs[count].handle != NULL)
-      dlclose (testobjs[count].handle);
+{        printf ("\nclose: %s: l_initfini = %p, l_versions = %p\n",
+                 testobjs[count].name,
+                 ((struct link_map*)testobjs[count].handle)->l_initfini,
+                 ((struct link_map*)testobjs[count].handle)->l_versions);
+      if (dlclose (testobjs[count].handle) != 0)
+       {
+         printf ("failed to close %s\n", testobjs[count].name);
+         result = 1;
+}      }
 
-  return 0;
+  return result;
 }
 
 
index e4eca55..2b649c0 100644 (file)
@@ -1,5 +1,6 @@
 #include <dlfcn.h>
 #include <error.h>
+#include <mcheck.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -13,6 +14,8 @@ main (void)
   int res1;
   int res2;
 
+  mtrace ();
+
   h1 = dlopen ("testobj1.so", RTLD_LAZY);
   if (h1 == NULL)
     error (EXIT_FAILURE, 0, "while loading `%s': %s", "testobj1.so",
@@ -37,6 +40,11 @@ main (void)
   res2 = fp2 (10);
   printf ("fp1(10) = %d\nfp2(10) = %d\n", res1, res2);
 
+  if (dlclose (h1) != 0)
+    error (EXIT_FAILURE, 0, "cannot close testobj1.so: %s\n", dlerror ());
+  if (dlclose (h2) != 0)
+    error (EXIT_FAILURE, 0, "cannot close testobj1_1.so: %s\n", dlerror ());
+
   return res1 != 42 || res2 != 72;
 }
 
index 9a444fc..41cf5c3 100644 (file)
@@ -590,7 +590,7 @@ of this helper program; chances are you did not intend to run this program.\n\
           the shared object is already loaded.  */
        _dl_rtld_libname.name = ((const char *) _dl_loaded->l_addr
                                 + ph->p_vaddr);
-       _dl_rtld_libname.next = NULL;
+       /* _dl_rtld_libname.next = NULL;        Already zero.  */
        _dl_rtld_map.l_libname = &_dl_rtld_libname;
 
        /* Ordinarilly, we would get additional names for the loader from
@@ -604,7 +604,7 @@ of this helper program; chances are you did not intend to run this program.\n\
            if (p)
              {
                _dl_rtld_libname2.name = p+1;
-               _dl_rtld_libname2.next = NULL;
+               /* _dl_rtld_libname2.next = NULL;  Already zero.  */
                _dl_rtld_libname.next = &_dl_rtld_libname2;
              }
          }
@@ -626,7 +626,7 @@ of this helper program; chances are you did not intend to run this program.\n\
       /* We were invoked directly, so the program might not have a
         PT_INTERP.  */
       _dl_rtld_libname.name = _dl_rtld_map.l_name;
-      _dl_rtld_libname.next = NULL;
+      /* _dl_rtld_libname.next = NULL;         Alread zero.  */
       _dl_rtld_map.l_libname =  &_dl_rtld_libname;
     }
   else
@@ -1059,6 +1059,17 @@ of this helper program; chances are you did not intend to run this program.\n\
     HP_TIMING_NOW (start);
     do
       {
+       /* While we are at it, help the memory handling a bit.  We have to
+          mark some data structures as allocated with the fake malloc()
+          implementation in ld.so.  */
+       struct libname_list *lnp = l->l_libname->next;
+
+       while (__builtin_expect (lnp != NULL, 0))
+         {
+           lnp->dont_free = 1;
+           lnp = lnp->next;
+         }
+
        if (l != &_dl_rtld_map)
          _dl_relocate_object (l, l->l_scope, _dl_lazy, consider_profiling);
 
index f7f77c2..ceb2b87 100644 (file)
@@ -115,6 +115,8 @@ struct libname_list
   {
     const char *name;          /* Name requested (before search).  */
     struct libname_list *next; /* Link to next name for this object.  */
+    int dont_free;             /* Flag whether this element should be freed
+                                  if the object is not entirely unloaded.  */
   };