Handle unloading of DSO with a unique symbol definition.
authorUlrich Drepper <drepper@redhat.com>
Thu, 23 Jul 2009 14:07:53 +0000 (07:07 -0700)
committerUlrich Drepper <drepper@redhat.com>
Thu, 23 Jul 2009 14:07:53 +0000 (07:07 -0700)
ChangeLog
elf/dl-lookup.c
elf/tst-unique1.c
sysdeps/generic/ldsodefs.h

index 006dd5a..bea7ba0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * sysdeps/x86_64/multiarch/strstr.c: Minor cleanups.  Remove
index fd0d624..bdc84af 100644 (file)
@@ -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);
index 9b7996c..46d41d9 100644 (file)
@@ -1,6 +1,7 @@
 #include <config.h>
 #include <dlfcn.h>
 #include <stdio.h>
+#include <sys/mman.h>
 
 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 ()
index 30f9d23..e18e60f 100644 (file)
@@ -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;