Fri Jul 13 19:50:22 2018 UTC ()
Determine dynamic binaries by presence of PT_INTERP. Static PIE has
_DYNAMIC.


(joerg)
diff -r1.8 -r1.9 src/lib/libc/tls/tls.c

cvs diff -r1.8 -r1.9 src/lib/libc/tls/tls.c (expand / switch to unified diff)

--- src/lib/libc/tls/tls.c 2014/12/14 23:49:17 1.8
+++ src/lib/libc/tls/tls.c 2018/07/13 19:50:21 1.9
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tls.c,v 1.8 2014/12/14 23:49:17 chs Exp $ */ 1/* $NetBSD: tls.c,v 1.9 2018/07/13 19:50:21 joerg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Joerg Sonnenberger. 8 * by Joerg Sonnenberger.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,48 +20,50 @@ @@ -20,48 +20,50 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__RCSID("$NetBSD: tls.c,v 1.8 2014/12/14 23:49:17 chs Exp $"); 33__RCSID("$NetBSD: tls.c,v 1.9 2018/07/13 19:50:21 joerg Exp $");
34 34
35#include "namespace.h" 35#include "namespace.h"
36 36
37#define _rtld_tls_allocate __libc_rtld_tls_allocate 37#define _rtld_tls_allocate __libc_rtld_tls_allocate
38#define _rtld_tls_free __libc_rtld_tls_free 38#define _rtld_tls_free __libc_rtld_tls_free
39 39
40#include <sys/tls.h> 40#include <sys/tls.h>
41 41
42#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II) 42#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/mman.h> 45#include <sys/mman.h>
46#include <link_elf.h> 46#include <link_elf.h>
47#include <lwp.h> 47#include <lwp.h>
 48#include <stdbool.h>
48#include <stddef.h> 49#include <stddef.h>
49#include <stdlib.h> 50#include <stdlib.h>
50#include <string.h> 51#include <string.h>
51#include <unistd.h> 52#include <unistd.h>
52 53
53__dso_hidden void __libc_static_tls_setup(void); 54__dso_hidden void __libc_static_tls_setup(void);
54 55
 56static bool is_dynamic;
55static const void *tls_initaddr; 57static const void *tls_initaddr;
56static size_t tls_initsize; 58static size_t tls_initsize;
57static size_t tls_size; 59static size_t tls_size;
58static size_t tls_allocation; 60static size_t tls_allocation;
59static void *initial_thread_tcb; 61static void *initial_thread_tcb;
60 62
61void * __libc_tls_get_addr(void); 63void * __libc_tls_get_addr(void);
62 64
63__weak_alias(__tls_get_addr, __libc_tls_get_addr) 65__weak_alias(__tls_get_addr, __libc_tls_get_addr)
64#ifdef __i386__ 66#ifdef __i386__
65__weak_alias(___tls_get_addr, __libc_tls_get_addr) 67__weak_alias(___tls_get_addr, __libc_tls_get_addr)
66#endif 68#endif
67 69
@@ -121,51 +123,51 @@ _rtld_tls_free(struct tls_tcb *tcb) @@ -121,51 +123,51 @@ _rtld_tls_free(struct tls_tcb *tcb)
121#ifdef __HAVE_TLS_VARIANT_I 123#ifdef __HAVE_TLS_VARIANT_I
122 /* LINTED */ 124 /* LINTED */
123 p = (uint8_t *)tcb; 125 p = (uint8_t *)tcb;
124#else 126#else
125 /* LINTED */ 127 /* LINTED */
126 p = (uint8_t *)tcb - tls_size; 128 p = (uint8_t *)tcb - tls_size;
127#endif 129#endif
128 if (p == initial_thread_tcb) 130 if (p == initial_thread_tcb)
129 munmap(p, tls_allocation); 131 munmap(p, tls_allocation);
130 else 132 else
131 free(p); 133 free(p);
132} 134}
133 135
134__weakref_visible int rtld_DYNAMIC __weak_reference(_DYNAMIC); 
135 
136static int __section(".text.startup") 136static int __section(".text.startup")
137__libc_static_tls_setup_cb(struct dl_phdr_info *data, size_t len, void *cookie) 137__libc_static_tls_setup_cb(struct dl_phdr_info *data, size_t len, void *cookie)
138{ 138{
139 const Elf_Phdr *phdr = data->dlpi_phdr; 139 const Elf_Phdr *phdr = data->dlpi_phdr;
140 const Elf_Phdr *phlimit = data->dlpi_phdr + data->dlpi_phnum; 140 const Elf_Phdr *phlimit = data->dlpi_phdr + data->dlpi_phnum;
141 141
142 for (; phdr < phlimit; ++phdr) { 142 for (; phdr < phlimit; ++phdr) {
 143 if (phdr->p_type == PT_INTERP) {
 144 is_dynamic = true;
 145 return -1;
 146 }
143 if (phdr->p_type != PT_TLS) 147 if (phdr->p_type != PT_TLS)
144 continue; 148 continue;
145 tls_initaddr = (void *)(phdr->p_vaddr + data->dlpi_addr); 149 tls_initaddr = (void *)(phdr->p_vaddr + data->dlpi_addr);
146 tls_initsize = phdr->p_filesz; 150 tls_initsize = phdr->p_filesz;
147 tls_size = phdr->p_memsz; 151 tls_size = phdr->p_memsz;
148 } 152 }
149 return 0; 153 return 0;
150} 154}
151 155
152void 156void
153__libc_static_tls_setup(void) 157__libc_static_tls_setup(void)
154{ 158{
155 struct tls_tcb *tcb; 159 struct tls_tcb *tcb;
156 160
157 if (&rtld_DYNAMIC != NULL) { 
158 return; 
159 } 
160 
161 dl_iterate_phdr(__libc_static_tls_setup_cb, NULL); 161 dl_iterate_phdr(__libc_static_tls_setup_cb, NULL);
 162 if (is_dynamic)
 163 return;
162 164
163 tcb = _rtld_tls_allocate(); 165 tcb = _rtld_tls_allocate();
164#ifdef __HAVE___LWP_SETTCB 166#ifdef __HAVE___LWP_SETTCB
165 __lwp_settcb(tcb); 167 __lwp_settcb(tcb);
166#else 168#else
167 _lwp_setprivate(tcb); 169 _lwp_setprivate(tcb);
168#endif 170#endif
169} 171}
170 172
171#endif /* __HAVE_TLS_VARIANT_I || __HAVE_TLS_VARIANT_II */ 173#endif /* __HAVE_TLS_VARIANT_I || __HAVE_TLS_VARIANT_II */