From: Ulrich Drepper Date: Thu, 23 Jul 2009 14:07:53 +0000 (-0700) Subject: Handle unloading of DSO with a unique symbol definition. X-Git-Tag: upstream/2.30~13433 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=802fe9a1ca0577e8eac28c31a8c20497b15e7e69;p=external%2Fglibc.git Handle unloading of DSO with a unique symbol definition. --- diff --git a/ChangeLog b/ChangeLog index 006dd5a..bea7ba0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-07-23 Ulrich Drepper + + * elf/tst-unique1.c: Extend test to check for unloading DSO with + unique symbol definition. + Patch by Jakub Jelinek. + * elf/dl-lookup.c (do_lookup_x): When entering a new unique symbol, + make sure the object with the definition cannot be unloaded. Adjust + a few types. + * sysdeps/generic/ldsodefs.h (struct rtld_global): The map element in + the unique symbol hash table should not be const. + 2009-07-21 Ulrich Drepper * sysdeps/x86_64/multiarch/strstr.c: Minor cleanups. Remove diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index fd0d624..bdc84af 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -312,7 +312,7 @@ 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, const struct link_map *map) + const ElfW(Sym) *sym, struct link_map *map) { size_t idx = hash % size; size_t hash2 = 1 + hash % (size - 2); @@ -332,6 +332,12 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, table[idx].sym = sym; table[idx].map = map; } + + if (table[idx].map->l_type == lt_loaded) + /* Make sure we don't unload this object by + artificially increason the open count. */ + ++table[idx].map->l_direct_opencount; + return; } @@ -410,7 +416,8 @@ 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, map); + enter (entries, size, new_hash, strtab + sym->st_name, sym, + (struct link_map *) map); ++tab->n_elements; __rtld_lock_unlock_recursive (tab->lock); diff --git a/elf/tst-unique1.c b/elf/tst-unique1.c index 9b7996c..46d41d9 100644 --- a/elf/tst-unique1.c +++ b/elf/tst-unique1.c @@ -1,6 +1,7 @@ #include #include #include +#include static int do_test (void) @@ -30,10 +31,45 @@ do_test (void) puts ("cannot locate f in tst-unique1mod2"); return 1; } - return f2 (f1 ()); -#else - return 0; + if (f2 (f1 ())) + { + puts ("f from tst-unique1mod2 failed"); + return 1; + } + dlclose (h2); + dlclose (h1); + mmap (NULL, 1024 * 1024 * 16, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + h2 = dlopen ("tst-unique1mod2.so", RTLD_LAZY); + if (h2 == NULL) + { + puts ("cannot load tst-unique1mod2"); + return 1; + } + f2 = dlsym (h2, "f"); + if (f2 == NULL) + { + puts ("cannot locate f in tst-unique1mod2"); + return 1; + } + h1 = dlopen ("tst-unique1mod1.so", RTLD_LAZY); + if (h1 == NULL) + { + puts ("cannot load tst-unique1mod1"); + return 1; + } + f1 = dlsym (h1, "f"); + if (f1 == NULL) + { + puts ("cannot locate f in tst-unique1mod1"); + return 1; + } + if (f2 (f1 ())) + { + puts ("f from tst-unique1mod2 failed"); + return 1; + } #endif + return 0; } #define TEST_FUNCTION do_test () diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 30f9d23..e18e60f 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -396,7 +396,7 @@ struct rtld_global uint32_t hashval; const char *name; const ElfW(Sym) *sym; - const struct link_map *map; + struct link_map *map; } *entries; size_t size; size_t n_elements;