about summary refs log tree commit diff
path: root/sysdeps/generic/dl-tls.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-08-05 18:56:03 +0000
committerRoland McGrath <roland@gnu.org>2002-08-05 18:56:03 +0000
commit08da062122aef3020fd4bf258984102d38bfc12d (patch)
tree328d6483bf27978d2eb8331199f8f2803b156bd4 /sysdeps/generic/dl-tls.c
parent1614dd9fe02b2ed6ada1f2879cc917934949cc62 (diff)
downloadglibc-08da062122aef3020fd4bf258984102d38bfc12d.tar.gz
glibc-08da062122aef3020fd4bf258984102d38bfc12d.tar.xz
glibc-08da062122aef3020fd4bf258984102d38bfc12d.zip
2002-08-05 Roland McGrath <roland@redhat.com>
	* sysdeps/generic/ldsodefs.h (struct rtld_global): Replace member
	`bool _dl_initial_dtv_malloced' with `void *_dl_initial_dtv'.
	* elf/rtld.c (dl_main): Set it to the new dtv for the main thread.
	* sysdeps/generic/dl-tls.c (__tls_get_addr): When reallocating the
	dtv, check if it matches _dl_initial_dtv; if so, malloc and copy the
	old data, abandoning the original memory allocated by rtld at startup,
	instead of calling realloc normally.
Diffstat (limited to 'sysdeps/generic/dl-tls.c')
-rw-r--r--sysdeps/generic/dl-tls.c26
1 files changed, 20 insertions, 6 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));