Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src/libexec/ld.elf_so Pull up following revision(s) (requeste...



details:   https://anonhg.NetBSD.org/src/rev/4d27f8ead639
branches:  netbsd-8
changeset: 850862:4d27f8ead639
user:      snj <snj%NetBSD.org@localhost>
date:      Tue Jul 25 01:36:58 2017 +0000

description:
Pull up following revision(s) (requested by joerg in ticket #133):
        libexec/ld.elf_so/tls.c: revision 1.11
Fix two bugs related to promotion of DSO TLS blocks into the static
thread allocation:
(1) Set the DTV vector up whenever an offset into the static allocation
is assigned, even if the block itself is not initialized. This has been
seen in libstdc++.
(2) Do not free a DTV block if it is part of the static thread
allocation.

diffstat:

 libexec/ld.elf_so/tls.c |  25 +++++++++++++++----------
 1 files changed, 15 insertions(+), 10 deletions(-)

diffs (69 lines):

diff -r fe8f6f6aee78 -r 4d27f8ead639 libexec/ld.elf_so/tls.c
--- a/libexec/ld.elf_so/tls.c   Tue Jul 25 01:35:53 2017 +0000
+++ b/libexec/ld.elf_so/tls.c   Tue Jul 25 01:36:58 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tls.c,v 1.10 2014/12/14 23:49:17 chs Exp $     */
+/*     $NetBSD: tls.c,v 1.10.8.1 2017/07/25 01:36:58 snj Exp $ */
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: tls.c,v 1.10 2014/12/14 23:49:17 chs Exp $");
+__RCSID("$NetBSD: tls.c,v 1.10.8.1 2017/07/25 01:36:58 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/ucontext.h>
@@ -134,7 +134,7 @@
        SET_DTV_GENERATION(tcb->tcb_dtv, _rtld_tls_dtv_generation);
 
        for (obj = _rtld_objlist; obj != NULL; obj = obj->next) {
-               if (obj->tlsinitsize && obj->tls_done) {
+               if (obj->tls_done) {
 #ifdef __HAVE_TLS_VARIANT_I
                        q = p + obj->tlsoffset;
 #else
@@ -142,7 +142,8 @@
 #endif
                        dbg(("obj %p dtv %p tlsoffset %zu",
                            obj, q, obj->tlsoffset));
-                       memcpy(q, obj->tlsinit, obj->tlsinitsize);
+                       if (obj->tlsinitsize)
+                               memcpy(q, obj->tlsinit, obj->tlsinitsize);
                        tcb->tcb_dtv[obj->tlsindex] = q;
                }
        }
@@ -167,21 +168,25 @@
 _rtld_tls_free(struct tls_tcb *tcb)
 {
        size_t i, max_index;
-       uint8_t *p;
+       uint8_t *p, *p_end;
        sigset_t mask;
 
        _rtld_exclusive_enter(&mask);
 
-       max_index = DTV_MAX_INDEX(tcb->tcb_dtv);
-       for (i = 1; i <= max_index; ++i)
-               xfree(tcb->tcb_dtv[i]);
-       xfree(tcb->tcb_dtv - 1);
-
 #ifdef __HAVE_TLS_VARIANT_I
        p = (uint8_t *)tcb;
 #else
        p = (uint8_t *)tcb - _rtld_tls_static_space;
 #endif
+       p_end = p + _rtld_tls_static_space;
+
+       max_index = DTV_MAX_INDEX(tcb->tcb_dtv);
+       for (i = 1; i <= max_index; ++i) {
+               if ((uint8_t *)tcb->tcb_dtv[i] < p ||
+                   (uint8_t *)tcb->tcb_dtv[i] >= p_end)
+                       xfree(tcb->tcb_dtv[i]);
+       }
+       xfree(tcb->tcb_dtv - 1);
        xfree(p);
 
        _rtld_exclusive_exit(&mask);



Home | Main Index | Thread Index | Old Index