Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 27 Oct 2004 20:27:40 +0000 (20:27 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 27 Oct 2004 20:27:40 +0000 (20:27 +0000)
2004-10-27  Ulrich Drepper  <drepper@redhat.com>

* elf/dl-fini.c (_dl_fini): Fix search for map in maps array.
Reverse order of namespaces.
* elf/Makefile: Add rules to build and run tst-dlmopen3.
* elf/tst-dlmopen3.c: New file.
* elf/tst-dlmopen1mod.c: Add check whether constructor runs.

ChangeLog
elf/Makefile
elf/dl-fini.c
elf/tst-dlmopen1mod.c

index 6cb52ba..9c52aeb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2004-10-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-fini.c (_dl_fini): Fix search for map in maps array.
+       Reverse order of namespaces.
+       * elf/Makefile: Add rules to build and run tst-dlmopen3.
+       * elf/tst-dlmopen3.c: New file.
+       * elf/tst-dlmopen1mod.c: Add check whether constructor runs.
+
 2004-10-27  Jakub Jelinek  <jakub@redhat.com>
 
        * sysdeps/generic/glob.c (globfree): Clear gl_pathv after freeing it.
index 0bec4ab..028be25 100644 (file)
@@ -154,7 +154,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
         circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
         tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
         $(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
-        tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2
+        tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2 tst-dlmopen3
 #       reldep9
 test-srcs = tst-pathopt
 tests-vis-yes = vismain
@@ -770,3 +770,6 @@ $(objpfx)tst-dlmopen1.out: $(objpfx)tst-dlmopen1mod.so
 
 $(objpfx)tst-dlmopen2: $(libdl)
 $(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so
+
+$(objpfx)tst-dlmopen3: $(libdl)
+$(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so
index 33036b5..f43f4a0 100644 (file)
@@ -42,23 +42,18 @@ _dl_fini (void)
      using `dlopen' there are possibly several other modules with its
      dependencies to be taken into account.  Therefore we have to start
      determining the order of the modules once again from the beginning.  */
-  unsigned int i;
-  unsigned int nloaded;
-  struct link_map *l;
   struct link_map **maps = NULL;
   size_t maps_size = 0;
 
-  /* We First run the destructors of the main namespaces, then the
-     other ones.  The order should not matter since the namespace
-     content is supposed to be independent.  But we can have auditing
-     code in a auxiliaty namespace and we want it to monitor the
-     destructors.  */
-  for (Lmid_t cnt = 0; cnt < DL_NNS; ++cnt)
+  /* We run the destructors of the main namespaces last.  As for the
+     other namespaces, we pick run the destructors in them in reverse
+     order of the namespace ID.  */
+  for (Lmid_t cnt = DL_NNS - 1; cnt >= 0; --cnt)
     {
       /* Protect against concurrent loads and unloads.  */
       __rtld_lock_lock_recursive (GL(dl_load_lock));
 
-      nloaded = GL(dl_ns)[cnt]._ns_nloaded;
+      unsigned int nloaded = GL(dl_ns)[cnt]._ns_nloaded;
 
       /* XXX Could it be (in static binaries) that there is no object
         loaded?  */
@@ -79,20 +74,20 @@ _dl_fini (void)
                             nloaded * sizeof (struct link_map *));
        }
 
+      unsigned int i;
+      struct link_map *l;
       for (l = GL(dl_ns)[cnt]._ns_loaded, i = 0; l != NULL; l = l->l_next)
-       {
-         assert (i < nloaded);
+       /* Do not handle ld.so in secondary namespaces.  */
+       if (l == l->l_real)
+         {
+           assert (i < nloaded);
 
-         /* Do not handle ld.so in secondary namespaces.  */
-         if (l == l->l_real)
-           {
-             maps[i++] = l;
+           maps[i++] = l;
 
-             /* Bump l_opencount of all objects so that they are not
-                dlclose()ed from underneath us.  */
-             ++l->l_opencount;
-           }
-       }
+           /* Bump l_opencount of all objects so that they are not
+              dlclose()ed from underneath us.  */
+           ++l->l_opencount;
+         }
       assert (cnt != LM_ID_BASE || i == nloaded);
       assert (cnt == LM_ID_BASE || i == nloaded || i == nloaded - 1);
       unsigned int nmaps = i;
@@ -105,46 +100,23 @@ _dl_fini (void)
            /* The main executable always comes first.  */
            l = l->l_next;
          for (; l != NULL; l = l->l_next)
-           {
-             unsigned int j;
-             unsigned int k;
-
-             /* Find the place in the 'maps' array.  */
-             for (j = 1; maps[j] != l; ++j)
-               ;
-
-             /* Find all object for which the current one is a dependency and
-                move the found object (if necessary) in front.  */
-             for (k = j + 1; k < nmaps; ++k)
-               {
-                 struct link_map **runp = maps[k]->l_initfini;
-                 if (runp != NULL)
-                   {
-                     while (*runp != NULL)
-                       if (*runp == l)
-                         {
-                           struct link_map *here = maps[k];
-
-                           /* Move it now.  */
-                           memmove (&maps[j] + 1,
-                                    &maps[j],
-                                    (k - j) * sizeof (struct link_map *));
-                           maps[j++] = here;
-
-                           break;
-                         }
-                       else
-                         ++runp;
-                   }
-
-                 if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
-                   {
-                     unsigned int m = maps[k]->l_reldepsact;
-                     struct link_map **relmaps = maps[k]->l_reldeps;
-
-                     while (m-- > 0)
-                       {
-                         if (relmaps[m] == l)
+           /* Do not handle ld.so in secondary namespaces.  */
+           if (l == l->l_real)
+             {
+               /* Find the place in the 'maps' array.  */
+               unsigned int j;
+               for (j = cnt == LM_ID_BASE ? 1 : 0; maps[j] != l; ++j)
+                 assert (j < nmaps);
+
+               /* Find all object for which the current one is a dependency
+                  and move the found object (if necessary) in front.  */
+               for (unsigned int k = j + 1; k < nmaps; ++k)
+                 {
+                   struct link_map **runp = maps[k]->l_initfini;
+                   if (runp != NULL)
+                     {
+                       while (*runp != NULL)
+                         if (*runp == l)
                            {
                              struct link_map *here = maps[k];
 
@@ -152,14 +124,37 @@ _dl_fini (void)
                              memmove (&maps[j] + 1,
                                       &maps[j],
                                       (k - j) * sizeof (struct link_map *));
-                             maps[j] = here;
+                             maps[j++] = here;
 
                              break;
                            }
-                       }
-                   }
-               }
-           }
+                         else
+                           ++runp;
+                     }
+
+                   if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
+                     {
+                       unsigned int m = maps[k]->l_reldepsact;
+                       struct link_map **relmaps = maps[k]->l_reldeps;
+
+                       while (m-- > 0)
+                         {
+                           if (relmaps[m] == l)
+                             {
+                               struct link_map *here = maps[k];
+
+                               /* Move it now.  */
+                               memmove (&maps[j] + 1,
+                                        &maps[j],
+                                        (k - j) * sizeof (struct link_map *));
+                               maps[j] = here;
+
+                               break;
+                             }
+                         }
+                     }
+                 }
+             }
        }
 
       /* We do not rely on the linked list of loaded object anymore from
index 40a4c8f..1424880 100644 (file)
@@ -3,6 +3,16 @@
 #include <gnu/lib-names.h>
 
 
+static int cnt;
+
+static void
+__attribute ((constructor))
+constr (void)
+{
+  ++cnt;
+}
+
+
 int
 foo (Lmid_t ns2)
 {
@@ -34,5 +44,16 @@ foo (Lmid_t ns2)
       return 1;
     }
 
+  if (cnt == 0)
+    {
+      puts ("constructor did not run");
+      return 1;
+    }
+  else if (cnt != 1)
+    {
+      puts ("constructor did not run exactly once");
+      return 1;
+    }
+
   return 0;
 }