Handle unloading of DSO with a unique symbol definition.

This commit is contained in:
Ulrich Drepper 2009-07-23 07:07:53 -07:00
parent 0122f28eb9
commit 802fe9a1ca
4 changed files with 60 additions and 6 deletions

View File

@ -1,3 +1,14 @@
2009-07-23 Ulrich Drepper <drepper@redhat.com>
* 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 <drepper@redhat.com> 2009-07-21 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/multiarch/strstr.c: Minor cleanups. Remove * sysdeps/x86_64/multiarch/strstr.c: Minor cleanups. Remove

View File

@ -312,7 +312,7 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
definition we have to use it. */ definition we have to use it. */
void enter (struct unique_sym *table, size_t size, void enter (struct unique_sym *table, size_t size,
unsigned int hash, const char *name, 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 idx = hash % size;
size_t hash2 = 1 + hash % (size - 2); 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].sym = sym;
table[idx].map = map; 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; return;
} }
@ -410,7 +416,8 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
tab->free = free; 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; ++tab->n_elements;
__rtld_lock_unlock_recursive (tab->lock); __rtld_lock_unlock_recursive (tab->lock);

View File

@ -1,6 +1,7 @@
#include <config.h> #include <config.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <stdio.h> #include <stdio.h>
#include <sys/mman.h>
static int static int
do_test (void) do_test (void)
@ -30,10 +31,45 @@ do_test (void)
puts ("cannot locate f in tst-unique1mod2"); puts ("cannot locate f in tst-unique1mod2");
return 1; return 1;
} }
return f2 (f1 ()); if (f2 (f1 ()))
#else {
return 0; 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 #endif
return 0;
} }
#define TEST_FUNCTION do_test () #define TEST_FUNCTION do_test ()

View File

@ -396,7 +396,7 @@ struct rtld_global
uint32_t hashval; uint32_t hashval;
const char *name; const char *name;
const ElfW(Sym) *sym; const ElfW(Sym) *sym;
const struct link_map *map; struct link_map *map;
} *entries; } *entries;
size_t size; size_t size;
size_t n_elements; size_t n_elements;