summary refs log tree commit diff
path: root/elf/dl-close.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-close.c')
-rw-r--r--elf/dl-close.c67
1 files changed, 28 insertions, 39 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);