about summary refs log tree commit diff
path: root/elf/rtld.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2006-03-19 07:48:05 +0000
committerRoland McGrath <roland@gnu.org>2006-03-19 07:48:05 +0000
commitcafdfdb65b38a14653854c3f6b535235614e0b3e (patch)
tree0fedb701658f8f39f07e73d620082deabfb0e1f6 /elf/rtld.c
parent1903f2ec29d8f29ae55ac1d7172862e418e80183 (diff)
downloadglibc-cafdfdb65b38a14653854c3f6b535235614e0b3e.tar.gz
glibc-cafdfdb65b38a14653854c3f6b535235614e0b3e.tar.xz
glibc-cafdfdb65b38a14653854c3f6b535235614e0b3e.zip
* elf/rtld.c (dl_main): Run final self-relocation after setting up TLS.
	From Alexandre Oliva <aoliva@redhat.com>.

	* elf/tst-audit2.c: New file.
	* elf/Makefile (tests): Add it.
	($(objpfx)tst-audit2.out): New target.
	(tst-audit2-ENV): New variable.

	* elf/tst-leaks1.c: Include <stdio.h>.
Diffstat (limited to 'elf/rtld.c')
-rw-r--r--elf/rtld.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/elf/rtld.c b/elf/rtld.c
index 76d129a0a0..68fe809700 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1,5 +1,5 @@
 /* Run time dynamic linker.
-   Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 2004, 2005, 2006 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
@@ -2200,7 +2200,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 #ifndef HP_TIMING_NONAVAIL
       hp_timing_t start;
       hp_timing_t stop;
-      hp_timing_t add;
 #endif
 
       /* If we are profiling we also must do lazy reloaction.  */
@@ -2255,19 +2254,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
       if (__builtin_expect (GL(dl_profile_map) != NULL, 0))
 	/* We must prepare the profiling.  */
 	_dl_start_profile ();
-
-      if (rtld_multiple_ref)
-	{
-	  /* There was an explicit ref to the dynamic linker as a shared lib.
-	     Re-relocate ourselves with user-controlled symbol definitions.  */
-	  HP_TIMING_NOW (start);
-	  /* Mark the link map as not yet relocated again.  */
-	  GL(dl_rtld_map).l_relocated = 0;
-	  _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
-	  HP_TIMING_NOW (stop);
-	  HP_TIMING_DIFF (add, start, stop);
-	  HP_TIMING_ACCUM_NT (relocate_time, add);
-	}
     }
 
 #ifndef NONTLS_INIT_TP
@@ -2296,6 +2282,30 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
   NONTLS_INIT_TP;
 #endif
 
+  if (! prelinked && rtld_multiple_ref)
+    {
+      /* There was an explicit ref to the dynamic linker as a shared lib.
+	 Re-relocate ourselves with user-controlled symbol definitions.
+
+	 We must do this after TLS initialization in case after this
+	 re-relocation, we might call a user-supplied function
+	 (e.g. calloc from _dl_relocate_object) that uses TLS data.  */
+
+#ifndef HP_TIMING_NONAVAIL
+      hp_timing_t start;
+      hp_timing_t stop;
+      hp_timing_t add;
+#endif
+
+      HP_TIMING_NOW (start);
+      /* Mark the link map as not yet relocated again.  */
+      GL(dl_rtld_map).l_relocated = 0;
+      _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
+      HP_TIMING_NOW (stop);
+      HP_TIMING_DIFF (add, start, stop);
+      HP_TIMING_ACCUM_NT (relocate_time, add);
+    }
+
 #ifdef SHARED
   /* Auditing checkpoint: we have added all objects.  */
   if (__builtin_expect (GLRO(dl_naudit) > 0, 0))