Deleted Added
full compact
tls.c (160711) tls.c (161800)
1/*-
2 * Copyright (c) 2004 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 2004 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/lib/libc/gen/tls.c 160711 2006-07-26 16:56:56Z imp $
26 * $FreeBSD: head/lib/libc/gen/tls.c 161800 2006-09-01 06:13:16Z marcel $
27 */
28
29/*
30 * Define stubs for TLS internals so that programs and libraries can
31 * link. These functions will be replaced by functional versions at
32 * runtime from ld-elf.so.1.
33 */
34

--- 18 unchanged lines hidden (view full) ---

53void * __libc_tls_get_addr(void *);
54__weak_reference(__libc_tls_get_addr, __tls_get_addr);
55
56void *_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign);
57void _rtld_free_tls(void *tls, size_t tcbsize, size_t tcbalign);
58void *__libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign);
59void __libc_free_tls(void *tls, size_t tcbsize, size_t tcbalign);
60
27 */
28
29/*
30 * Define stubs for TLS internals so that programs and libraries can
31 * link. These functions will be replaced by functional versions at
32 * runtime from ld-elf.so.1.
33 */
34

--- 18 unchanged lines hidden (view full) ---

53void * __libc_tls_get_addr(void *);
54__weak_reference(__libc_tls_get_addr, __tls_get_addr);
55
56void *_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign);
57void _rtld_free_tls(void *tls, size_t tcbsize, size_t tcbalign);
58void *__libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign);
59void __libc_free_tls(void *tls, size_t tcbsize, size_t tcbalign);
60
61#if defined(__ia64__) || defined(__alpha__) || defined(__powerpc__)
61#if defined(__ia64__) || defined(__powerpc__)
62#define TLS_VARIANT_I
63#endif
64#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \
65 defined(__arm__)
66#define TLS_VARIANT_II
67#endif
68
69#ifndef PIC
70
71#define round(size, align) \
72 (((size) + (align) - 1) & ~((align) - 1))
73
74static size_t tls_static_space;
75static size_t tls_init_size;
62#define TLS_VARIANT_I
63#endif
64#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \
65 defined(__arm__)
66#define TLS_VARIANT_II
67#endif
68
69#ifndef PIC
70
71#define round(size, align) \
72 (((size) + (align) - 1) & ~((align) - 1))
73
74static size_t tls_static_space;
75static size_t tls_init_size;
76#ifdef TLS_VARIANT_I
77static size_t tls_init_offset;
78#endif
79static void *tls_init;
80#endif
81
82#ifdef __i386__
83
84/* GNU ABI */
85
86__attribute__((__regparm__(1)))

--- 10 unchanged lines hidden (view full) ---

97{
98 return (0);
99}
100
101#ifndef PIC
102
103#ifdef TLS_VARIANT_I
104
76static void *tls_init;
77#endif
78
79#ifdef __i386__
80
81/* GNU ABI */
82
83__attribute__((__regparm__(1)))

--- 10 unchanged lines hidden (view full) ---

