about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-init.c120
-rw-r--r--elf/dl-load.c7
-rw-r--r--elf/elf.h1
-rw-r--r--elf/soinit.c8
4 files changed, 73 insertions, 63 deletions
diff --git a/elf/dl-init.c b/elf/dl-init.c
index 627f823524..82e573712f 100644
--- a/elf/dl-init.c
+++ b/elf/dl-init.c
@@ -1,5 +1,5 @@
 /* Return the next shared object initializer function not yet run.
-   Copyright (C) 1995, 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1995,1996,1998,1999,2000,2001 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
@@ -27,6 +27,63 @@ typedef void (*init_t) (int, char **, char **);
 /* Flag, nonzero during startup phase.  */
 extern int _dl_starting_up;
 
+/* The object to be initialized first.  */
+extern struct link_map *_dl_initfirst;
+
+
+static void
+call_init (struct link_map *l, int argc, char **argv, char **env)
+{
+  if (l->l_init_called)
+    /* This object is all done.  */
+    return;
+
+  /* Avoid handling this constructor again in case we have a circular
+     dependency.  */
+  l->l_init_called = 1;
+
+  /* Check for object which constructors we do not run here.  */
+  if (l->l_name[0] == '\0' && l->l_type == lt_executable)
+    return;
+
+  /* Are there any constructors?  */
+  if (l->l_info[DT_INIT] == NULL && l->l_info[DT_INIT_ARRAY] == NULL)
+    return;
+
+  /* Print a debug message if wanted.  */
+  if (__builtin_expect (_dl_debug_impcalls, 0))
+    _dl_debug_message (1, "\ncalling init: ",
+		       l->l_name[0] ? l->l_name : _dl_argv[0], "\n\n", NULL);
+
+  /* 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);
+    }
+
+  /* Next see whether there is an array with initialization functions.  */
+  if (l->l_info[DT_INIT_ARRAY] != NULL)
+    {
+      unsigned int j;
+      unsigned int jm;
+      ElfW(Addr) *addrs;
+
+      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);
+      for (j = 0; j < jm; ++j)
+	((init_t) addrs[j]) (argc, argv, env);
+    }
+}
+
 
 void
 internal_function
@@ -36,6 +93,12 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
   struct r_debug *r;
   unsigned int i;
 
+  if (_dl_initfirst != NULL)
+    {
+      call_init (_dl_initfirst, argc, argv, env);
+      _dl_initfirst = NULL;
+    }
+
   /* Don't do anything if there is no preinit array.  */
   if (preinit_array != NULL
       && (i = preinit_array->d_un.d_val / sizeof (ElfW(Addr))) > 0)
@@ -73,60 +136,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
 
   i = main_map->l_searchlist.r_nlist;
   while (i-- > 0)
-    {
-      struct link_map *l = main_map->l_initfini[i];
-      init_t init;
-
-      if (l->l_init_called)
-	/* This object is all done.  */
-	continue;
-
-      /* Avoid handling this constructor again in case we have a circular
-	 dependency.  */
-      l->l_init_called = 1;
-
-      /* Check for object which constructors we do not run here.  */
-      if (l->l_name[0] == '\0' && l->l_type == lt_executable)
-	continue;
-
-      /* Are there any constructors?  */
-      if (l->l_info[DT_INIT] == NULL && l->l_info[DT_INIT_ARRAY] == NULL)
-	continue;
-
-      /* Print a debug message if wanted.  */
-      if (__builtin_expect (_dl_debug_impcalls, 0))
-	_dl_debug_message (1, "\ncalling init: ",
-			   l->l_name[0] ? l->l_name : _dl_argv[0],
-			   "\n\n", NULL);
-
-      /* 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 = (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);
-	}
-
-      /* Next see whether there is an array with initialization functions.  */
-      if (l->l_info[DT_INIT_ARRAY] != NULL)
-	{
-	  unsigned int j;
-	  unsigned int jm;
-	  ElfW(Addr) *addrs;
-
-	  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);
-	  for (j = 0; j < jm; ++j)
-	    ((init_t) addrs[j]) (argc, argv, env);
-	}
-    }
+    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;
diff --git a/elf/dl-load.c b/elf/dl-load.c
index e8112b10bb..157d827419 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -117,6 +117,9 @@ int _dl_clktck;
 extern const char *_dl_platform;
 extern size_t _dl_platformlen;
 
+/* The object to be initialized first.  */
+struct link_map *_dl_initfirst;
+
 /* This is the decomposed LD_LIBRARY_PATH search path.  */
 static struct r_search_path_struct env_path_list;
 
@@ -1150,6 +1153,10 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
       l->l_scope[0] = &l->l_symbolic_searchlist;
     }
 
+  /* Remember whether this object must be initialized first.  */
+  if (l->l_flags_1 & DF_1_INITFIRST)
+    _dl_initfirst = l;
+
   /* Finally the file information.  */
   l->l_dev = st.st_dev;
   l->l_ino = st.st_ino;
diff --git a/elf/elf.h b/elf/elf.h
index 93e4372bb5..6f88d8c13d 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -295,6 +295,7 @@ typedef struct
 #define SHT_SYMTAB_SHNDX  18		/* Extended section indeces */
 #define	SHT_NUM		  19		/* Number of defined types.  */
 #define SHT_LOOS	  0x60000000	/* Start OS-specific */
+#define SHT_CHECKSUM	  0x6ffffff8	/* Checksum for DSO content.  */
 #define SHT_LOSUNW	  0x6ffffffa	/* Sun-specific low bound.  */
 #define SHT_SUNW_move	  0x6ffffffa
 #define SHT_SUNW_COMDAT   0x6ffffffb
diff --git a/elf/soinit.c b/elf/soinit.c
index 42e6cf1691..ff65af4a36 100644
--- a/elf/soinit.c
+++ b/elf/soinit.c
@@ -36,9 +36,6 @@ extern void __deregister_frame (const void *);
 # endif
 #endif
 
-/* We have to initialize the thread library at least if bit.  */
-extern void __pthread_initialize_minimal (void) __attribute__ ((weak));
-
 /* This function will be called from _init in init-first.c.  */
 void
 __libc_global_ctors (void)
@@ -46,11 +43,6 @@ __libc_global_ctors (void)
   /* Call constructor functions.  */
   run_hooks (__CTOR_LIST__);
 
-  /* Initialize the thread library at least a bit since the libgcc functions
-     are using thread functions if these are available.  */
-  if (__pthread_initialize_minimal)
-    __pthread_initialize_minimal ();
-
 #ifdef HAVE_DWARF2_UNWIND_INFO
 # ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
   {