* elf/dl-lookup.c (_dl_debug_bindings): Remove unised symbol_scope
authorUlrich Drepper <drepper@redhat.com>
Fri, 27 Oct 2006 15:54:20 +0000 (15:54 +0000)
committerUlrich Drepper <drepper@redhat.com>
Fri, 27 Oct 2006 15:54:20 +0000 (15:54 +0000)
argument.
(_dl_lookup_symbol_x): Adjust caller.

* sysdeps/generic/ldsodefs.h (struct link_namespaces): Remove
_ns_global_scope.
* elf/rtld.c (dl_main): Don't initialize _ns_global_scope.

* elf/dl-libc.c: Revert l_scope name changes.
* elf/dl-load.c: Likewise.
* elf/dl-object.c: Likewise.
* elf/rtld.c: Likewise.
* elf/dl-close.c (_dl_close): Likewise.
* elf/dl-open.c (dl_open_worker): Likewise.  If not SINGLE_THREAD_P,
always use __rtld_mrlock_{change,done}.  Always free old scope list
here if not l_scope_mem.
* elf/dl-runtime.c (_dl_fixup, _dl_profile_fixup): Revert l_scope name
change.  Never free scope list here.  Just __rtld_mrlock_lock before
the lookup and __rtld_mrlock_unlock it after the lookup.
* elf/dl-sym.c: Likewise.
* include/link.h (struct r_scoperec): Remove.
(struct link_map): Replace l_scoperec with l_scope, l_scoperec_mem
with l_scope_mem and l_scoperec_lock with l_scope_lock.

25 files changed:
ChangeLog
elf/dl-close.c
elf/dl-libc.c
elf/dl-load.c
elf/dl-lookup.c
elf/dl-object.c
elf/dl-open.c
elf/dl-runtime.c
elf/dl-sym.c
elf/rtld.c
include/link.h
nptl/ChangeLog
nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
sysdeps/generic/ldsodefs.h

index aa54d61..19ebca2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2006-10-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/dl-lookup.c (_dl_debug_bindings): Remove unised symbol_scope
+       argument.
+       (_dl_lookup_symbol_x): Adjust caller.
+
+       * sysdeps/generic/ldsodefs.h (struct link_namespaces): Remove
+       _ns_global_scope.
+       * elf/rtld.c (dl_main): Don't initialize _ns_global_scope.
+
+       * elf/dl-libc.c: Revert l_scope name changes.
+       * elf/dl-load.c: Likewise.
+       * elf/dl-object.c: Likewise.
+       * elf/rtld.c: Likewise.
+       * elf/dl-close.c (_dl_close): Likewise.
+       * elf/dl-open.c (dl_open_worker): Likewise.  If not SINGLE_THREAD_P,
+       always use __rtld_mrlock_{change,done}.  Always free old scope list
+       here if not l_scope_mem.
+       * elf/dl-runtime.c (_dl_fixup, _dl_profile_fixup): Revert l_scope name
+       change.  Never free scope list here.  Just __rtld_mrlock_lock before
+       the lookup and __rtld_mrlock_unlock it after the lookup.
+       * elf/dl-sym.c: Likewise.
+       * include/link.h (struct r_scoperec): Remove.
+       (struct link_map): Replace l_scoperec with l_scope, l_scoperec_mem
+       with l_scope_mem and l_scoperec_lock with l_scope_lock.
+
 2006-10-25  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/gnu/netinet/tcp.h: Define TCP_CONGESTION.
index bfcceea..31bc80b 100644 (file)
@@ -343,14 +343,14 @@ _dl_close (void *_map)
             one for the terminating NULL pointer.  */
          size_t remain = (new_list != NULL) + 1;
          bool removed_any = false;
-         for (size_t cnt = 0; imap->l_scoperec->scope[cnt] != NULL; ++cnt)
+         for (size_t cnt = 0; imap->l_scope[cnt] != NULL; ++cnt)
            /* This relies on l_scope[] entries being always set either
               to its own l_symbolic_searchlist address, or some map's
               l_searchlist address.  */
