about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--NEWS4
-rw-r--r--elf/Makefile5
-rw-r--r--elf/dl-lookup.c18
-rw-r--r--elf/tst-unique3.cc23
-rw-r--r--elf/tst-unique3.h8
-rw-r--r--elf/tst-unique3lib.cc11
-rw-r--r--elf/tst-unique3lib2.cc12
-rw-r--r--include/bits/dlfcn.h1
9 files changed, 85 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 95f0525d43..b83905ba1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2011-03-10  Ulrich Drepper  <drepper@gmail.com>
 
+	[BZ #12510]
+	* elf/dl-lookup.c (do_lookup_x): For copy relocations of unique objects
+	copy from the symbol referenced in the relocation to initialize the
+	used variable.
+	Patch by Piotr Bury <pbury@goahead.com>.
+	* elf/Makefile: Add rules to build and tst-unique3.
+	* include/bits/dlfcn.h: Remove _dl_mcount_wrapper_check declaration.
+	* elf/tst-unique3.cc: New file.
+	* elf/tst-unique3.h: New file.
+	* elf/tst-unique3lib.cc: New file.
+	* elf/tst-unique3lib2.cc: New file.
+
 	* elf/Makefile: Don't run tst-execstack* tests of SELinux is enabled.
 
 2011-03-06  Ulrich Drepper  <drepper@gmail.com>
diff --git a/NEWS b/NEWS
index 38243c3ae1..3b02f3b8be 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes.  2011-2-25
+GNU C Library NEWS -- history of user-visible changes.  2011-3-10
 Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
 See the end for copying conditions.
 
@@ -9,7 +9,7 @@ Version 2.14
 
 * The following bugs are resolved with this release:
 
-  11724, 12445, 12454, 12460, 12469, 12489, 12509
+  11724, 12445, 12454, 12460, 12469, 12489, 12509, 12510
 
 Version 2.13
 
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 <cstdio>
+#include "../dlfcn/dlfcn.h"
+
+int t = S<char>::i;
+
+int
+main (void)
+{
+  std::printf ("%d %d\n", S<char>::i, t);
+  int result = S<char>::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<typename T>
+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 <cstdio>
+#include "tst-unique3.h"
+template<typename T> int S<T>::i = 1;
+static int i = S<char>::i;
+
+int
+in_lib (void)
+{
+  std::printf ("in_lib: %d %d\n", S<char>::i, i);
+  return S<char>::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 <cstdio>
+#include "tst-unique3.h"
+
+template<typename T> int S<T>::i;
+
+extern "C"
+int
+in_lib2 ()
+{
+  std::printf ("in_lib2: %d\n", S<char>::i);
+  return S<char>::i != 3;
+}
diff --git a/include/bits/dlfcn.h b/include/bits/dlfcn.h
index cb4a5c202b..c31a645bc8 100644
--- a/include/bits/dlfcn.h
+++ b/include/bits/dlfcn.h
@@ -1,4 +1,3 @@
 #include_next <bits/dlfcn.h>
 
-extern void _dl_mcount_wrapper_check (void *__selfpc);
 libc_hidden_proto (_dl_mcount_wrapper_check)