summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr Bury <pbury@goahead.com>2011-05-13 02:59:09 +0100
committerPetr Baudis <pasky@ucw.cz>2011-05-27 01:27:55 +0200
commitb77931ad9f5661f23fcb236eac7ec1f8b0c94bff (patch)
treec07e7fe4ecb287c5f9bed9a27ed626ae6adfe761
parent9bb6bfdf659cd1a04c5d93282535b8a9e320fc7d (diff)
downloadglibc-b77931ad9f5661f23fcb236eac7ec1f8b0c94bff.tar.gz
Fix resizing able for unique symbols when adding symbol for copy relocation
(cherry picked from commit 320a5dc07b907b1e640fd11ce49a04aa2b367711)
-rw-r--r--ChangeLog9
-rw-r--r--elf/dl-lookup.c47
2 files changed, 29 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog
index 5a63842eef..50772691bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-05-12 Ulrich Drepper <drepper@gmail.com>
+
+ [BZ #12511]
+ * elf/dl-lookup.c (enter): Don't test for copy relocation here and
+ don't set DF_1_NODELETE here.
+ (do_lookup_x): When entering new entry test for copy relocation
+ and if necessary set DF_1_NODELETE flag.
+ Patch by Piotr Bury <pbury@goahead.com>.
+
2011-05-11 Ulrich Drepper <drepper@gmail.com>
[BZ #12052]
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 0a7b94b2ee..8f37cacb85 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
@@ -436,8 +418,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);