-           if (imap->l_scoperec->scope[cnt] != &imap->l_symbolic_searchlist)
+           if (imap->l_scope[cnt] != &imap->l_symbolic_searchlist)
              {
                struct link_map *tmap = (struct link_map *)
-                 ((char *) imap->l_scoperec->scope[cnt]
+                 ((char *) imap->l_scope[cnt]
                   - offsetof (struct link_map, l_searchlist));
                assert (tmap->l_ns == ns);
                if (tmap->l_idx == IDX_STILL_USED)
@@ -368,38 +368,35 @@ _dl_close (void *_map)
                 user of the current array.  If possible use the link map's
                 memory.  */
              size_t new_size;
-             struct r_scoperec *newp;
-             if (imap->l_scoperec != &imap->l_scoperec_mem
-                 && remain < NINIT_SCOPE_ELEMS (imap)
-                 && imap->l_scoperec_mem.nusers == 0)
+             struct r_scope_elem **newp;
+
+#define SCOPE_ELEMS(imap) \
+  (sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0]))
+
+             if (imap->l_scope != imap->l_scope_mem
+                 && remain < SCOPE_ELEMS (imap))
                {
-                 new_size = NINIT_SCOPE_ELEMS (imap);
-                 newp = &imap->l_scoperec_mem;
+                 new_size = SCOPE_ELEMS (imap);
+                 newp = imap->l_scope_mem;
                }
              else
                {
                  new_size = imap->l_scope_max;
-                 newp = (struct r_scoperec *)
-                   malloc (sizeof (struct r_scoperec)
-                           + new_size * sizeof (struct r_scope_elem *));
+                 newp = (struct r_scope_elem **)
+                   malloc (new_size * sizeof (struct r_scope_elem *));
                  if (newp == NULL)
                    _dl_signal_error (ENOMEM, "dlclose", NULL,
                                      N_("cannot create scope list"));
                }
 
-             newp->nusers = 0;
-             newp->remove_after_use = false;
-             newp->notify = false;
-
              /* Copy over the remaining scope elements.  */
              remain = 0;
-             for (size_t cnt = 0; imap->l_scoperec->scope[cnt] != NULL; ++cnt)
+             for (size_t cnt = 0; imap->l_scope[cnt] != NULL; ++cnt)
                {
-                 if (imap->l_scoperec->scope[cnt]
-                     != &imap->l_symbolic_searchlist)
+                 if (imap->l_scope[cnt] != &imap->l_symbolic_searchlist)
                    {
                      struct link_map *tmap = (struct link_map *)
-                       ((char *) imap->l_scoperec->scope[cnt]
+                       ((char *) imap->l_scope[cnt]
                         - offsetof (struct link_map, l_searchlist));
                      if (tmap->l_idx != IDX_STILL_USED)
                        {
@@ -407,38 +404,30 @@ _dl_close (void *_map)
                             scope.  */
                          if (new_list != NULL)
                            {
-                             newp->scope[remain++] = new_list;
+                             newp[remain++] = new_list;
                              new_list = NULL;
                            }
                          continue;
                        }
                    }
 
-                 newp->scope[remain++] = imap->l_scoperec->scope[cnt];
+                 newp[remain++] = imap->l_scope[cnt];
                }
-             newp->scope[remain] = NULL;
+             newp[remain] = NULL;
 
-             struct r_scoperec *old = imap->l_scoperec;
+             struct r_scope_elem **old = imap->l_scope;
 
              if (SINGLE_THREAD_P)
-               imap->l_scoperec = newp;
+               imap->l_scope = newp;
              else
                {
-                 __rtld_mrlock_change (imap->l_scoperec_lock);
-                 imap->l_scoperec = newp;
-                 __rtld_mrlock_done (imap->l_scoperec_lock);
-
-                 if (atomic_increment_val (&old->nusers) != 1)
-                   {
-                     old->remove_after_use = true;
-                     old->notify = true;
-                     if (atomic_decrement_val (&old->nusers) != 0)
-                       __rtld_waitzero (old->nusers);
-                   }
+                 __rtld_mrlock_change (imap->l_scope_lock);
+                 imap->l_scope = newp;
+                 __rtld_mrlock_done (imap->l_scope_lock);
                }
 
              /* No user anymore, we can free it now.  */
-             if (old != &imap->l_scoperec_mem)
+             if (old != imap->l_scope_mem)
                free (old);
 
              imap->l_scope_max = new_size;
@@ -652,8 +641,8 @@ _dl_close (void *_map)
          free (imap->l_initfini);
 
          /* Remove the scope array if we allocated it.  */
-         if (imap->l_scoperec != &imap->l_scoperec_mem)
-           free (imap->l_scoperec);
+         if (imap->l_scope != imap->l_scope_mem)
+           free (imap->l_scope);
 
          if (imap->l_phdr_allocated)
            free ((void *) imap->l_phdr);
index 8b78a7a..a6d0d1f 100644 (file)
@@ -133,8 +133,7 @@ do_dlsym_private (void *ptr)
   struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
   args->ref = NULL;
   l = GLRO(dl_lookup_symbol_x) (args->name, args->map, &args->ref,
-                               args->map->l_scoperec->scope, &vers, 0, 0,
-                               NULL);
+                               args->map->l_scope, &vers, 0, 0, NULL);
   args->loadbase = l;
 }
 
