diff options
author | Roland McGrath <roland@gnu.org> | 2002-08-05 18:56:03 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2002-08-05 18:56:03 +0000 |
commit | 08da062122aef3020fd4bf258984102d38bfc12d (patch) | |
tree | 328d6483bf27978d2eb8331199f8f2803b156bd4 | |
parent | 1614dd9fe02b2ed6ada1f2879cc917934949cc62 (diff) | |
download | glibc-08da062122aef3020fd4bf258984102d38bfc12d.zip glibc-08da062122aef3020fd4bf258984102d38bfc12d.tar.gz glibc-08da062122aef3020fd4bf258984102d38bfc12d.tar.bz2 |
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.
-rw-r--r-- | elf/rtld.c | 4 | ||||
-rw-r--r-- | sysdeps/generic/dl-tls.c | 26 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 4 |
3 files changed, 26 insertions, 8 deletions
@@ -1091,6 +1091,10 @@ of this helper program; chances are you did not intend to run this program.\n\ if (tcbp == NULL) _dl_fatal_printf ("\ cannot allocate TLS data structures for initial thread"); + + /* Store for detection of the special case by __tls_get_addr + so it knows not to pass this dtv to the normal realloc. */ + _dl_initial_dtv = GET_DTV (tcbp); } #endif diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c index 2d211fb..2ef69e5 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 2269950..cd499f6 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 |