diff options
author | Jakub Jelinek <jakub@redhat.com> | 2006-03-28 09:36:28 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2006-03-28 09:36:28 +0000 |
commit | 5a6a773f6c388e7740afb495fcd03d3b500f30cb (patch) | |
tree | ad7b4e3dd8bb8a750bf6b3a016c591e5d98026dc /elf | |
parent | 0c20be13c576b849ab201bd887a6585973a49d0e (diff) |
Updated to fedora-glibc-20060328T0900cvs/fedora-
Diffstat (limited to 'elf')
-rw-r--r-- | elf/Makefile | 17 | ||||
-rw-r--r-- | elf/dl-load.c | 25 | ||||
-rw-r--r-- | elf/rtld.c | 40 | ||||
-rw-r--r-- | elf/tst-audit2.c | 50 | ||||
-rw-r--r-- | elf/tst-leaks1.c | 25 |
5 files changed, 132 insertions, 25 deletions
diff --git a/elf/Makefile b/elf/Makefile index 791341758e..3b4ef26d45 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -91,7 +91,7 @@ distribute := rtld-Rules \ order2mod1.c order2mod2.c order2mod3.c order2mod4.c \ tst-stackguard1.c tst-stackguard1-static.c \ tst-array5.c tst-array5-static.c tst-array5dep.c \ - tst-array5.exp + tst-array5.exp tst-leaks1.c CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables @@ -139,7 +139,7 @@ vpath %.c ../locale/programs endif endif -tests = tst-tls1 tst-tls2 tst-tls9 +tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1 ifeq (yes,$(have-initfini-array)) tests += tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 endif @@ -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 @@ -180,6 +181,7 @@ endif ifeq (yesyes,$(have-fpie)$(build-shared)) tests: $(objpfx)tst-pie1.out endif +tests: $(objpfx)tst-leaks1-mem modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ testobj1_1 failobj constload2 constload3 unloadmod \ dep1 dep2 dep3 dep4 $(modules-vis-$(have-protected)) \ @@ -878,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 @@ -895,3 +900,9 @@ order2mod2.so-no-z-defs = yes tst-stackguard1-ARGS = --command "$(built-program-cmd) --child" tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child" + +$(objpfx)tst-leaks1: $(libdl) +$(objpfx)tst-leaks1-mem: $(objpfx)tst-leaks1.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@ + +tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace diff --git a/elf/dl-load.c b/elf/dl-load.c index bba1c83ba0..088954a04f 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1,5 +1,6 @@ /* Map in a shared object's segments from the file. - Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 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 @@ -1554,7 +1555,7 @@ print_search_path (struct r_search_path_elem **list, user might want to know about this. */ static int open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, - int whatcode, bool *found_other_class) + int whatcode, bool *found_other_class, bool free_name) { /* This is the expected ELF header. */ #define ELF32_CLASS ELFCLASS32 @@ -1635,6 +1636,12 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, errstring = (errval == 0 ? N_("file too short") : N_("cannot read file data")); call_lose: + if (free_name) + { + char *realname = (char *) name; + name = strdupa (realname); + free (realname); + } lose (errval, fd, name, NULL, NULL, errstring); } @@ -1821,7 +1828,8 @@ open_path (const char *name, size_t namelen, int preloaded, if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)) _dl_debug_printf (" trying file=%s\n", buf); - fd = open_verify (buf, fbp, loader, whatcode, found_other_class); + fd = open_verify (buf, fbp, loader, whatcode, found_other_class, + false); if (this_dir->status[cnt] == unknown) { if (fd != -1) @@ -2098,7 +2106,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, { fd = open_verify (cached, &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, - LA_SER_CONFIG, &found_other_class); + LA_SER_CONFIG, &found_other_class, false); if (__builtin_expect (fd != -1, 1)) { realname = local_strdup (cached); @@ -2136,7 +2144,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, { fd = open_verify (realname, &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, - &found_other_class); + &found_other_class, true); if (__builtin_expect (fd, 0) == -1) free (realname); } @@ -2166,8 +2174,11 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, if ((name_copy = local_strdup (name)) == NULL || (l = _dl_new_object (name_copy, name, type, loader, mode, nsid)) == NULL) - _dl_signal_error (ENOMEM, name, NULL, - N_("cannot create shared object descriptor")); + { + free (name_copy); + _dl_signal_error (ENOMEM, name, NULL, + N_("cannot create shared object descriptor")); + } /* Signal that this is a faked entry. */ l->l_faked = 1; /* Since the descriptor is initialized with zero we do not 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)) diff --git a/elf/tst-audit2.c b/elf/tst-audit2.c new file mode 100644 index 0000000000..fd089b6f64 --- /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 new file mode 100644 index 0000000000..36e4aee9cf --- /dev/null +++ b/elf/tst-leaks1.c @@ -0,0 +1,25 @@ +#include <stdio.h> +#include <dlfcn.h> +#include <mcheck.h> +#include <stdlib.h> + +int +main (void) +{ + mtrace (); + + int ret = 0; + for (int i = 0; i < 10; i++) + { + void *h = dlopen (i < 5 ? "./tst-leaks1.c" + : "$ORIGIN/tst-leaks1.o", RTLD_LAZY); + if (h != NULL) + { + puts ("dlopen unexpectedly succeeded"); + ret = 1; + dlclose (h); + } + } + + return ret; +} |