summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-10-27 15:54:20 +0000
committerUlrich Drepper <drepper@redhat.com>2006-10-27 15:54:20 +0000
commitc0a777e8d01ab40dd9c0ce95328430a4ce7299e3 (patch)
treecf716a0ed441fb850dd3ec3774aa6eebeac4d95b /elf
parentee96ce2fca39c9660a7efccb708f4ad876b24883 (diff)
downloadglibc-c0a777e8d01ab40dd9c0ce95328430a4ce7299e3.tar.gz
glibc-c0a777e8d01ab40dd9c0ce95328430a4ce7299e3.tar.xz
glibc-c0a777e8d01ab40dd9c0ce95328430a4ce7299e3.zip
* 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.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-close.c67
-rw-r--r--elf/dl-libc.c3
-rw-r--r--elf/dl-load.c8
-rw-r--r--elf/dl-lookup.c8
-rw-r--r--elf/dl-object.c16
-rw-r--r--elf/dl-open.c61
-rw-r--r--elf/dl-runtime.c43
-rw-r--r--elf/dl-sym.c20
-rw-r--r--elf/rtld.c12
9 files changed, 85 insertions, 153 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c
index bfcceea4bc..31bc80b935 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -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);
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index 8b78a7a388..a6d0d1fcef 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -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;
 }
 
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 172fb2fc35..36dc123c01 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -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.  */
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 72381698db..29a52165ce 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -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)
 {
diff --git a/elf/dl-object.c b/elf/dl-object.c
index c5dae9ef11..29f44bfd55 100644
--- a/elf/dl-object.c
+++ b/elf/dl-object.c
@@ -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;
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 85b9637305..2ae861f9cc 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -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
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 8bf5b89eb6..0488fab8d0 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -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
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 34d75a1a67..8bb564c2fe 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -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))
 	    {
diff --git a/elf/rtld.c b/elf/rtld.c
index ace3a3099d..8f0b0703a7 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -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);