diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | elf/Makefile | 6 | ||||
-rw-r--r-- | elf/rtld.c | 40 | ||||
-rw-r--r-- | elf/tst-audit2.c | 50 | ||||
-rw-r--r-- | elf/tst-leaks1.c | 1 |
5 files changed, 93 insertions, 16 deletions
@@ -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> * sysdeps/unix/sysv/linux/alpha/getcontext.S (__getcontext_x): diff --git a/elf/Makefile b/elf/Makefile index 5e45930..3b4ef26 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -168,7 +168,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \ tst-dlmodcount tst-dlopenrpath tst-deep1 \ 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 # reldep9 test-srcs = tst-pathopt @@ -879,6 +880,9 @@ $(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so $(objpfx)tst-audit1.out: $(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.out: $(objpfx)testobj6.so $(objpfx)testobj2.so @@ -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)) diff --git a/elf/tst-audit2.c b/elf/tst-audit2.c new file mode 100644 index 0000000..fd089b6 --- /dev/null +++ b/elf/tst-audit2.c @@ -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; +} diff --git a/elf/tst-leaks1.c b/elf/tst-leaks1.c index c9db5e0..36e4aee 100644 --- a/elf/tst-leaks1.c +++ b/elf/tst-leaks1.c @@ -1,3 +1,4 @@ +#include <stdio.h> #include <dlfcn.h> #include <mcheck.h> #include <stdlib.h> |