aboutsummaryrefslogtreecommitdiff
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
parent1614dd9fe02b2ed6ada1f2879cc917934949cc62 (diff)
downloadglibc-08da062122aef3020fd4bf258984102d38bfc12d.tar
glibc-08da062122aef3020fd4bf258984102d38bfc12d.tar.gz
glibc-08da062122aef3020fd4bf258984102d38bfc12d.tar.bz2
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.
-rw-r--r--elf/rtld.c4
-rw-r--r--sysdeps/generic/dl-tls.c26
-rw-r--r--sysdeps/generic/ldsodefs.h4
3 files changed, 26 insertions, 8 deletions
diff --git a/elf/rtld.c b/elf/rtld.c
index 1472c18235..a035a26c99 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -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 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