index 172fb2f..36dc123 100644 (file)
@@ -1473,7 +1473,7 @@ cannot enable executable stack as shared object requires");
      have to do this for the main map.  */
   if ((mode & RTLD_DEEPBIND) == 0
       && __builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0)
-      && &l->l_searchlist != l->l_scoperec->scope[0])
+      && &l->l_searchlist != l->l_scope[0])
     {
       /* Create an appropriate searchlist.  It contains only this map.
         This is the definition of DT_SYMBOLIC in SysVr4.  */
@@ -1490,11 +1490,11 @@ cannot enable executable stack as shared object requires");
       l->l_symbolic_searchlist.r_nlist = 1;
 
       /* Now move the existing entries one back.  */
-      memmove (&l->l_scoperec->scope[1], &l->l_scoperec->scope[0],
-              (l->l_scope_max - 1) * sizeof (l->l_scoperec->scope[0]));
+      memmove (&l->l_scope[1], &l->l_scope[0],
+              (l->l_scope_max - 1) * sizeof (l->l_scope[0]));
 
       /* Now add the new entry.  */
-      l->l_scoperec->scope[0] = &l->l_symbolic_searchlist;
+      l->l_scope[0] = &l->l_symbolic_searchlist;
     }
 
   /* Remember whether this object must be initialized first.  */
index 7238169..29a5216 100644 (file)
@@ -200,8 +200,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
 static void
 internal_function
 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
-                   const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
-                   struct sym_val *value,
+                   const ElfW(Sym) **ref, struct sym_val *value,
                    const struct r_found_version *version, int type_class,
                    int protected);
 
