]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - elf/dl-init.c
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / elf / dl-init.c
index 5448b03c33d52d81aaf648bdf34ec1aae0d62bb8..28a6ff6d8ac2fe0c835b09513f3ad903f7263fba 100644 (file)
@@ -1,5 +1,5 @@
-/* Return the next shared object initializer function not yet run.
-   Copyright (C) 1995,1996,1998,1999,2000,2001 Free Software Foundation, Inc.
+/* Run initializers for newly loaded objects.
+   Copyright (C) 1995-2014 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
@@ -13,9 +13,8 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #include <stddef.h>
 #include <ldsodefs.h>
 /* Type of the initializer.  */
 typedef void (*init_t) (int, char **, char **);
 
+#ifndef HAVE_INLINED_SYSCALLS
 /* Flag, nonzero during startup phase.  */
 extern int _dl_starting_up;
-
-/* The object to be initialized first.  */
-extern struct link_map *_dl_initfirst;
+extern int _dl_starting_up_internal attribute_hidden;
+#endif
 
 
 static void
@@ -53,25 +52,20 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
     return;
 
   /* Print a debug message if wanted.  */
-  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
+  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
     _dl_debug_printf ("\ncalling init: %s\n\n",
-                     l->l_name[0] ? l->l_name : _dl_argv[0]);
+                     DSO_FILENAME (l->l_name));
 
   /* Now run the local constructors.  There are two forms of them:
      - the one named by DT_INIT
      - the others in the DT_INIT_ARRAY.
   */
   if (l->l_info[DT_INIT] != NULL)
-    {
-      init_t init = (init_t) DL_DT_INIT_ADDRESS
-       (l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr);
-
-      /* Call the function.  */
-      init (argc, argv, env);
-    }
+    DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
 
   /* Next see whether there is an array with initialization functions.  */
-  if (l->l_info[DT_INIT_ARRAY] != NULL)
+  ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
+  if (init_array != NULL)
     {
       unsigned int j;
       unsigned int jm;
@@ -79,8 +73,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
 
       jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr));
 
-      addrs = (ElfW(Addr) *) (l->l_info[DT_INIT_ARRAY]->d_un.d_ptr
-                             + l->l_addr);
+      addrs = (ElfW(Addr) *) (init_array->d_un.d_ptr + l->l_addr);
       for (j = 0; j < jm; ++j)
        ((init_t) addrs[j]) (argc, argv, env);
     }
@@ -92,40 +85,32 @@ internal_function
 _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
 {
   ElfW(Dyn) *preinit_array = main_map->l_info[DT_PREINIT_ARRAY];
-  struct r_debug *r;
+  ElfW(Dyn) *preinit_array_size = main_map->l_info[DT_PREINIT_ARRAYSZ];
   unsigned int i;
 
-  if (__builtin_expect (_dl_initfirst != NULL, 0))
+  if (__builtin_expect (GL(dl_initfirst) != NULL, 0))
     {
-      call_init (_dl_initfirst, argc, argv, env);
-      _dl_initfirst = NULL;
+      call_init (GL(dl_initfirst), argc, argv, env);
+      GL(dl_initfirst) = NULL;
     }
 
   /* Don't do anything if there is no preinit array.  */
   if (__builtin_expect (preinit_array != NULL, 0)
-      && (i = preinit_array->d_un.d_val / sizeof (ElfW(Addr))) > 0)
+      && preinit_array_size != NULL
+      && (i = preinit_array_size->d_un.d_val / sizeof (ElfW(Addr))) > 0)
     {
       ElfW(Addr) *addrs;
       unsigned int cnt;
 
-      if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0))
+      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
        _dl_debug_printf ("\ncalling preinit: %s\n\n",
-                         main_map->l_name[0]
-                         ? main_map->l_name : _dl_argv[0]);
+                         DSO_FILENAME (main_map->l_name));
 
-      addrs = (ElfW(Addr) *) (main_map->l_info[DT_PREINIT_ARRAY]->d_un.d_ptr
-                             + main_map->l_addr);
+      addrs = (ElfW(Addr) *) (preinit_array->d_un.d_ptr + main_map->l_addr);
       for (cnt = 0; cnt < i; ++cnt)
        ((init_t) addrs[cnt]) (argc, argv, env);
     }
 
-  /* Notify the debugger we have added some objects.  We need to call
-     _dl_debug_initialize in a static program in case dynamic linking has
-     not been used before.  */
-  r = _dl_debug_initialize (0);
-  r->r_state = RT_ADD;
-  _dl_debug_state ();
-
   /* Stupid users forced the ELF specification to be changed.  It now
      says that the dynamic loader is responsible for determining the
      order in which the constructors have to run.  The constructors
@@ -140,10 +125,9 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
   while (i-- > 0)
     call_init (main_map->l_initfini[i], argc, argv, env);
 
-  /* Notify the debugger all new objects are now ready to go.  */
-  r->r_state = RT_CONSISTENT;
-  _dl_debug_state ();
-
+#ifndef HAVE_INLINED_SYSCALLS
   /* Finished starting up.  */
-  _dl_starting_up = 0;
+  INTUSE(_dl_starting_up) = 0;
+#endif
 }
+INTDEF (_dl_init)