Resolve race between dlopen and lazy binding on MIPS.
authorViju Vincent <vijuvince@gmail.com>
Wed, 15 Feb 2012 17:25:51 +0000 (17:25 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 15 Feb 2012 17:25:51 +0000 (17:25 +0000)
ChangeLog.mips
sysdeps/mips/dl-trampoline.c

index ff8cfc2..2a9ed6c 100644 (file)
@@ -1,3 +1,8 @@
+2012-02-15  Viju Vincent  <vijuvince@gmail.com>
+
+       * sysdeps/mips/dl-trampoline.c (__dl_runtime_resolve): Use locking
+       around calls to _dl_lookup_symbol_x.
+
 2012-02-13  Joseph Myers  <joseph@codesourcery.com>
 
        * sysdeps/unix/sysv/linux/mips/bits/inotify.h: New file.
index 2c94140..c4367f7 100644 (file)
@@ -26,6 +26,7 @@
 #include <elf.h>
 #include <ldsodefs.h>
 #include <dl-machine.h>
+#include <sysdep-cancel.h>
 
 /* Get link map for callers object containing STUB_PC.  */
 static inline struct link_map *
@@ -153,17 +154,44 @@ __dl_runtime_resolve (ElfW(Word) sym_index,
 
            if (version->hash != 0)
              {
+                /* We need to keep the scope around so do some locking.  This is
+                  not necessary for objects which cannot be unloaded or when
+                  we are not using any threads (yet).  */
+               if (!RTLD_SINGLE_THREAD_P)
+                 THREAD_GSCOPE_SET_FLAG ();
+
                sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l,
                                               &sym, l->l_scope, version,
                                               ELF_RTYPE_CLASS_PLT, 0, 0);
+
+                /* We are done with the global scope.  */
+               if (!RTLD_SINGLE_THREAD_P)
+                 THREAD_GSCOPE_RESET_FLAG ();
+
                break;
              }
            /* Fall through.  */
          }
        case 0:
+         {
+          /* We need to keep the scope around so do some locking.  This is
+            not necessary for objects which cannot be unloaded or when
+            we are not using any threads (yet).  */
+         int flags = DL_LOOKUP_ADD_DEPENDENCY;
+         if (!RTLD_SINGLE_THREAD_P)
+           {
+             THREAD_GSCOPE_SET_FLAG ();
+             flags |= DL_LOOKUP_GSCOPE_LOCK;
+           }
+
          sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
                                         l->l_scope, 0, ELF_RTYPE_CLASS_PLT,
-                                        DL_LOOKUP_ADD_DEPENDENCY, 0);
+                                        flags, 0);
+
+          /* We are done with the global scope.  */
+         if (!RTLD_SINGLE_THREAD_P)
+           THREAD_GSCOPE_RESET_FLAG ();
+         }
        }
 
       /* Currently value contains the base load address of the object