@@ -351,7 +350,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
 
   if (__builtin_expect (GLRO(dl_debug_mask)
                        & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
-    _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
+    _dl_debug_bindings (undef_name, undef_map, ref,
                        &current_value, version, type_class, protected);
 
   *ref = current_value.s;
@@ -408,8 +407,7 @@ _dl_setup_hash (struct link_map *map)
 static void
 internal_function
 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
-                   const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
-                   struct sym_val *value,
+                   const ElfW(Sym) **ref, struct sym_val *value,
                    const struct r_found_version *version, int type_class,
                    int protected)
 {
index c5dae9e..29f44bf 100644 (file)
@@ -82,13 +82,12 @@ _dl_new_object (char *realname, const char *libname, int type,
   /* Use the 'l_scope_mem' array by default for the the 'l_scope'
      information.  If we need more entries we will allocate a large
      array dynamically.  */
-  new->l_scoperec = &new->l_scoperec_mem;
-  new->l_scope_max = (sizeof (new->l_scope_realmem.scope_elems)
-                     / sizeof (new->l_scope_realmem.scope_elems[0]));
+  new->l_scope = new->l_scope_mem;
+  new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]);
 
   /* No need to initialize the scope lock if the initializer is zero.  */
 #if _RTLD_MRLOCK_INITIALIZER != 0
-  __rtld_mrlock_initialize (new->l_scoperec_mem.lock);
+  __rtld_mrlock_initialize (new->l_scope_lock);
 #endif
 
   /* Counter for the scopes we have to handle.  */
@@ -104,8 +103,7 @@ _dl_new_object (char *realname, const char *libname, int type,
       l->l_next = new;
 
       /* Add the global scope.  */
-      new->l_scoperec->scope[idx++]
-       = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
+      new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
     }
   else
     GL(dl_ns)[nsid]._ns_loaded = new;
@@ -121,15 +119,15 @@ _dl_new_object (char *realname, const char *libname, int type,
       loader = loader->l_loader;
 
   /* Insert the scope if it isn't the global scope we already added.  */
-  if (idx == 0 || &loader->l_searchlist != new->l_scoperec->scope[0])
+  if (idx == 0 || &loader->l_searchlist != new->l_scope[0])
     {
       if ((mode & RTLD_DEEPBIND) != 0 && idx != 0)
        {
-         new->l_scoperec->scope[1] = new->l_scoperec->scope[0];
+         new->l_scope[1] = new->l_scope[0];
          idx = 0;
        }
 
-      new->l_scoperec->scope[idx] = &loader->l_searchlist;
+      new->l_scope[idx] = &loader->l_searchlist;
     }
 
   new->l_local_scope[0] = &new->l_searchlist;
index 85b9637..2ae861f 100644 (file)
@@ -344,7 +344,7 @@ dl_open_worker (void *a)
                 start the profiling.  */
              struct link_map *old_profile_map = GL(dl_profile_map);
 
-             _dl_relocate_object (l, l->l_scoperec->scope, 1, 1);
+             _dl_relocate_object (l, l->l_scope, 1, 1);
 
              if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
                {
@@ -357,7 +357,7 @@ dl_open_worker (void *a)
            }
          else
 #endif
-           _dl_relocate_object (l, l->l_scoperec->scope, lazy, 0);
+           _dl_relocate_object (l, l->l_scope, lazy, 0);
        }
 
       if (l == new)
@@ -375,7 +375,7 @@ dl_open_worker (void *a)
         not been loaded here and now.  */
       if (imap->l_init_called && imap->l_type == lt_loaded)
        {
-         struct r_scope_elem **runp = imap->l_scoperec->scope;
+         struct r_scope_elem **runp = imap->l_scope;
          size_t cnt = 0;
 
          while (*runp != NULL)
@@ -395,62 +395,51 @@ dl_open_worker (void *a)
              /* The 'r_scope' array is too small.  Allocate a new one
                 dynamically.  */
              size_t new_size;
-             struct r_scoperec *newp;
+             struct r_scope_elem **newp;
 
-             if (imap->l_scoperec != &imap->l_scoperec_mem
-                 && imap->l_scope_max < NINIT_SCOPE_ELEMS (imap)
-                 && imap->l_scoperec_mem.nusers == 0)
+#define SCOPE_ELEMS(imap) \
+  (sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0]))
+
+             if (imap->l_scope != imap->l_scope_mem
+                 && imap->l_scope_max < SCOPE_ELEMS (imap))
                {
-                 new_size = NINIT_SCOPE_ELEMS (imap);
-                 newp = &imap->l_scoperec_mem;
+                 new_size = SCOPE_ELEMS (imap);
+                 newp = imap->l_scope_mem;
                }
              else
                {
                  new_size = imap->l_scope_max * 2;
-                 newp = (struct r_scoperec *)
-                   malloc (sizeof (struct r_scoperec)
-                           + new_size * sizeof (struct r_scope_elem *));
+                 newp = (struct r_scope_elem **)
+                   malloc (new_size * sizeof (struct r_scope_elem *));
                  if (newp == NULL)
                    _dl_signal_error (ENOMEM, "dlopen", NULL,
                                      N_("cannot create scope list"));
                }
 
-             newp->nusers = 0;
-             newp->remove_after_use = false;
-             newp->notify = false;
-             memcpy (newp->scope, imap->l_scoperec->scope,
-                     cnt * sizeof (imap->l_scoperec->scope[0]));
-             struct r_scoperec *old = imap->l_scoperec;
+             memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0]));
+             struct r_scope_elem **old = imap->l_scope;
 
-             if (old == &imap->l_scoperec_mem)
-               imap->l_scoperec = newp;
-             else if (SINGLE_THREAD_P)
-               {
-                 imap->l_scoperec = newp;
-                 free (old);
-               }
+             if (SINGLE_THREAD_P)
+               imap->l_scope = newp;
              else
                {
-                 __rtld_mrlock_change (imap->l_scoperec_lock);
-                 imap->l_scoperec = newp;
-                 __rtld_mrlock_done (imap->l_scoperec_lock);
-
-                 atomic_increment (&old->nusers);
-                 old->remove_after_use = true;
-                 if (atomic_decrement_val (&old->nusers) == 0)
-                   /* No user, we can free it here and now.  */
-                   free (old);
+                 __rtld_mrlock_change (imap->l_scope_lock);
+                 imap->l_scope = newp;
+                 __rtld_mrlock_done (imap->l_scope_lock);
                }
 
