summaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorPiotr Bury <pbury@goahead.com>2011-05-12 21:59:09 -0400
committerUlrich Drepper <drepper@gmail.com>2011-05-12 21:59:09 -0400
commit320a5dc07b907b1e640fd11ce49a04aa2b367711 (patch)
tree2013cd7929bfc4fc4115233318c216cea60b5b79 /elf
parentf574184a0e4b6ed69a5d9a3234543fba6d2a7367 (diff)
Fix resizing able for unique symbols when adding symbol for copy relocation
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile5
-rw-r--r--elf/dl-lookup.c47
-rw-r--r--elf/tst-unique4.cc27
-rw-r--r--elf/tst-unique4.h7
-rw-r--r--elf/tst-unique4lib.cc17
5 files changed, 75 insertions, 28 deletions
diff --git a/elf/Makefile b/elf/Makefile
index 56cb1b1321..a18c1cd8ae 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -201,7 +201,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
unload3 unload4 unload5 unload6 unload7 tst-global1 order2 \
tst-audit1 tst-audit2 \
tst-stackguard1 tst-addr1 tst-thrlock \
- tst-unique1 tst-unique2 tst-unique3 \
+ tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
tst-initorder
# reldep9
test-srcs = tst-pathopt
@@ -259,6 +259,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-unique1mod1 tst-unique1mod2 \
tst-unique2mod1 tst-unique2mod2 \
tst-unique3lib tst-unique3lib2 \
+ tst-unique4lib \
tst-initordera1 tst-initorderb1 \
tst-initordera2 tst-initorderb2 \
tst-initordera3 tst-initordera4
@@ -1185,6 +1186,8 @@ $(objpfx)tst-unique2.out: $(objpfx)tst-unique2mod2.so
$(objpfx)tst-unique3: $(libdl) $(objpfx)tst-unique3lib.so
$(objpfx)tst-unique3.out: $(objpfx)tst-unique3lib2.so
+$(objpfx)tst-unique4: $(objpfx)tst-unique4lib.so
+
$(objpfx)tst-initorder.out: $(objpfx)tst-initorder
$(elf-objpfx)${rtld-installed-name} \
--library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 19b27d71ba..affb53f30e 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -312,39 +312,21 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
definition we have to use it. */
void enter (struct unique_sym *table, size_t size,
unsigned int hash, const char *name,
- const ElfW(Sym) *sym, struct link_map *map)
+ const ElfW(Sym) *sym, const struct link_map *map)
{
size_t idx = hash % size;
size_t hash2 = 1 + hash % (size - 2);
- while (1)
+ while (table[idx].name != NULL)
{
- if (table[idx].name == NULL)
- {
- table[idx].hashval = hash;
- table[idx].name = name;
- if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
- {
- table[idx].sym = ref;
- table[idx].map = undef_map;
- }
- else
- {
- table[idx].sym = sym;
- table[idx].map = map;
-
- if (map->l_type == lt_loaded)
- /* Make sure we don't unload this object by
- setting the appropriate flag. */
- map->l_flags_1 |= DF_1_NODELETE;
- }
-
- return;
- }
-
idx += hash2;
if (idx >= size)
idx -= size;
}
+
+ table[idx].hashval = hash;
+ table[idx].name = name;
+ table[idx].sym = sym;
+ table[idx].map = map;
}
struct unique_sym_table *tab
@@ -450,8 +432,19 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
tab->free = free;
}
- enter (entries, size, new_hash, strtab + sym->st_name, sym,
- (struct link_map *) map);
+ if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
+ enter (entries, size, new_hash, strtab + sym->st_name, ref,
+ undef_map);
+ else
+ {
+ enter (entries, size, new_hash, strtab + sym->st_name, sym,
+ map);
+
+ if (map->l_type == lt_loaded)
+ /* Make sure we don't unload this object by
+ setting the appropriate flag. */
+ ((struct link_map *) map)->l_flags_1 |= DF_1_NODELETE;
+ }
++tab->n_elements;
__rtld_lock_unlock_recursive (tab->lock);
diff --git a/elf/tst-unique4.cc b/elf/tst-unique4.cc
new file mode 100644
index 0000000000..9eaa909986
--- /dev/null
+++ b/elf/tst-unique4.cc
@@ -0,0 +1,27 @@
+// BZ 12511
+#include "tst-unique4.h"
+#include <cstdio>
+
+static int a[24] =
+ {
+ S<1>::i, S<2>::i, S<3>::i, S<4>::i, S<5>::i, S<6>::i, S<7>::i, S<8>::i,
+ S<9>::i, S<10>::i, S<11>::i, S<12>::i, S<13>::i, S<14>::i, S<15>::i,
+ S<16>::i, S<17>::i, S<18>::i, S<19>::i, S<20>::i, S<21>::i, S<22>::i,
+ S<23>::i, S<24>::i
+ };
+
+int
+main (void)
+{
+ int result = 0;
+ for (int i = 0; i < 24; ++i)
+ {
+ printf("%d ", a[i]);
+ result |= a[i] != i + 1;
+ }
+
+ printf("\n%d\n", S<1>::j);
+ result |= S<1>::j != -1;
+
+ return result;
+}
diff --git a/elf/tst-unique4.h b/elf/tst-unique4.h
new file mode 100644
index 0000000000..2d377f5d51
--- /dev/null
+++ b/elf/tst-unique4.h
@@ -0,0 +1,7 @@
+// BZ 12511
+template<int N>
+struct S
+{
+ static int i;
+ static const int j;
+};
diff --git a/elf/tst-unique4lib.cc b/elf/tst-unique4lib.cc
new file mode 100644
index 0000000000..c9fdf9cfea
--- /dev/null
+++ b/elf/tst-unique4lib.cc
@@ -0,0 +1,17 @@
+// BZ 12511
+#include "tst-unique4.h"
+
+template<int N>
+int S<N>::i = N;
+template<int N>
+const int S<N>::j __attribute__ ((used)) = -1;
+
+static int a[24] =
+ {
+ S<1>::i, S<2>::i, S<3>::i, S<4>::i, S<5>::i, S<6>::i, S<7>::i, S<8>::i,
+ S<9>::i, S<10>::i, S<11>::i, S<12>::i, S<13>::i, S<14>::i, S<15>::i,
+ S<16>::i, S<17>::i, S<18>::i, S<19>::i, S<20>::i, S<21>::i, S<22>::i,
+ S<23>::i, S<24>::i
+ };
+
+static int b = S<1>::j;