This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] BZ #14545: Always check dtv before freeing dtv[-1]
On Thu, Sep 6, 2012 at 12:43 PM, Roland McGrath <roland@hack.frob.com> wrote:
>> diff --git a/csu/libc-tls.c b/csu/libc-tls.c
>> index b00a5cc..eb9c502 100644
>> --- a/csu/libc-tls.c
>> +++ b/csu/libc-tls.c
>> @@ -65,6 +65,8 @@ size_t _dl_tls_static_size = 2048;
>> size_t _dl_tls_static_used;
>> /* Alignment requirement of the static TLS block. */
>> size_t _dl_tls_static_align;
>> +/* Initial dtv of the main thread, not allocated with normal malloc. */
>> +void *_dl_initial_dtv = &static_dtv[1];
>
> Make this 'void *const' so it stays in .rodata.
>
> Better yet, make static_dtv a global _dl_static_dtv and put:
>
> #ifndef SHARED
> # define _dl_initial_dtv ((void *) &_dl_static_dtv[1])
> #endif
>
> into ldsodefs.h so we don't waste a data word on this at all.
>
I am testing this patch on x86-64. OK to install if there is
no regression?
Thanks.
--
H.J.
---
2012-09-06 H.J. Lu <hongjiu.lu@intel.com>
* csu/libc-tls.c (static_dtv): Renamed to ...
(_dl_static_dtv): This. Make it global.
(_dl_initial_dtv): Removed.
(__libc_setup_tls): Updated.
* elf/dl-tls.c (DL_INITIAL_DTV): New macro.
(_dl_deallocate_tls): Replace GL(dl_initial_dtv) with
DL_INITIAL_DTV.
diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index eb9c502..9bc4d84 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -32,7 +32,7 @@ extern ElfW(Phdr) *_dl_phdr;
extern size_t _dl_phnum;
-static dtv_t static_dtv[2 + TLS_SLOTINFO_SURPLUS];
+dtv_t _dl_static_dtv[2 + TLS_SLOTINFO_SURPLUS];
static struct
@@ -65,8 +65,6 @@ size_t _dl_tls_static_size = 2048;
size_t _dl_tls_static_used;
/* Alignment requirement of the static TLS block. */
size_t _dl_tls_static_align;
-/* Initial dtv of the main thread, not allocated with normal malloc. */
-void *_dl_initial_dtv = &static_dtv[1];
/* Generation counter for the dtv. */
size_t _dl_tls_generation;
@@ -165,33 +163,33 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
& ~(max_align - 1));
/* Initialize the dtv. [0] is the length, [1] the generation counter. */
- static_dtv[0].counter = (sizeof (static_dtv) / sizeof (static_dtv[0])) - 2;
- // static_dtv[1].counter = 0; would be needed if not already done
+ _dl_static_dtv[0].counter = (sizeof (_dl_static_dtv) / sizeof
(_dl_static_dtv[0])) - 2;
+ // _dl_static_dtv[1].counter = 0; would be needed if not already done
/* Initialize the TLS block. */
#if TLS_TCB_AT_TP
- static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset
+ _dl_static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset
- roundup (memsz, align ?: 1));
static_map.l_tls_offset = roundup (memsz, align ?: 1);
#elif TLS_DTV_AT_TP
- static_dtv[2].pointer.val = (char *) tlsblock + tcb_offset;
+ _dl_static_dtv[2].pointer.val = (char *) tlsblock + tcb_offset;
static_map.l_tls_offset = tcb_offset;
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
- static_dtv[2].pointer.is_static = true;
+ _dl_static_dtv[2].pointer.is_static = true;
/* sbrk gives us zero'd memory, so we don't need to clear the remainder. */
- memcpy (static_dtv[2].pointer.val, initimage, filesz);
+ memcpy (_dl_static_dtv[2].pointer.val, initimage, filesz);
/* Install the pointer to the dtv. */
/* Initialize the thread pointer. */
#if TLS_TCB_AT_TP
- INSTALL_DTV ((char *) tlsblock + tcb_offset, static_dtv);
+ INSTALL_DTV ((char *) tlsblock + tcb_offset, _dl_static_dtv);
const char *lossage = TLS_INIT_TP ((char *) tlsblock + tcb_offset, 0);
#elif TLS_DTV_AT_TP
- INSTALL_DTV (tlsblock, static_dtv);
+ INSTALL_DTV (tlsblock, _dl_static_dtv);
const char *lossage = TLS_INIT_TP (tlsblock, 0);
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index ff59e9e..9d896b7 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -464,6 +464,13 @@ _dl_allocate_tls (void *mem)
rtld_hidden_def (_dl_allocate_tls)
+#ifndef SHARED
+extern dtv_t _dl_static_dtv[];
+# define DL_INITIAL_DTV (&_dl_static_dtv[1])
+#else
+# define DL_INITIAL_DTV GL(dl_initial_dtv)
+#endif
+
void
internal_function
_dl_deallocate_tls (void *tcb, bool dealloc_tcb)
@@ -477,7 +484,7 @@ _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
free (dtv[1 + cnt].pointer.val);
/* The array starts with dtv[-1]. */
- if (dtv != GL(dl_initial_dtv))
+ if (dtv != DL_INITIAL_DTV)
free (dtv - 1);
if (dealloc_tcb)