+             if (old != imap->l_scope_mem)
+               free (old);
+
              imap->l_scope_max = new_size;
            }
 
          /* First terminate the extended list.  Otherwise a thread
             might use the new last element and then use the garbage
             at offset IDX+1.  */
-         imap->l_scoperec->scope[cnt + 1] = NULL;
+         imap->l_scope[cnt + 1] = NULL;
          atomic_write_barrier ();
-         imap->l_scoperec->scope[cnt] = &new->l_searchlist;
+         imap->l_scope[cnt] = &new->l_searchlist;
        }
 #if USE_TLS
       /* Only add TLS memory if this object is loaded now and
index 8bf5b89..0488fab 100644 (file)
@@ -93,29 +93,15 @@ _dl_fixup (
            version = NULL;
        }
 
-      struct r_scoperec *scoperec = l->l_scoperec;
       if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
-       {
-         __rtld_mrlock_lock (l->l_scoperec_lock);
-         scoperec = l->l_scoperec;
-         atomic_increment (&scoperec->nusers);
-         __rtld_mrlock_unlock (l->l_scoperec_lock);
-       }
+       __rtld_mrlock_lock (l->l_scope_lock);
 
       result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
-                                   scoperec->scope, version,
-                                   ELF_RTYPE_CLASS_PLT,
+                                   l->l_scope, version, ELF_RTYPE_CLASS_PLT,
                                    DL_LOOKUP_ADD_DEPENDENCY, NULL);
 
-      if (l->l_type == lt_loaded && !SINGLE_THREAD_P
-         && atomic_decrement_val (&scoperec->nusers) == 0
-         && __builtin_expect (scoperec->remove_after_use, 0))
-       {
-         if (scoperec->notify)
-           __rtld_notify (scoperec->nusers);
-         else
-           free (scoperec);
-       }
+      if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
+       __rtld_mrlock_unlock (l->l_scope_lock);
 
       /* Currently result contains the base load address (or link map)
         of the object that defines sym.  Now add in the symbol
@@ -195,29 +181,16 @@ _dl_profile_fixup (
                version = NULL;
            }
 
-         struct r_scoperec *scoperec = l->l_scoperec;
          if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
-           {
-             __rtld_mrlock_lock (l->l_scoperec_lock);
-             scoperec = l->l_scoperec;
-             atomic_increment (&scoperec->nusers);
-             __rtld_mrlock_unlock (l->l_scoperec_lock);
-           }
+           __rtld_mrlock_lock (l->l_scope_lock);
 
          result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, &defsym,
-                                       scoperec->scope, version,
+                                       l->l_scope, version,
                                        ELF_RTYPE_CLASS_PLT,
                                        DL_LOOKUP_ADD_DEPENDENCY, NULL);
 
-         if (l->l_type == lt_loaded && !SINGLE_THREAD_P
-             && atomic_decrement_val (&scoperec->nusers) == 0
-             && __builtin_expect (scoperec->remove_after_use, 0))
-           {
-             if (scoperec->notify)
-               __rtld_notify (scoperec->nusers);
-             else
-               free (scoperec);
-           }
+         if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
+           __rtld_mrlock_unlock (l->l_scope_lock);
 
          /* Currently result contains the base load address (or link map)
             of the object that defines sym.  Now add in the symbol
index 34d75a1..8bb564c 100644 (file)
@@ -65,7 +65,6 @@ struct call_dl_lookup_args
   /* Arguments to do_dlsym.  */
   struct link_map *map;
   const char *name;
-  struct r_scope_elem **scope;
   struct r_found_version *vers;
   int flags;
 
@@ -79,7 +78,7 @@ call_dl_lookup (void *ptr)
 {
   struct call_dl_lookup_args *args = (struct call_dl_lookup_args *) ptr;
   args->map = GLRO(dl_lookup_symbol_x) (args->name, args->map, args->refp,
-                                       args->scope, args->vers, 0,
+                                       args->map->l_scope, args->vers, 0,
                                        args->flags, NULL);
 }
 
