Tue Jun 4 18:57:57 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
authorroland <roland>
Tue, 4 Jun 1996 22:59:06 +0000 (22:59 +0000)
committerroland <roland>
Tue, 4 Jun 1996 22:59:06 +0000 (22:59 +0000)
* elf/dl-init.c (_dl_init_next): Take argument, link_map whose
  searchlist describes the piece of the DT_NEEDED graph to be
  initialized.
* elf/link.h: Update prototype.
* sysdeps/i386/dl-machine.h (RTLD_START): Pass _dl_loaded as argument
to _dl_init_next.
* sysdeps/m68k/dl-machine.h: Likewise.
* elf/dl-deps.c (_dl_open): Pass new object as arg to _dl_init_next.

elf/dl-init.c
sysdeps/i386/dl-machine.h
sysdeps/m68k/dl-machine.h

index 7375c5f..ee99ce3 100644 (file)
@@ -1,5 +1,5 @@
 /* Return the next shared object initializer function not yet run.
 /* Return the next shared object initializer function not yet run.
-Copyright (C) 1995 Free Software Foundation, Inc.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -21,45 +21,35 @@ Cambridge, MA 02139, USA.  */
 #include <link.h>
 
 
 #include <link.h>
 
 
+/* Run initializers for MAP and its dependencies, in inverse dependency
+   order (that is, leaf nodes first).  */
+
 Elf32_Addr
 Elf32_Addr
-_dl_init_next (void)
+_dl_init_next (struct link_map *map)
 {
 {
-  struct link_map *l;
-  Elf32_Addr init;
+  unsigned int i;
+
+  /* The search list for symbol lookup is a flat list in top-down
+     dependency order, so processing that list from back to front gets us
+     breadth-first leaf-to-root order.  */
 
 
-  Elf32_Addr next_init (struct link_map *l)
+  i = map->l_nsearchlist;
+  while (i-- > 0)
     {
     {
+      struct link_map *l = map->l_searchlist[i];
+
       if (l->l_init_called)
        /* This object is all done.  */
       if (l->l_init_called)
        /* This object is all done.  */
-       return 0;
+       continue;
+
       if (l->l_init_running)
        {
          /* This object's initializer was just running.
             Now mark it as having run, so this object
             will be skipped in the future.  */
       if (l->l_init_running)
        {
          /* This object's initializer was just running.
             Now mark it as having run, so this object
             will be skipped in the future.  */
-         l->l_init_called = 1;
          l->l_init_running = 0;
          l->l_init_running = 0;
-         return 0;
-       }
-
-      if (l->l_info[DT_NEEDED])
-       {
-         /* Find each dependency in order, and see if it
-            needs to run an initializer.  */
-         const char *strtab
-           = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
-         const Elf32_Dyn *d;
-         for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
-           if (d->d_tag == DT_NEEDED)
-             {
-               struct link_map *needed
-                 = _dl_map_object (l, strtab + d->d_un.d_val);
-               Elf32_Addr init;
-               --needed->l_opencount;
-               init = next_init (needed); /* Recurse on this dependency.  */
-               if (init != 0)
-                 return init;
-             }
+         l->l_init_called = 1;
+         continue;
        }
 
       if (l->l_info[DT_INIT] &&
        }
 
       if (l->l_info[DT_INIT] &&
@@ -73,17 +63,7 @@ _dl_init_next (void)
       /* No initializer for this object.
         Mark it so we will skip it in the future.  */
       l->l_init_called = 1;
       /* No initializer for this object.
         Mark it so we will skip it in the future.  */
       l->l_init_called = 1;
-      return 0;
-    }
-
-  /* Look for the first initializer not yet called.  */
-  l = _dl_loaded;
-  do
-    {
-      init = next_init (l);
-      l = l->l_next;
     }
     }
-  while (init == 0 && l);
 
 
-  return init;
+  return 0;
 }
 }
index e53c779..7ed20de 100644 (file)
@@ -225,14 +225,19 @@ _dl_start_user:\n\
        leal (%esp,%eax,4), %esp\n\
        # Push back the modified argument count.\n\
        pushl %ecx\n\
        leal (%esp,%eax,4), %esp\n\
        # Push back the modified argument count.\n\
        pushl %ecx\n\
+       # Push _dl_loaded as argument in _dl_init_next call below.\n\
+       movl _dl_loaded@GOT(%ebx), %eax\n\
+       movl (%eax), %esi\n\
+0:     pushl %esi\n\
        # Call _dl_init_next to return the address of an initializer\n\
        # function to run.\n\
        # Call _dl_init_next to return the address of an initializer\n\
        # function to run.\n\
-0:     call _dl_init_next@PLT\n\
+       call _dl_init_next@PLT\n\
+       addl $4, %esp # Pop argument.\n\
        # Check for zero return, when out of initializers.\n\
        testl %eax,%eax\n\
        jz 1f\n\
        # Call the shared object initializer function.\n\
        # Check for zero return, when out of initializers.\n\
        testl %eax,%eax\n\
        jz 1f\n\
        # Call the shared object initializer function.\n\
-       # NOTE: We depend only on the registers (%ebx and %edi)\n\
+       # NOTE: We depend only on the registers (%ebx, %esi and %edi)\n\
        # and the return address pushed by this call;\n\
        # the initializer is called with the stack just\n\
        # as it appears on entry, and it is free to move\n\
        # and the return address pushed by this call;\n\
        # the initializer is called with the stack just\n\
        # as it appears on entry, and it is free to move\n\
index 760bf96..6c6b01d 100644 (file)
@@ -250,14 +250,18 @@ _dl_start_user:
        lea (%sp, %d0*4), %sp
        | Push back the modified argument count.
        move.l %d1, -(%sp)
        lea (%sp, %d0*4), %sp
        | Push back the modified argument count.
        move.l %d1, -(%sp)
+       | Push _dl_loaded as argument in _dl_init_next call below.
+       move.l ([_dl_loaded@GOT, %a5]), %d2
+0:     move.l %d2, -(%sp)
        | Call _dl_init_next to return the address of an initializer
        | function to run.
        | Call _dl_init_next to return the address of an initializer
        | function to run.
-0:     bsr.l _dl_init_next@PLTPC
+       bsr.l _dl_init_next@PLTPC
+       add.l #4, %sp | Pop argument.
        | Check for zero return, when out of initializers.
        tst.l %d0
        jeq 1f
        | Call the shared object initializer function.
        | Check for zero return, when out of initializers.
        tst.l %d0
        jeq 1f
        | Call the shared object initializer function.
-       | NOTE: We depend only on the registers (%a4 and %a5)
+       | NOTE: We depend only on the registers (%d2, %a4 and %a5)
        | and the return address pushed by this call;
        | the initializer is called with the stack just
        | as it appears on entry, and it is free to move
        | and the return address pushed by this call;
        | the initializer is called with the stack just
        | as it appears on entry, and it is free to move