aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-03-10 12:51:33 -0500
committerUlrich Drepper <drepper@gmail.com>2011-03-10 12:51:33 -0500
commit028478fa40d85a73b19638dbe3f83b1acebf370c (patch)
tree03f5573c44e2cde7b809f44134526d202c8b29e2 /elf
parent908ea63341bbbca534411a0581cd16ba36e08706 (diff)
downloadglibc-028478fa40d85a73b19638dbe3f83b1acebf370c.zip
glibc-028478fa40d85a73b19638dbe3f83b1acebf370c.tar.gz
glibc-028478fa40d85a73b19638dbe3f83b1acebf370c.tar.bz2
Fix copy relocations handling of unique objects.
Diffstat (limited to 'elf')
-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
6 files changed, 71 insertions, 6 deletions
diff --git a/elf/Makefile b/elf/Makefile
index 126ae32..56cb1b1 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 78c8669..874a4bb 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 0000000..b2c9593
--- /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 0000000..716d236
--- /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 0000000..fa8e85a
--- /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 0000000..17d817e
--- /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;
+}