10e1c7d0fSDoug Rabson /*- 20e1c7d0fSDoug Rabson * Copyright (c) 2004 Doug Rabson 30e1c7d0fSDoug Rabson * All rights reserved. 40e1c7d0fSDoug Rabson * 50e1c7d0fSDoug Rabson * Redistribution and use in source and binary forms, with or without 60e1c7d0fSDoug Rabson * modification, are permitted provided that the following conditions 70e1c7d0fSDoug Rabson * are met: 80e1c7d0fSDoug Rabson * 1. Redistributions of source code must retain the above copyright 90e1c7d0fSDoug Rabson * notice, this list of conditions and the following disclaimer. 100e1c7d0fSDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 110e1c7d0fSDoug Rabson * notice, this list of conditions and the following disclaimer in the 120e1c7d0fSDoug Rabson * documentation and/or other materials provided with the distribution. 130e1c7d0fSDoug Rabson * 140e1c7d0fSDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 150e1c7d0fSDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 160e1c7d0fSDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 170e1c7d0fSDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 180e1c7d0fSDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 190e1c7d0fSDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 200e1c7d0fSDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 210e1c7d0fSDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 220e1c7d0fSDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 230e1c7d0fSDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 240e1c7d0fSDoug Rabson * SUCH DAMAGE. 250e1c7d0fSDoug Rabson * 260e1c7d0fSDoug Rabson * $FreeBSD$ 270e1c7d0fSDoug Rabson */ 280e1c7d0fSDoug Rabson 290e1c7d0fSDoug Rabson /* 300e1c7d0fSDoug Rabson * Define stubs for TLS internals so that programs and libraries can 310e1c7d0fSDoug Rabson * link. These functions will be replaced by functional versions at 320e1c7d0fSDoug Rabson * runtime from ld-elf.so.1. 330e1c7d0fSDoug Rabson */ 340e1c7d0fSDoug Rabson 3526896bdaSDavid Xu #include <sys/cdefs.h> 366b2d5217SPedro F. Giffuni #include <sys/param.h> 37ccd13c49SDoug Rabson #include <stdlib.h> 38ccd13c49SDoug Rabson #include <string.h> 39ccd13c49SDoug Rabson #include <elf.h> 40*8584ed54SMichal Meloun #include <unistd.h> 4126896bdaSDavid Xu 42ccd13c49SDoug Rabson #include "libc_private.h" 43ccd13c49SDoug Rabson 44*8584ed54SMichal Meloun #define tls_assert(cond) ((cond) ? (void) 0 : \ 45*8584ed54SMichal Meloun (tls_msg(#cond ": assert failed: " __FILE__ ":" \ 46*8584ed54SMichal Meloun __XSTRING(__LINE__) "\n"), abort())) 47*8584ed54SMichal Meloun #define tls_msg(s) write(STDOUT_FILENO, s, strlen(s)) 48*8584ed54SMichal Meloun 49a4bd5210SJason Evans /* Provided by jemalloc to avoid bootstrapping issues. */ 50d0e79aa3SJason Evans void *__je_bootstrap_malloc(size_t size); 51d0e79aa3SJason Evans void *__je_bootstrap_calloc(size_t num, size_t size); 52d0e79aa3SJason Evans void __je_bootstrap_free(void *ptr); 53a4bd5210SJason Evans 5426896bdaSDavid Xu __weak_reference(__libc_allocate_tls, _rtld_allocate_tls); 5526896bdaSDavid Xu __weak_reference(__libc_free_tls, _rtld_free_tls); 5626896bdaSDavid Xu 5726896bdaSDavid Xu #ifdef __i386__ 5826896bdaSDavid Xu 5926896bdaSDavid Xu __weak_reference(___libc_tls_get_addr, ___tls_get_addr); 6026896bdaSDavid Xu __attribute__((__regparm__(1))) void * ___libc_tls_get_addr(void *); 6126896bdaSDavid Xu 6226896bdaSDavid Xu #endif 6326896bdaSDavid Xu 6426896bdaSDavid Xu void * __libc_tls_get_addr(void *); 6526896bdaSDavid Xu __weak_reference(__libc_tls_get_addr, __tls_get_addr); 6626896bdaSDavid Xu 6726896bdaSDavid Xu void *_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign); 6826896bdaSDavid Xu void _rtld_free_tls(void *tls, size_t tcbsize, size_t tcbalign); 6926896bdaSDavid Xu void *__libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign); 7026896bdaSDavid Xu void __libc_free_tls(void *tls, size_t tcbsize, size_t tcbalign); 7126896bdaSDavid Xu 72e7d939bdSMarcel Moolenaar #if defined(__amd64__) 73b84c7a79SKip Macy #define TLS_TCB_ALIGN 16 740bfee928SRuslan Bukin #elif defined(__aarch64__) || defined(__arm__) || defined(__i386__) || \ 75ca20f8ecSRuslan Bukin defined(__mips__) || defined(__powerpc__) || defined(__riscv) || \ 760bfee928SRuslan Bukin defined(__sparc64__) 77b84c7a79SKip Macy #define TLS_TCB_ALIGN sizeof(void *) 78b84c7a79SKip Macy #else 79b84c7a79SKip Macy #error TLS_TCB_ALIGN undefined for target architecture 80b84c7a79SKip Macy #endif 81b84c7a79SKip Macy 820bfee928SRuslan Bukin #if defined(__aarch64__) || defined(__arm__) || defined(__mips__) || \ 83ca20f8ecSRuslan Bukin defined(__powerpc__) || defined(__riscv) 84ccd13c49SDoug Rabson #define TLS_VARIANT_I 85ccd13c49SDoug Rabson #endif 8654da2fb8SOleksandr Tymoshenko #if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) 87ccd13c49SDoug Rabson #define TLS_VARIANT_II 88ccd13c49SDoug Rabson #endif 89ccd13c49SDoug Rabson 90294246bbSEd Maste #ifndef PIC 91ccd13c49SDoug Rabson 92ccd13c49SDoug Rabson static size_t tls_static_space; 93ccd13c49SDoug Rabson static size_t tls_init_size; 94*8584ed54SMichal Meloun static size_t tls_init_align; 95ccd13c49SDoug Rabson static void *tls_init; 96ccd13c49SDoug Rabson #endif 970e1c7d0fSDoug Rabson 980e1c7d0fSDoug Rabson #ifdef __i386__ 990e1c7d0fSDoug Rabson 10026896bdaSDavid Xu /* GNU ABI */ 1010e1c7d0fSDoug Rabson 1020e1c7d0fSDoug Rabson __attribute__((__regparm__(1))) 1030e1c7d0fSDoug Rabson void * 10426896bdaSDavid Xu ___libc_tls_get_addr(void *ti __unused) 1050e1c7d0fSDoug Rabson { 1060e1c7d0fSDoug Rabson return (0); 1070e1c7d0fSDoug Rabson } 1080e1c7d0fSDoug Rabson 1090e1c7d0fSDoug Rabson #endif 1100e1c7d0fSDoug Rabson 1110e1c7d0fSDoug Rabson void * 11226896bdaSDavid Xu __libc_tls_get_addr(void *ti __unused) 1130e1c7d0fSDoug Rabson { 1140e1c7d0fSDoug Rabson return (0); 1150e1c7d0fSDoug Rabson } 1160e1c7d0fSDoug Rabson 117294246bbSEd Maste #ifndef PIC 11826896bdaSDavid Xu 119*8584ed54SMichal Meloun static void * 120*8584ed54SMichal Meloun malloc_aligned(size_t size, size_t align) 121*8584ed54SMichal Meloun { 122*8584ed54SMichal Meloun void *mem, *res; 123*8584ed54SMichal Meloun 124*8584ed54SMichal Meloun if (align < sizeof(void *)) 125*8584ed54SMichal Meloun align = sizeof(void *); 126*8584ed54SMichal Meloun 127*8584ed54SMichal Meloun mem = __je_bootstrap_malloc(size + sizeof(void *) + align - 1); 128*8584ed54SMichal Meloun res = (void *)roundup2((uintptr_t)mem + sizeof(void *), align); 129*8584ed54SMichal Meloun *(void **)((uintptr_t)res - sizeof(void *)) = mem; 130*8584ed54SMichal Meloun return (res); 131*8584ed54SMichal Meloun } 132*8584ed54SMichal Meloun 133*8584ed54SMichal Meloun static void 134*8584ed54SMichal Meloun free_aligned(void *ptr) 135*8584ed54SMichal Meloun { 136*8584ed54SMichal Meloun void *mem; 137*8584ed54SMichal Meloun uintptr_t x; 138*8584ed54SMichal Meloun 139*8584ed54SMichal Meloun if (ptr == NULL) 140*8584ed54SMichal Meloun return; 141*8584ed54SMichal Meloun 142*8584ed54SMichal Meloun x = (uintptr_t)ptr; 143*8584ed54SMichal Meloun x -= sizeof(void *); 144*8584ed54SMichal Meloun mem = *(void **)x; 145*8584ed54SMichal Meloun __je_bootstrap_free(mem); 146*8584ed54SMichal Meloun } 147*8584ed54SMichal Meloun 148ccd13c49SDoug Rabson #ifdef TLS_VARIANT_I 149ccd13c49SDoug Rabson 1503614156cSMarcel Moolenaar #define TLS_TCB_SIZE (2 * sizeof(void *)) 1513614156cSMarcel Moolenaar 15217ceb495SDavid Xu /* 15396a93293SDavid Xu * Free Static TLS using the Variant I method. 15417ceb495SDavid Xu */ 155ccd13c49SDoug Rabson void 156*8584ed54SMichal Meloun __libc_free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign __unused) 157ccd13c49SDoug Rabson { 158ccd13c49SDoug Rabson Elf_Addr *dtv; 1593614156cSMarcel Moolenaar Elf_Addr **tls; 160ccd13c49SDoug Rabson 161*8584ed54SMichal Meloun tls = (Elf_Addr **)tcb; 1623614156cSMarcel Moolenaar dtv = tls[0]; 163d0e79aa3SJason Evans __je_bootstrap_free(dtv); 164*8584ed54SMichal Meloun free_aligned(tls); 165ccd13c49SDoug Rabson } 166ccd13c49SDoug Rabson 167ccd13c49SDoug Rabson /* 168ccd13c49SDoug Rabson * Allocate Static TLS using the Variant I method. 169ccd13c49SDoug Rabson */ 1700e1c7d0fSDoug Rabson void * 171*8584ed54SMichal Meloun __libc_allocate_tls(void *oldtcb, size_t tcbsize, size_t tcbalign) 1720e1c7d0fSDoug Rabson { 173ccd13c49SDoug Rabson Elf_Addr *dtv; 1743614156cSMarcel Moolenaar Elf_Addr **tls; 175ccd13c49SDoug Rabson 1763614156cSMarcel Moolenaar if (oldtcb != NULL && tcbsize == TLS_TCB_SIZE) 1773614156cSMarcel Moolenaar return (oldtcb); 178ccd13c49SDoug Rabson 179*8584ed54SMichal Meloun tls_assert(tcbalign >= TLS_TCB_ALIGN); 180*8584ed54SMichal Meloun tls_assert(tcbsize == TLS_TCB_SIZE); 181*8584ed54SMichal Meloun 182*8584ed54SMichal Meloun tcbsize = roundup2(tcbsize, tcbalign); 183*8584ed54SMichal Meloun tls = malloc_aligned(tcbsize + tls_static_space, tcbalign); 184*8584ed54SMichal Meloun if (tls == NULL) { 185*8584ed54SMichal Meloun tls_msg("__libc_allocate_tls: Out of memory.\n"); 186*8584ed54SMichal Meloun abort(); 187*8584ed54SMichal Meloun } 188*8584ed54SMichal Meloun memset(tls, 0, tcbsize + tls_static_space); 1893614156cSMarcel Moolenaar 1903614156cSMarcel Moolenaar if (oldtcb != NULL) { 191*8584ed54SMichal Meloun memcpy(tls, oldtcb, tcbsize + tls_static_space); 192d0e79aa3SJason Evans __je_bootstrap_free(oldtcb); 1933614156cSMarcel Moolenaar 1943614156cSMarcel Moolenaar /* Adjust the DTV. */ 1953614156cSMarcel Moolenaar dtv = tls[0]; 196*8584ed54SMichal Meloun dtv[2] = (Elf_Addr)tls + tcbsize; 1973614156cSMarcel Moolenaar } else { 198d0e79aa3SJason Evans dtv = __je_bootstrap_malloc(3 * sizeof(Elf_Addr)); 199*8584ed54SMichal Meloun if (dtv == NULL) { 200*8584ed54SMichal Meloun tls_msg("__libc_allocate_tls: Out of memory.\n"); 201*8584ed54SMichal Meloun abort(); 202*8584ed54SMichal Meloun } 2033614156cSMarcel Moolenaar tls[0] = dtv; 204*8584ed54SMichal Meloun dtv[0] = 1; /* Generation. */ 205*8584ed54SMichal Meloun dtv[1] = 1; /* Segments count. */ 206*8584ed54SMichal Meloun dtv[2] = (Elf_Addr)tls + tcbsize; 207ccd13c49SDoug Rabson 2083614156cSMarcel Moolenaar if (tls_init_size > 0) 2093614156cSMarcel Moolenaar memcpy((void*)dtv[2], tls_init, tls_init_size); 2100e1c7d0fSDoug Rabson } 2110e1c7d0fSDoug Rabson 212*8584ed54SMichal Meloun return (tls); 213ccd13c49SDoug Rabson } 214ccd13c49SDoug Rabson 215ccd13c49SDoug Rabson #endif 216ccd13c49SDoug Rabson 217ccd13c49SDoug Rabson #ifdef TLS_VARIANT_II 218ccd13c49SDoug Rabson 2193614156cSMarcel Moolenaar #define TLS_TCB_SIZE (3 * sizeof(Elf_Addr)) 2203614156cSMarcel Moolenaar 221ccd13c49SDoug Rabson /* 222ccd13c49SDoug Rabson * Free Static TLS using the Variant II method. 223ccd13c49SDoug Rabson */ 2240e1c7d0fSDoug Rabson void 22526896bdaSDavid Xu __libc_free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign) 2260e1c7d0fSDoug Rabson { 227ccd13c49SDoug Rabson size_t size; 228ccd13c49SDoug Rabson Elf_Addr* dtv; 229ccd13c49SDoug Rabson Elf_Addr tlsstart, tlsend; 230ccd13c49SDoug Rabson 231ccd13c49SDoug Rabson /* 232ccd13c49SDoug Rabson * Figure out the size of the initial TLS block so that we can 233ccd13c49SDoug Rabson * find stuff which ___tls_get_addr() allocated dynamically. 234ccd13c49SDoug Rabson */ 2356b2d5217SPedro F. Giffuni size = roundup2(tls_static_space, tcbalign); 236ccd13c49SDoug Rabson 237ccd13c49SDoug Rabson dtv = ((Elf_Addr**)tcb)[1]; 238ccd13c49SDoug Rabson tlsend = (Elf_Addr) tcb; 239ccd13c49SDoug Rabson tlsstart = tlsend - size; 240*8584ed54SMichal Meloun free_aligned((void*)tlsstart); 241d0e79aa3SJason Evans __je_bootstrap_free(dtv); 242ccd13c49SDoug Rabson } 243ccd13c49SDoug Rabson 244ccd13c49SDoug Rabson /* 245ccd13c49SDoug Rabson * Allocate Static TLS using the Variant II method. 246ccd13c49SDoug Rabson */ 247ccd13c49SDoug Rabson void * 24826896bdaSDavid Xu __libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign) 249ccd13c49SDoug Rabson { 250ccd13c49SDoug Rabson size_t size; 251ccd13c49SDoug Rabson char *tls; 252ccd13c49SDoug Rabson Elf_Addr *dtv; 253ccd13c49SDoug Rabson Elf_Addr segbase, oldsegbase; 254ccd13c49SDoug Rabson 2556b2d5217SPedro F. Giffuni size = roundup2(tls_static_space, tcbalign); 256ccd13c49SDoug Rabson 2570031cdf4STim Kientzle if (tcbsize < 2 * sizeof(Elf_Addr)) 2580031cdf4STim Kientzle tcbsize = 2 * sizeof(Elf_Addr); 259*8584ed54SMichal Meloun tls = malloc_aligned(size + tcbsize, tcbalign); 260*8584ed54SMichal Meloun if (tls == NULL) { 261*8584ed54SMichal Meloun tls_msg("__libc_allocate_tls: Out of memory.\n"); 262*8584ed54SMichal Meloun abort(); 263*8584ed54SMichal Meloun } 264*8584ed54SMichal Meloun memset(tls, 0, size + tcbsize); 265d0e79aa3SJason Evans dtv = __je_bootstrap_malloc(3 * sizeof(Elf_Addr)); 266*8584ed54SMichal Meloun if (dtv == NULL) { 267*8584ed54SMichal Meloun tls_msg("__libc_allocate_tls: Out of memory.\n"); 268*8584ed54SMichal Meloun abort(); 269*8584ed54SMichal Meloun } 270ccd13c49SDoug Rabson 271ccd13c49SDoug Rabson segbase = (Elf_Addr)(tls + size); 272ccd13c49SDoug Rabson ((Elf_Addr*)segbase)[0] = segbase; 273ccd13c49SDoug Rabson ((Elf_Addr*)segbase)[1] = (Elf_Addr) dtv; 274ccd13c49SDoug Rabson 275ccd13c49SDoug Rabson dtv[0] = 1; 276ccd13c49SDoug Rabson dtv[1] = 1; 277ccd13c49SDoug Rabson dtv[2] = segbase - tls_static_space; 278ccd13c49SDoug Rabson 279ccd13c49SDoug Rabson if (oldtls) { 280ccd13c49SDoug Rabson /* 281ccd13c49SDoug Rabson * Copy the static TLS block over whole. 282ccd13c49SDoug Rabson */ 283ccd13c49SDoug Rabson oldsegbase = (Elf_Addr) oldtls; 284ccd13c49SDoug Rabson memcpy((void *)(segbase - tls_static_space), 285ccd13c49SDoug Rabson (const void *)(oldsegbase - tls_static_space), 286ccd13c49SDoug Rabson tls_static_space); 287ccd13c49SDoug Rabson 288ccd13c49SDoug Rabson /* 289ccd13c49SDoug Rabson * We assume that this block was the one we created with 290ccd13c49SDoug Rabson * allocate_initial_tls(). 291ccd13c49SDoug Rabson */ 292ccd13c49SDoug Rabson _rtld_free_tls(oldtls, 2*sizeof(Elf_Addr), sizeof(Elf_Addr)); 293ccd13c49SDoug Rabson } else { 294ccd13c49SDoug Rabson memcpy((void *)(segbase - tls_static_space), 295ccd13c49SDoug Rabson tls_init, tls_init_size); 296ccd13c49SDoug Rabson memset((void *)(segbase - tls_static_space + tls_init_size), 297ccd13c49SDoug Rabson 0, tls_static_space - tls_init_size); 298ccd13c49SDoug Rabson } 299ccd13c49SDoug Rabson 300ccd13c49SDoug Rabson return (void*) segbase; 301ccd13c49SDoug Rabson } 302ccd13c49SDoug Rabson 30326896bdaSDavid Xu #endif /* TLS_VARIANT_II */ 30426896bdaSDavid Xu 30526896bdaSDavid Xu #else 30626896bdaSDavid Xu 30726896bdaSDavid Xu void * 30826896bdaSDavid Xu __libc_allocate_tls(void *oldtls __unused, size_t tcbsize __unused, 30926896bdaSDavid Xu size_t tcbalign __unused) 31026896bdaSDavid Xu { 31126896bdaSDavid Xu return (0); 31226896bdaSDavid Xu } 31326896bdaSDavid Xu 31426896bdaSDavid Xu void 31526896bdaSDavid Xu __libc_free_tls(void *tcb __unused, size_t tcbsize __unused, 31626896bdaSDavid Xu size_t tcbalign __unused) 31726896bdaSDavid Xu { 31826896bdaSDavid Xu } 31926896bdaSDavid Xu 320294246bbSEd Maste #endif /* PIC */ 32126896bdaSDavid Xu 32226896bdaSDavid Xu extern char **environ; 323ccd13c49SDoug Rabson 324ccd13c49SDoug Rabson void 32555b6b759SCraig Rodrigues _init_tls(void) 326ccd13c49SDoug Rabson { 327294246bbSEd Maste #ifndef PIC 328ccd13c49SDoug Rabson Elf_Addr *sp; 329ccd13c49SDoug Rabson Elf_Auxinfo *aux, *auxp; 330ccd13c49SDoug Rabson Elf_Phdr *phdr; 331ccd13c49SDoug Rabson size_t phent, phnum; 332ccd13c49SDoug Rabson int i; 3330e7e4e5fSDoug Rabson void *tls; 334ccd13c49SDoug Rabson 335ccd13c49SDoug Rabson sp = (Elf_Addr *) environ; 336ccd13c49SDoug Rabson while (*sp++ != 0) 337ccd13c49SDoug Rabson ; 338ccd13c49SDoug Rabson aux = (Elf_Auxinfo *) sp; 339513004a2SPedro F. Giffuni phdr = NULL; 340ccd13c49SDoug Rabson phent = phnum = 0; 341ccd13c49SDoug Rabson for (auxp = aux; auxp->a_type != AT_NULL; auxp++) { 342ccd13c49SDoug Rabson switch (auxp->a_type) { 343ccd13c49SDoug Rabson case AT_PHDR: 344ccd13c49SDoug Rabson phdr = auxp->a_un.a_ptr; 345ccd13c49SDoug Rabson break; 346ccd13c49SDoug Rabson 347ccd13c49SDoug Rabson case AT_PHENT: 348ccd13c49SDoug Rabson phent = auxp->a_un.a_val; 349ccd13c49SDoug Rabson break; 350ccd13c49SDoug Rabson 351ccd13c49SDoug Rabson case AT_PHNUM: 352ccd13c49SDoug Rabson phnum = auxp->a_un.a_val; 353ccd13c49SDoug Rabson break; 354ccd13c49SDoug Rabson } 355ccd13c49SDoug Rabson } 356513004a2SPedro F. Giffuni if (phdr == NULL || phent != sizeof(Elf_Phdr) || phnum == 0) 357ccd13c49SDoug Rabson return; 358ccd13c49SDoug Rabson 35926896bdaSDavid Xu for (i = 0; (unsigned) i < phnum; i++) { 360ccd13c49SDoug Rabson if (phdr[i].p_type == PT_TLS) { 3616b2d5217SPedro F. Giffuni tls_static_space = roundup2(phdr[i].p_memsz, 362ccd13c49SDoug Rabson phdr[i].p_align); 363ccd13c49SDoug Rabson tls_init_size = phdr[i].p_filesz; 364*8584ed54SMichal Meloun tls_init_align = phdr[i].p_align; 365ccd13c49SDoug Rabson tls_init = (void*) phdr[i].p_vaddr; 366*8584ed54SMichal Meloun break; 367ccd13c49SDoug Rabson } 368ccd13c49SDoug Rabson } 369ccd13c49SDoug Rabson 370*8584ed54SMichal Meloun tls = _rtld_allocate_tls(NULL, TLS_TCB_SIZE, 371*8584ed54SMichal Meloun MAX(TLS_TCB_ALIGN, tls_init_align)); 372ccd13c49SDoug Rabson 373ccd13c49SDoug Rabson _set_tp(tls); 374ccd13c49SDoug Rabson #endif 3750e1c7d0fSDoug Rabson } 376