94{
95 return (0);
96}
97
98#ifndef PIC
99
100#ifdef TLS_VARIANT_I
101
102#define TLS_TCB_SIZE (2 * sizeof(void *))
103
105/*
106 * Free Static TLS using the Variant I method.
107 */
108void
104/*
105 * Free Static TLS using the Variant I method.
106 */
107void
109__libc_free_tls(void *tls, size_t tcbsize __unused, size_t tcbalign __unused)
108__libc_free_tls(void *tcb, size_t tcbsize, size_t tcbalign __unused)
110{
109{
111 Elf_Addr* dtv;
110 Elf_Addr *dtv;
111 Elf_Addr **tls;
112
112
113 dtv = ((Elf_Addr**)tls)[0];
114 free(tls);
113 tls = (Elf_Addr **)((Elf_Addr)tcb + tcbsize - TLS_TCB_SIZE);
114 dtv = tls[0];
115 free(dtv);
115 free(dtv);
116 free(tcb);
116}
117
118/*
119 * Allocate Static TLS using the Variant I method.
120 */
121void *
117}
118
119/*
120 * Allocate Static TLS using the Variant I method.
121 */
122void *
122__libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign __unused)
123__libc_allocate_tls(void *oldtcb, size_t tcbsize, size_t tcbalign __unused)
123{
124{
124 size_t size;
125 char *tls;
126 Elf_Addr *dtv;
125 Elf_Addr *dtv;
126 Elf_Addr **tls;
127 char *tcb;
127
128
128 size = tls_static_space;
129 if (size < tcbsize)
130 size = tcbsize;
129 if (oldtcb != NULL && tcbsize == TLS_TCB_SIZE)
130 return (oldtcb);
131
131
132 tls = calloc(1, size);
133 dtv = malloc(3 * sizeof(Elf_Addr));
132 tcb = calloc(1, tls_static_space + tcbsize);
133 tls = (Elf_Addr **)(tcb + tcbsize - TLS_TCB_SIZE);
134
134
135 *(Elf_Addr **) tls = dtv;
135 if (oldtcb != NULL) {
136 memcpy(tls, oldtcb, tls_static_space + TLS_TCB_SIZE);
137 free(oldtcb);
136
138
137 dtv[0] = 1;
138 dtv[1] = 1;
139 dtv[2] = (Elf_Addr)(tls + tls_init_offset);
140 if (oldtls) {
141 /*
142 * Copy the static TLS block over whole.
143 */
144 memcpy(tls + tls_init_offset,
145 (char *)oldtls + tls_init_offset,
146 tls_static_space - tls_init_offset);
147
148 /*
149 * We assume that this block was the one we created with
150 * allocate_initial_tls().
151 */
152 _rtld_free_tls(oldtls, 2 * sizeof(Elf_Addr), sizeof(Elf_Addr));
139 /* Adjust the DTV. */
140 dtv = tls[0];
141 dtv[2] = (Elf_Addr)tls + TLS_TCB_SIZE;
153 } else {
142 } else {
154 memcpy(tls + tls_init_offset, tls_init, tls_init_size);
155 memset(tls + tls_init_offset + tls_init_size,
156 0, tls_static_space - tls_init_size);
143 dtv = malloc(3 * sizeof(Elf_Addr));
144 tls[0] = dtv;
145 dtv[0] = 1;
146 dtv[1] = 1;
147 dtv[2] = (Elf_Addr)tls + TLS_TCB_SIZE;
148
149 if (tls_init_size > 0)
150 memcpy((void*)dtv[2], tls_init, tls_init_size);
151 if (tls_static_space > tls_init_size)
152 memset((void*)(dtv[2] + tls_init_size), 0,
153 tls_static_space - tls_init_size);
157 }
158
154 }
155
159 return tls;
156 return(tcb);
160}
161
162#endif
163
164#ifdef TLS_VARIANT_II
165
157}
158
159#endif
160
161#ifdef TLS_VARIANT_II
162
163#define TLS_TCB_SIZE (3 * sizeof(Elf_Addr))
164
166/*
167 * Free Static TLS using the Variant II method.
168 */
169void
170__libc_free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign)
171{
172 size_t size;
173 Elf_Addr* dtv;

--- 114 unchanged lines hidden (view full) ---

288 break;
289 }
290 }
291 if (phdr == 0 || phent != sizeof(Elf_Phdr) || phnum == 0)
292 return;
293
294 for (i = 0; (unsigned) i < phnum; i++) {
295 if (phdr[i].p_type == PT_TLS) {
165/*
166 * Free Static TLS using the Variant II method.
167 */
168void
169__libc_free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign)
170{
171 size_t size;
172 Elf_Addr* dtv;

--- 114 unchanged lines hidden (view full) ---

287 break;
288 }
289 }
290 if (phdr == 0 || phent != sizeof(Elf_Phdr) || phnum == 0)
291 return;
292
293 for (i = 0; (unsigned) i < phnum; i++) {
294 if (phdr[i].p_type == PT_TLS) {
296#ifdef TLS_VARIANT_I
297 tls_static_space = round(2*sizeof(Elf_Addr),
298 phdr[i].p_align) + phdr[i].p_memsz;
299 tls_init_offset = round(2*sizeof(Elf_Addr),
300 phdr[i].p_align);
301#else
302 tls_static_space = round(phdr[i].p_memsz,
303 phdr[i].p_align);
295 tls_static_space = round(phdr[i].p_memsz,
296 phdr[i].p_align);
304#endif
305 tls_init_size = phdr[i].p_filesz;
306 tls_init = (void*) phdr[i].p_vaddr;
307 }
308 }
309
297 tls_init_size = phdr[i].p_filesz;
298 tls_init = (void*) phdr[i].p_vaddr;
299 }
300 }
301
310 tls = _rtld_allocate_tls(NULL, 3*sizeof(Elf_Addr),
311 sizeof(Elf_Addr));
302 tls = _rtld_allocate_tls(NULL, TLS_TCB_SIZE, 1);
312
313 _set_tp(tls);
314#endif
315}
303
304 _set_tp(tls);
305#endif
306}