2002-08-05 Roland McGrath <roland@redhat.com>
authorRoland McGrath <roland@gnu.org>
Mon, 5 Aug 2002 18:56:03 +0000 (18:56 +0000)
committerRoland McGrath <roland@gnu.org>
Mon, 5 Aug 2002 18:56:03 +0000 (18:56 +0000)
* 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.

elf/rtld.c
sysdeps/generic/dl-tls.c
sysdeps/generic/ldsodefs.h

index 1472c18..a035a26 100644 (file)
@@ -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
 
index 2d211fb..2ef69e5 100644 (file)
@@ -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));
 
index 2269950..cd499f6 100644 (file)
@@ -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