summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-close.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 7655ef433e..3d8122a375 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -36,19 +36,29 @@ typedef void (*fini_t) (void);
 #ifdef USE_TLS
 /* Returns true we an non-empty was found.  */
 static bool
-remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp)
+remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
+		 bool should_be_there)
 {
   if (idx - disp >= listp->len)
     {
-      /* There must be a next entry.  Otherwise would the index be wrong.  */
-      assert (listp->next != NULL);
-
-      if (remove_slotinfo (idx, listp->next, disp + listp->len))
-	return true;
+      if (listp->next == NULL)
+	{
+	  /* The index is not actually valid in the slotinfo list,
+	     because this object was closed before it was fully setup
+	     due to some error.  */
+	  assert (idx - disp == listp->len);
+	  assert (! should_be_there);
+	}
+      else
+	{
+	  if (remove_slotinfo (idx, listp->next, disp + listp->len,
+			       should_be_there))
+	    return true;
 
-      /* No non-empty entry.  Search from the end of this elements
-	 slotinfo array.  */
-      idx = disp + listp->len;
+	  /* No non-empty entry.  Search from the end of this element's
+	     slotinfo array.  */
+	  idx = disp + listp->len;
+	}
     }
   else
     {
@@ -267,14 +277,14 @@ _dl_close (void *_map)
 	    }
 
 #ifdef USE_TLS
-	  /* Remove the object from the dtv slotinfo array if it uses
-	     TLS.  */
+	  /* Remove the object from the dtv slotinfo array if it uses TLS.  */
 	  if (__builtin_expect (imap->l_tls_blocksize > 0, 0))
 	    {
 	      any_tls = true;
 
 	      if (! remove_slotinfo (imap->l_tls_modid,
-				     GL(dl_tls_dtv_slotinfo_list), 0))
+				     GL(dl_tls_dtv_slotinfo_list), 0,
+				     imap->l_init_called))
 		/* All dynamically loaded modules with TLS are unloaded.  */
 		GL(dl_tls_max_dtv_idx) = GL(dl_tls_static_nelem);
 	    }