about summary refs log tree commit diff
path: root/elf/dl-init.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-07-24 19:45:13 +0000
committerUlrich Drepper <drepper@redhat.com>1999-07-24 19:45:13 +0000
commitfcf70d4114db9ff7923f5dfeb3fea6e2d623e5c2 (patch)
tree772e5473a5404c04bf293d2b90db1e83f9075a1a /elf/dl-init.c
parent3f3822198993be18d4d9ccb1593eea274dbd2ba0 (diff)
downloadglibc-fcf70d4114db9ff7923f5dfeb3fea6e2d623e5c2.tar.gz
glibc-fcf70d4114db9ff7923f5dfeb3fea6e2d623e5c2.tar.xz
glibc-fcf70d4114db9ff7923f5dfeb3fea6e2d623e5c2.zip
Update.
1999-07-24  Ulrich Drepper  <drepper@cygnus.com>

	* elf/dl-fini.c: Handle DT_FINI_ARRAY.
	* elf/link.h (struct link_map): Remove l_init_running.  Add l_runcount
	and l_initcount.
	* elf/dl-init.c: Handle DT_INIT_ARRAY.
	* elf/dynamic-link.h: Change parameters.  Now only get link_map
	pointer.  Calculate l_initcount.

	* elf/link.h (struct link_map): Add l_runpath_dirs.
	* elf/dynamic-link.h: If RUNPATH is given, set RPATH to NULL.
	* elf/dl-load.c: Pretty print.
	(decompose_rpath): Take new parameter with info from where the path
	comes.  Pass it the fillin_rpath.
	(_dl_init_paths): Initialize l_runpath_dirs.
	(_dl_map_object): Don't search using RPATHs if object has RUNPATH.
	Search using RUNPATH after LD_LIBRARY_PATH.
	* elf/dl-support.c: Adjust comment.
	* elf/rtld.c: Adjust help message.
Diffstat (limited to 'elf/dl-init.c')
-rw-r--r--elf/dl-init.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/elf/dl-init.c b/elf/dl-init.c
index 64aa1ce0bf..c4b1e22152 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 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1998, 1999 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
@@ -38,39 +38,59 @@ _dl_init_next (struct r_scope_elem *searchlist)
   while (i-- > 0)
     {
       struct link_map *l = searchlist->r_list[i];
+      ElfW(Addr) *array;
 
       if (l->l_init_called)
 	/* This object is all done.  */
 	continue;
 
-      if (l->l_init_running)
+      /* Check for object which constructors we do not run here.
+	 XXX Maybe this should be pre-computed, but where?  */
+      if (l->l_name[0] == '\0' && l->l_type == lt_executable)
 	{
-	  /* 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_running = 0;
 	  l->l_init_called = 1;
 	  continue;
 	}
 
-      if (l->l_info[DT_INIT]
-	  && (l->l_name[0] != '\0' || l->l_type != lt_executable))
-	{
-	  /* Run this object's initializer.  */
-	  l->l_init_running = 1;
+      /* Account for running next constructor.  */
+      ++l->l_runcount;
 
-	  /* Print a debug message if wanted.  */
-	  if (_dl_debug_impcalls)
-	    _dl_debug_message (1, "\ncalling init: ",
-				l->l_name[0] ? l->l_name : _dl_argv[0],
-				"\n\n", NULL);
+      if (l->l_runcount == 1)
+	{
+	  /* Try running the DT_INIT constructor.  */
+	  if (l->l_info[DT_INIT])
+	    {
+	      /* Print a debug message if wanted.  */
+	      if (_dl_debug_impcalls)
+		_dl_debug_message (1, "\ncalling init: ",
+				   l->l_name[0] ? l->l_name : _dl_argv[0],
+				   "\n\n", NULL);
+
+	      return l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr;
+	    }
+
+	  /* No DT_INIT, so go on with the array.  */
+	  ++l->l_runcount;
+	}
 
-	  return l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr;
+      if (l->l_runcount > l->l_initcount)
+	{
+	  /* That were all of the constructors.  */
+	  l->l_runcount = 0;
+	  l->l_init_called = 1;
+	  continue;
 	}
 
-      /* No initializer for this object.
-	 Mark it so we will skip it in the future.  */
-      l->l_init_called = 1;
+      /* Print a debug message if wanted.  */
+      if (_dl_debug_impcalls && l->l_info[DT_INIT] == NULL
+	  && l->l_runcount == 2)
+	_dl_debug_message (1, "\ncalling init: ",
+			   l->l_name[0] ? l->l_name : _dl_argv[0],
+			   "\n\n", NULL);
+
+      array = (ElfW(Addr) *) l->l_info[DT_INIT_ARRAY]->d_un.d_ptr;
+      return l->l_addr + array[l->l_runcount - 2];
+      /* NOTREACHED */
     }