From 028478fa40d85a73b19638dbe3f83b1acebf370c Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 10 Mar 2011 12:51:33 -0500 Subject: Fix copy relocations handling of unique objects. --- elf/Makefile | 5 +++-- elf/dl-lookup.c | 18 ++++++++++++++---- elf/tst-unique3.cc | 23 +++++++++++++++++++++++ elf/tst-unique3.h | 8 ++++++++ elf/tst-unique3lib.cc | 11 +++++++++++ elf/tst-unique3lib2.cc | 12 ++++++++++++ 6 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 elf/tst-unique3.cc create mode 100644 elf/tst-unique3.h create mode 100644 elf/tst-unique3lib.cc create mode 100644 elf/tst-unique3lib2.cc (limited to 'elf') diff --git a/elf/Makefile b/elf/Makefile index 126ae326ce..56cb1b1321 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -258,7 +258,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ order2mod1 order2mod2 order2mod3 order2mod4 \ tst-unique1mod1 tst-unique1mod2 \ tst-unique2mod1 tst-unique2mod2 \ - tst-unique3lib \ + tst-unique3lib tst-unique3lib2 \ tst-initordera1 tst-initorderb1 \ tst-initordera2 tst-initorderb2 \ tst-initordera3 tst-initordera4 @@ -1182,7 +1182,8 @@ $(objpfx)tst-unique1.out: $(objpfx)tst-unique1mod1.so \ $(objpfx)tst-unique2: $(libdl) $(objpfx)tst-unique2mod1.so $(objpfx)tst-unique2.out: $(objpfx)tst-unique2mod2.so -$(objpfx)tst-unique3: $(objpfx)tst-unique3lib.so +$(objpfx)tst-unique3: $(libdl) $(objpfx)tst-unique3lib.so +$(objpfx)tst-unique3.out: $(objpfx)tst-unique3lib2.so $(objpfx)tst-initorder.out: $(objpfx)tst-initorder $(elf-objpfx)${rtld-installed-name} \ diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 78c8669e30..874a4bba4e 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -1,6 +1,5 @@ /* Look up a symbol in the loaded objects. - Copyright (C) 1995-2005, 2006, 2007, 2009, 2010 - Free Software Foundation, Inc. + Copyright (C) 1995-2007, 2009, 2010, 2011 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 @@ -364,8 +363,19 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, if (entries[idx].hashval == new_hash && strcmp (entries[idx].name, undef_name) == 0) { - result->s = entries[idx].sym; - result->m = (struct link_map *) entries[idx].map; + if ((type_class & ELF_RTYPE_CLASS_COPY) != 0) + { + /* We possibly have to initialize the central + copy from the copy addressed through the + relocation. */ + result->s = sym; + result->m = (struct link_map *) map; + } + else + { + result->s = entries[idx].sym; + result->m = (struct link_map *) entries[idx].map; + } __rtld_lock_unlock_recursive (tab->lock); return 1; } diff --git a/elf/tst-unique3.cc b/elf/tst-unique3.cc new file mode 100644 index 0000000000..b2c95939a5 --- /dev/null +++ b/elf/tst-unique3.cc @@ -0,0 +1,23 @@ +#include "tst-unique3.h" +#include +#include "../dlfcn/dlfcn.h" + +int t = S::i; + +int +main (void) +{ + std::printf ("%d %d\n", S::i, t); + int result = S::i++ != 1 || t != 1; + result |= in_lib (); + void *d = dlopen ("$ORIGIN/tst-unique3lib2.so", RTLD_LAZY); + int (*fp) (); + if (d == NULL || (fp = (int(*)()) dlsym (d, "in_lib2")) == NULL) + { + std::printf ("failed to get symbol in_lib2\n"); + return 1; + } + result |= fp (); + dlclose (d); + return result; +} diff --git a/elf/tst-unique3.h b/elf/tst-unique3.h new file mode 100644 index 0000000000..716d23641c --- /dev/null +++ b/elf/tst-unique3.h @@ -0,0 +1,8 @@ +// BZ 12510 +template +struct S +{ + static int i; +}; + +extern int in_lib (void); diff --git a/elf/tst-unique3lib.cc b/elf/tst-unique3lib.cc new file mode 100644 index 0000000000..fa8e85a36c --- /dev/null +++ b/elf/tst-unique3lib.cc @@ -0,0 +1,11 @@ +#include +#include "tst-unique3.h" +template int S::i = 1; +static int i = S::i; + +int +in_lib (void) +{ + std::printf ("in_lib: %d %d\n", S::i, i); + return S::i++ != 2 || i != 1; +} diff --git a/elf/tst-unique3lib2.cc b/elf/tst-unique3lib2.cc new file mode 100644 index 0000000000..17d817e12e --- /dev/null +++ b/elf/tst-unique3lib2.cc @@ -0,0 +1,12 @@ +#include +#include "tst-unique3.h" + +template int S::i; + +extern "C" +int +in_lib2 () +{ + std::printf ("in_lib2: %d\n", S::i); + return S::i != 3; +} -- cgit v1.2.3