diff options
author | Roland McGrath <roland@gnu.org> | 2006-03-19 07:48:05 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2006-03-19 07:48:05 +0000 |
commit | cafdfdb65b38a14653854c3f6b535235614e0b3e (patch) | |
tree | 0fedb701658f8f39f07e73d620082deabfb0e1f6 /elf/rtld.c | |
parent | 1903f2ec29d8f29ae55ac1d7172862e418e80183 (diff) | |
download | glibc-cafdfdb65b38a14653854c3f6b535235614e0b3e.zip glibc-cafdfdb65b38a14653854c3f6b535235614e0b3e.tar.gz glibc-cafdfdb65b38a14653854c3f6b535235614e0b3e.tar.bz2 |
* 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.c | 40 |
1 files changed, 25 insertions, 15 deletions
@@ -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)) |