* 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>.
This commit is contained in:
Roland McGrath 2006-03-19 07:48:05 +00:00
parent 1903f2ec29
commit cafdfdb65b
5 changed files with 93 additions and 16 deletions

View File

@ -1,3 +1,15 @@
2006-03-17 Roland McGrath <roland@redhat.com>
* 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>.
2006-03-16 Roland McGrath <roland@redhat.com> 2006-03-16 Roland McGrath <roland@redhat.com>
* sysdeps/unix/sysv/linux/alpha/getcontext.S (__getcontext_x): * sysdeps/unix/sysv/linux/alpha/getcontext.S (__getcontext_x):

View File

@ -168,7 +168,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \ tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
tst-dlmodcount tst-dlopenrpath tst-deep1 \ tst-dlmodcount tst-dlopenrpath tst-deep1 \
tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \ tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
unload3 unload4 unload5 unload6 tst-audit1 tst-global1 order2 \ unload3 unload4 unload5 unload6 tst-global1 order2 \
tst-audit1 tst-audit2 \
tst-stackguard1 tst-stackguard1
# reldep9 # reldep9
test-srcs = tst-pathopt test-srcs = tst-pathopt
@ -879,6 +880,9 @@ $(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so
$(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so $(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so
tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
$(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so
tst-audit2-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
$(objpfx)tst-global1: $(libdl) $(objpfx)tst-global1: $(libdl)
$(objpfx)tst-global1.out: $(objpfx)testobj6.so $(objpfx)testobj2.so $(objpfx)tst-global1.out: $(objpfx)testobj6.so $(objpfx)testobj2.so

View File

@ -1,5 +1,5 @@
/* Run time dynamic linker. /* 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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 #ifndef HP_TIMING_NONAVAIL
hp_timing_t start; hp_timing_t start;
hp_timing_t stop; hp_timing_t stop;
hp_timing_t add;
#endif #endif
/* If we are profiling we also must do lazy reloaction. */ /* 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)) if (__builtin_expect (GL(dl_profile_map) != NULL, 0))
/* We must prepare the profiling. */ /* We must prepare the profiling. */
_dl_start_profile (); _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 #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; NONTLS_INIT_TP;
#endif #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 #ifdef SHARED
/* Auditing checkpoint: we have added all objects. */ /* Auditing checkpoint: we have added all objects. */
if (__builtin_expect (GLRO(dl_naudit) > 0, 0)) if (__builtin_expect (GLRO(dl_naudit) > 0, 0))

50
elf/tst-audit2.c Normal file
View File

@ -0,0 +1,50 @@
/* Test case for early TLS initialization in dynamic linker. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if HAVE___THREAD
# define MAGIC1 0xabcdef72
# define MAGIC2 0xd8675309
static __thread unsigned int magic[] = { MAGIC1, MAGIC2 };
#endif
#undef calloc
/* This calloc definition will be called by the dynamic linker itself.
We test that it has initialized our TLS block by the time it does so. */
void *
calloc (size_t n, size_t m)
{
#if HAVE___THREAD
if (magic[0] != MAGIC1 || magic[1] != MAGIC2)
{
printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC1, MAGIC2);
abort ();
}
magic[0] = MAGIC2;
magic[1] = MAGIC1;
#endif
n *= m;
void *ptr = malloc (n);
if (ptr != NULL)
memset (ptr, '\0', n);
return ptr;
}
int
main (void)
{
#if HAVE___THREAD
if (magic[1] != MAGIC1 || magic[0] != MAGIC2)
{
printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC2, MAGIC1);
return 1;
}
#endif
return 0;
}

View File

@ -1,3 +1,4 @@
#include <stdio.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <mcheck.h> #include <mcheck.h>
#include <stdlib.h> #include <stdlib.h>