@@ -118,20 +117,16 @@ do_sym (void *handle, const char *name, void *who,
         array can change.  */
       if (match->l_type != lt_loaded || SINGLE_THREAD_P)
        result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
-                                          match->l_scoperec->scope, vers, 0,
+                                          match->l_scope, vers, 0,
                                           flags | DL_LOOKUP_ADD_DEPENDENCY,
                                           NULL);
       else
        {
-         __rtld_mrlock_lock (match->l_scoperec_lock);
-         struct r_scoperec *scoperec = match->l_scoperec;
-         atomic_increment (&scoperec->nusers);
-         __rtld_mrlock_unlock (match->l_scoperec_lock);
+         __rtld_mrlock_lock (match->l_scope_lock);
 
          struct call_dl_lookup_args args;
          args.name = name;
          args.map = match;
-         args.scope = scoperec->scope;
          args.vers = vers;
          args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY;
          args.refp = &ref;
@@ -142,14 +137,7 @@ do_sym (void *handle, const char *name, void *who,
          int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced,
                                          call_dl_lookup, &args);
 
-         if (atomic_decrement_val (&scoperec->nusers) == 0
-             && __builtin_expect (scoperec->remove_after_use, 0))
-           {
-             if (scoperec->notify)
-               __rtld_notify (scoperec->nusers);
-             else
-               free (scoperec);
-           }
+         __rtld_mrlock_unlock (match->l_scope_lock);
 
          if (__builtin_expect (errstring != NULL, 0))
            {
index ace3a30..8f0b070 100644 (file)
@@ -609,7 +609,7 @@ relocate_doit (void *a)
 {
   struct relocate_args *args = (struct relocate_args *) a;
 
-  _dl_relocate_object (args->l, args->l->l_scoperec->scope, args->lazy, 0);
+  _dl_relocate_object (args->l, args->l->l_scope, args->lazy, 0);
 }
 
 static void
@@ -1963,7 +1963,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
            lookup_t result;
 
            result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map,
-                                         &ref, main_map->l_scoperec->scope,
+                                         &ref, main_map->l_scope,
                                          NULL, ELF_RTYPE_CLASS_PLT,
                                          DL_LOOKUP_ADD_DEPENDENCY, NULL);
 
@@ -2007,7 +2007,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
                  /* Mark the link map as not yet relocated again.  */
                  GL(dl_rtld_map).l_relocated = 0;
                  _dl_relocate_object (&GL(dl_rtld_map),
-                                      main_map->l_scoperec->scope, 0, 0);
+                                      main_map->l_scope, 0, 0);
                }
             }
 #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
@@ -2143,7 +2143,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 
   /* Now set up the variable which helps the assembler startup code.  */
   GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist;
-  GL(dl_ns)[LM_ID_BASE]._ns_global_scope[0] = &main_map->l_searchlist;
 
   /* Save the information about the original global scope list since
      we need it in the memory handling later.  */
@@ -2227,7 +2226,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
            }
 
          if (l != &GL(dl_rtld_map))
-           _dl_relocate_object (l, l->l_scoperec->scope, GLRO(dl_lazy),
+           _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy),
                                 consider_profiling);
 
 #ifdef USE_TLS
@@ -2303,8 +2302,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
       HP_TIMING_NOW (start);
       /* Mark the link map as not yet relocated again.  */
       GL(dl_rtld_map).l_relocated = 0;
-      _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scoperec->scope,
-                          0, 0);
+      _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
       HP_TIMING_NOW (stop);
       HP_TIMING_DIFF (add, start, stop);
       HP_TIMING_ACCUM_NT (relocate_time, add);
index 4b2f07e..80eff3a 100644 (file)
@@ -75,18 +75,6 @@ struct r_search_path_struct
   };
 
 
-/* Structure for a scope.  Each such data structure has a lock.  The
-   lock allows many readers.  It can be invalidated by setting bit 31
-   which means that no more lockers are allowe */
-struct r_scoperec
-{
-  bool remove_after_use;
-  bool notify;
-  int nusers;
-  struct r_scope_elem *scope[0];
-};
-
-
 /* Structure describing a loaded shared object.  The `l_next' and `l_prev'
    members form a chain of all the shared objects loaded at startup.
 
@@ -226,27 +214,14 @@ struct link_map
     ElfW(Addr) l_text_end;
 
     /* Default array for 'l_scope'.  */
