diff options
author | Piotr Bury <pbury@goahead.com> | 2011-05-13 02:59:09 +0100 |
---|---|---|
committer | Petr Baudis <pasky@ucw.cz> | 2011-05-27 01:27:55 +0200 |
commit | b77931ad9f5661f23fcb236eac7ec1f8b0c94bff (patch) | |
tree | c07e7fe4ecb287c5f9bed9a27ed626ae6adfe761 | |
parent | 9bb6bfdf659cd1a04c5d93282535b8a9e320fc7d (diff) | |
download | glibc-b77931ad9f5661f23fcb236eac7ec1f8b0c94bff.tar.gz |
Fix resizing able for unique symbols when adding symbol for copy relocation
(cherry picked from commit 320a5dc07b907b1e640fd11ce49a04aa2b367711)
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | elf/dl-lookup.c | 47 |
2 files changed, 29 insertions, 27 deletions
@@ -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); |