about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/dl-tls.c26
-rw-r--r--sysdeps/generic/ldsodefs.h4
2 files changed, 22 insertions, 8 deletions
diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c
index 2d211fb662..2ef69e5abc 100644
--- a/sysdeps/generic/dl-tls.c
+++ b/sysdeps/generic/dl-tls.c
@@ -487,15 +487,29 @@ __tls_get_addr (GET_ADDR_ARGS)
 
 		      assert (map->l_tls_modid <= newsize);
 
-		      newp = (dtv_t *) realloc (&dtv[-1],
-						(2 + newsize)
-						* sizeof (dtv_t));
-		      if (newp == NULL)
-			oom ();
+		      if (dtv == GL(dl_initial_dtv))
+			{
+			  /* This is the initial dtv that was allocated
+			     during rtld startup using the dl-minimal.c
+			     malloc instead of the real malloc.  We can't
+			     free it, we have to abandon the old storage.  */
+
+			  newp = malloc ((2 + newsize) * sizeof (dtv_t));
+			  if (newp == NULL)
+			    oom ();
+			  memcpy (newp, &dtv[-1], oldsize * sizeof (dtv_t));
+			}
+		      else
+			{
+			  newp = realloc (&dtv[-1],
+					  (2 + newsize) * sizeof (dtv_t));
+			  if (newp == NULL)
+			    oom ();
+			}
 
 		      newp[0].counter = newsize;
 
-		      /* Clear the newly allocate part.  */
+		      /* Clear the newly allocated part.  */
 		      memset (newp + 2 + oldsize, '\0',
 			      (newsize - oldsize) * sizeof (dtv_t));
 
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 2269950045..cd499f61b7 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -323,8 +323,8 @@ struct rtld_global
 /* Number of additional slots in the dtv allocated.  */
 # define DTV_SURPLUS	(14)
 
-  /* True if the dtv for the initial thread was malloc()ed.  */
-  EXTERN bool _dl_initial_dtv_malloced;
+  /* Initial dtv of the main thread, not allocated with normal malloc.  */
+  EXTERN void *_dl_initial_dtv;
   /* Generation counter for the dtv.  */
   EXTERN size_t _dl_tls_generation;
 #endif