-    union
-    {
-      struct r_scoperec l_scoperec_mem;
-      struct
-      {
-       struct r_scoperec scoperec_struct;
-       /* XXX This number should be increased once the scope memory
-          handling has been tested.  */
-       struct r_scope_elem *scope_elems[4];
-#define NINIT_SCOPE_ELEMS(map) \
-       (sizeof ((map)->l_scope_realmem.scope_elems)                          \
-        / sizeof ((map)->l_scope_realmem.scope_elems[0]))
-      } l_scope_realmem;
-    };
+    struct r_scope_elem *l_scope_mem[4];
     /* Size of array allocated for 'l_scope'.  */
     size_t l_scope_max;
     /* This is an array defining the lookup scope for this link map.
        There are initially at most three different scope lists.  */
-    struct r_scoperec *l_scoperec;
+    struct r_scope_elem **l_scope;
     /* We need to protect using the SCOPEREC.  */
-    __rtld_mrlock_define (, l_scoperec_lock)
+    __rtld_mrlock_define (, l_scope_lock)
 
     /* A similar array, this time only with the local scope.  This is
        used occasionally.  */
index afcb5d8..7921488 100644 (file)
@@ -1,3 +1,32 @@
+2006-10-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/rtld-lowlevel.h (__rtld_mrlock_lock,
+       __rtld_mrlock_change): Update oldval if atomic compare and exchange
+       failed.
+
+       * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (SINGLE_THREAD_P):
+       Define to THREAD_SELF->header.multiple_threads.
+       * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (SINGLE_THREAD_P):
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (SINGLE_THREAD_P):
+       Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (SINGLE_THREAD_P):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
+       (SINGLE_THREAD_P): Likewise.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (SINGLE_THREAD_P):
+       Likewise.
+
 2006-10-26  Jakub Jelinek  <jakub@redhat.com>
 
        * pthread_attr_setstacksize.c (NEW_VERNUM): Define to GLIBC_2_3_3
index f3f7718..7e61d68 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -163,7 +163,13 @@ extern int __local_multiple_threads attribute_hidden;
 
 #else
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index 2d1ad3d..3613e79 100644 (file)
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index 63aaa96..8e6653e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -216,7 +216,13 @@ __GC_##name:                                                                     \
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index dcbc0d6..e40388d 100644 (file)
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index 83eb444..cbc3fa7 100644 (file)
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index 7152dd2..bc7a645 100644 (file)
@@ -67,6 +67,7 @@ typedef int __rtld_mrlock_t;
                                                               oldval);       \
                if (__builtin_expect (ret == oldval, 1))                      \
                  goto out;                                                   \
+               oldval = ret;                                                 \
              }                                                               \
            atomic_delay ();                                                  \
          }                                                                   \
@@ -112,6 +113,7 @@ typedef int __rtld_mrlock_t;
                                                               oldval);       \
                if (__builtin_expect (ret == oldval, 1))                      \
                  goto out;                                                   \
+               oldval = ret;                                                 \
              }                                                               \
            atomic_delay ();                                                  \
          }                                                                   \
index 09dac2c..eb3b14a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -109,7 +109,13 @@ L(pseudo_end):
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index f8eb6a9..ad6dbc9 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -122,7 +122,13 @@ extern int __local_multiple_threads attribute_hidden;
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index 9a967ea..c6821a9 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index 75a4eb9..c780055 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -100,7 +100,13 @@ __##syscall_name##_nocancel:                       \
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index dd263a5..b422f8a 100644 (file)
@@ -98,7 +98,13 @@ __##syscall_name##_nocancel:                 \
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index 97debab..e6afcd3 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -132,7 +132,13 @@ extern int __local_multiple_threads attribute_hidden;
 
 #elif !defined __ASSEMBLER__
 
-# define SINGLE_THREAD_P (1)
+# ifdef IS_IN_rtld
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P (1)
+# endif
 # define NO_CANCELLATION 1
 
 #endif
index e9198bc..4fa3c01 100644 (file)
@@ -377,8 +377,6 @@ struct rtld_global
     struct link_map *_ns_loaded;
     /* Number of object in the _dl_loaded list.  */
     unsigned int _ns_nloaded;
-    /* Array representing global scope.  */
-    struct r_scope_elem *_ns_global_scope[2];
     /* Direct pointer to the searchlist of the main object.  */
     struct r_scope_elem *_ns_main_searchlist;
     /* This is zero at program start to signal that the global scope map is