10e1c7d0fSDoug Rabson /*- 2*d915a14eSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*d915a14eSPedro F. Giffuni * 40e1c7d0fSDoug Rabson * Copyright (c) 2004 Doug Rabson 50e1c7d0fSDoug Rabson * All rights reserved. 60e1c7d0fSDoug Rabson * 70e1c7d0fSDoug Rabson * Redistribution and use in source and binary forms, with or without 80e1c7d0fSDoug Rabson * modification, are permitted provided that the following conditions 90e1c7d0fSDoug Rabson * are met: 100e1c7d0fSDoug Rabson * 1. Redistributions of source code must retain the above copyright 110e1c7d0fSDoug Rabson * notice, this list of conditions and the following disclaimer. 120e1c7d0fSDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 130e1c7d0fSDoug Rabson * notice, this list of conditions and the following disclaimer in the 140e1c7d0fSDoug Rabson * documentation and/or other materials provided with the distribution. 150e1c7d0fSDoug Rabson * 160e1c7d0fSDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 170e1c7d0fSDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 180e1c7d0fSDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 190e1c7d0fSDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 200e1c7d0fSDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 210e1c7d0fSDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 220e1c7d0fSDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 230e1c7d0fSDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 240e1c7d0fSDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 250e1c7d0fSDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 260e1c7d0fSDoug Rabson * SUCH DAMAGE. 270e1c7d0fSDoug Rabson * 280e1c7d0fSDoug Rabson * $FreeBSD$ 290e1c7d0fSDoug Rabson */ 300e1c7d0fSDoug Rabson 310e1c7d0fSDoug Rabson /* 320e1c7d0fSDoug Rabson * Define stubs for TLS internals so that programs and libraries can 330e1c7d0fSDoug Rabson * link. These functions will be replaced by functional versions at 340e1c7d0fSDoug Rabson * runtime from ld-elf.so.1. 350e1c7d0fSDoug Rabson */ 360e1c7d0fSDoug Rabson 3726896bdaSDavid Xu #include <sys/cdefs.h> 386b2d5217SPedro F. Giffuni #include <sys/param.h> 39ccd13c49SDoug Rabson #include <stdlib.h> 40ccd13c49SDoug Rabson #include <string.h> 41ccd13c49SDoug Rabson #include <elf.h> 428584ed54SMichal Meloun #include <unistd.h> 4326896bdaSDavid Xu 44ccd13c49SDoug Rabson #include "libc_private.h" 45ccd13c49SDoug Rabson 468584ed54SMichal Meloun #define tls_assert(cond) ((cond) ? (void) 0 : \ 478584ed54SMichal Meloun (tls_msg(#cond ": assert failed: " __FILE__ ":" \ 488584ed54SMichal Meloun __XSTRING(__LINE__) "\n"), abort())) 498584ed54SMichal Meloun #define tls_msg(s) write(STDOUT_FILENO, s, strlen(s)) 508584ed54SMichal Meloun 51a4bd5210SJason Evans /* Provided by jemalloc to avoid bootstrapping issues. */ 52d0e79aa3SJason Evans void *__je_bootstrap_malloc(size_t size); 53d0e79aa3SJason Evans void *__je_bootstrap_calloc(size_t num, size_t size); 54d0e79aa3SJason Evans void __je_bootstrap_free(void *ptr); 55a4bd5210SJason Evans 5626896bdaSDavid Xu __weak_reference(__libc_allocate_tls, _rtld_allocate_tls); 5726896bdaSDavid Xu __weak_reference(__libc_free_tls, _rtld_free_tls); 5826896bdaSDavid Xu 5926896bdaSDavid Xu #ifdef __i386__ 6026896bdaSDavid Xu 6126896bdaSDavid Xu __weak_reference(___libc_tls_get_addr, ___tls_get_addr); 6226896bdaSDavid Xu __attribute__((__regparm__(1))) void * ___libc_tls_get_addr(void *); 6326896bdaSDavid Xu 6426896bdaSDavid Xu #endif 6526896bdaSDavid Xu 6626896bdaSDavid Xu void * __libc_tls_get_addr(void *); 6726896bdaSDavid Xu __weak_reference(__libc_tls_get_addr, __tls_get_addr); 6826896bdaSDavid Xu 6926896bdaSDavid Xu void *_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign); 7026896bdaSDavid Xu void _rtld_free_tls(void *tls, size_t tcbsize, size_t tcbalign); 7126896bdaSDavid Xu void *__libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign); 7226896bdaSDavid Xu void __libc_free_tls(void *tls, size_t tcbsize, size_t tcbalign); 7326896bdaSDavid Xu 74e7d939bdSMarcel Moolenaar #if defined(__amd64__) 75b84c7a79SKip Macy #define TLS_TCB_ALIGN 16 760bfee928SRuslan Bukin #elif defined(__aarch64__) || defined(__arm__) || defined(__i386__) || \ 77ca20f8ecSRuslan Bukin defined(__mips__) || defined(__powerpc__) || defined(__riscv) || \ 780bfee928SRuslan Bukin defined(__sparc64__) 79b84c7a79SKip Macy #define TLS_TCB_ALIGN sizeof(void *) 80b84c7a79SKip Macy #else 81b84c7a79SKip Macy #error TLS_TCB_ALIGN undefined for target architecture 82b84c7a79SKip Macy #endif 83b84c7a79SKip Macy 840bfee928SRuslan Bukin #if defined(__aarch64__) || defined(__arm__) || defined(__mips__) || \ 85ca20f8ecSRuslan Bukin defined(__powerpc__) || defined(__riscv) 86ccd13c49SDoug Rabson #define TLS_VARIANT_I 87ccd13c49SDoug Rabson #endif 8854da2fb8SOleksandr Tymoshenko #if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) 89ccd13c49SDoug Rabson #define TLS_VARIANT_II 90ccd13c49SDoug Rabson #endif 91ccd13c49SDoug Rabson 92294246bbSEd Maste #ifndef PIC 93ccd13c49SDoug Rabson 94ccd13c49SDoug Rabson static size_t tls_static_space; 95ccd13c49SDoug Rabson static size_t tls_init_size; 968584ed54SMichal Meloun static size_t tls_init_align; 97ccd13c49SDoug Rabson static void *tls_init; 98ccd13c49SDoug Rabson #endif 990e1c7d0fSDoug Rabson 1000e1c7d0fSDoug Rabson #ifdef __i386__ 1010e1c7d0fSDoug Rabson 10226896bdaSDavid Xu /* GNU ABI */ 1030e1c7d0fSDoug Rabson 1040e1c7d0fSDoug Rabson __attribute__((__regparm__(1))) 1050e1c7d0fSDoug Rabson void * 10626896bdaSDavid Xu ___libc_tls_get_addr(void *ti __unused) 1070e1c7d0fSDoug Rabson { 1080e1c7d0fSDoug Rabson return (0); 1090e1c7d0fSDoug Rabson } 1100e1c7d0fSDoug Rabson 1110e1c7d0fSDoug Rabson #endif 1120e1c7d0fSDoug Rabson 1130e1c7d0fSDoug Rabson void * 11426896bdaSDavid Xu __libc_tls_get_addr(void *ti __unused) 1150e1c7d0fSDoug Rabson { 1160e1c7d0fSDoug Rabson return (0); 1170e1c7d0fSDoug Rabson } 1180e1c7d0fSDoug Rabson 119294246bbSEd Maste #ifndef PIC 12026896bdaSDavid Xu 1218584ed54SMichal Meloun static void * 1228584ed54SMichal Meloun malloc_aligned(size_t size, size_t align) 1238584ed54SMichal Meloun { 1248584ed54SMichal Meloun void *mem, *res; 1258584ed54SMichal Meloun 1268584ed54SMichal Meloun if (align < sizeof(void *)) 1278584ed54SMichal Meloun align = sizeof(void *); 1288584ed54SMichal Meloun 1298584ed54SMichal Meloun mem = __je_bootstrap_malloc(size + sizeof(void *) + align - 1); 1308584ed54SMichal Meloun res = (void *)roundup2((uintptr_t)mem + sizeof(void *), align); 1318584ed54SMichal Meloun *(void **)((uintptr_t)res - sizeof(void *)) = mem; 1328584ed54SMichal Meloun return (res); 1338584ed54SMichal Meloun } 1348584ed54SMichal Meloun 1358584ed54SMichal Meloun static void 1368584ed54SMichal Meloun free_aligned(void *ptr) 1378584ed54SMichal Meloun { 1388584ed54SMichal Meloun void *mem; 1398584ed54SMichal Meloun uintptr_t x; 1408584ed54SMichal Meloun 1418584ed54SMichal Meloun if (ptr == NULL) 1428584ed54SMichal Meloun return; 1438584ed54SMichal Meloun 1448584ed54SMichal Meloun x = (uintptr_t)ptr; 1458584ed54SMichal Meloun x -= sizeof(void *); 1468584ed54SMichal Meloun mem = *(void **)x; 1478584ed54SMichal Meloun __je_bootstrap_free(mem); 1488584ed54SMichal Meloun } 1498584ed54SMichal Meloun 150ccd13c49SDoug Rabson #ifdef TLS_VARIANT_I 151ccd13c49SDoug Rabson 1523614156cSMarcel Moolenaar #define TLS_TCB_SIZE (2 * sizeof(void *)) 1533614156cSMarcel Moolenaar 15417ceb495SDavid Xu /* 15596a93293SDavid Xu * Free Static TLS using the Variant I method. 15617ceb495SDavid Xu */ 157ccd13c49SDoug Rabson void 1588584ed54SMichal Meloun __libc_free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign __unused) 159ccd13c49SDoug Rabson { 160ccd13c49SDoug Rabson Elf_Addr *dtv; 1613614156cSMarcel Moolenaar Elf_Addr **tls; 162ccd13c49SDoug Rabson 1638584ed54SMichal Meloun tls = (Elf_Addr **)tcb; 1643614156cSMarcel Moolenaar dtv = tls[0]; 165d0e79aa3SJason Evans __je_bootstrap_free(dtv); 1668584ed54SMichal Meloun free_aligned(tls); 167ccd13c49SDoug Rabson } 168ccd13c49SDoug Rabson 169ccd13c49SDoug Rabson /* 170ccd13c49SDoug Rabson * Allocate Static TLS using the Variant I method. 171ccd13c49SDoug Rabson */ 1720e1c7d0fSDoug Rabson void * 1738584ed54SMichal Meloun __libc_allocate_tls(void *oldtcb, size_t tcbsize, size_t tcbalign) 1740e1c7d0fSDoug Rabson { 175ccd13c49SDoug Rabson Elf_Addr *dtv; 1763614156cSMarcel Moolenaar Elf_Addr **tls; 177ccd13c49SDoug Rabson 1783614156cSMarcel Moolenaar if (oldtcb != NULL && tcbsize == TLS_TCB_SIZE) 1793614156cSMarcel Moolenaar return (oldtcb); 180ccd13c49SDoug Rabson 1818584ed54SMichal Meloun tls_assert(tcbalign >= TLS_TCB_ALIGN); 1828584ed54SMichal Meloun tls_assert(tcbsize == TLS_TCB_SIZE); 1838584ed54SMichal Meloun 1848584ed54SMichal Meloun tcbsize = roundup2(tcbsize, tcbalign); 1858584ed54SMichal Meloun tls = malloc_aligned(tcbsize + tls_static_space, tcbalign); 1868584ed54SMichal Meloun if (tls == NULL) { 1878584ed54SMichal Meloun tls_msg("__libc_allocate_tls: Out of memory.\n"); 1888584ed54SMichal Meloun abort(); 1898584ed54SMichal Meloun } 1908584ed54SMichal Meloun memset(tls, 0, tcbsize + tls_static_space); 1913614156cSMarcel Moolenaar 1923614156cSMarcel Moolenaar if (oldtcb != NULL) { 1938584ed54SMichal Meloun memcpy(tls, oldtcb, tcbsize + tls_static_space); 194d0e79aa3SJason Evans __je_bootstrap_free(oldtcb); 1953614156cSMarcel Moolenaar 1963614156cSMarcel Moolenaar /* Adjust the DTV. */ 1973614156cSMarcel Moolenaar dtv = tls[0]; 1988584ed54SMichal Meloun dtv[2] = (Elf_Addr)tls + tcbsize; 1993614156cSMarcel Moolenaar } else { 200d0e79aa3SJason Evans dtv = __je_bootstrap_malloc(3 * sizeof(Elf_Addr)); 2018584ed54SMichal Meloun if (dtv == NULL) { 2028584ed54SMichal Meloun tls_msg("__libc_allocate_tls: Out of memory.\n"); 2038584ed54SMichal Meloun abort(); 2048584ed54SMichal Meloun } 2053614156cSMarcel Moolenaar tls[0] = dtv; 2068584ed54SMichal Meloun dtv[0] = 1; /* Generation. */ 2078584ed54SMichal Meloun dtv[1] = 1; /* Segments count. */ 2088584ed54SMichal Meloun dtv[2] = (Elf_Addr)tls + tcbsize; 209ccd13c49SDoug Rabson 2103614156cSMarcel Moolenaar if (tls_init_size > 0) 2113614156cSMarcel Moolenaar memcpy((void*)dtv[2], tls_init, tls_init_size); 2120e1c7d0fSDoug Rabson } 2130e1c7d0fSDoug Rabson 2148584ed54SMichal Meloun return (tls); 215ccd13c49SDoug Rabson } 216ccd13c49SDoug Rabson 217ccd13c49SDoug Rabson #endif 218ccd13c49SDoug Rabson 219ccd13c49SDoug Rabson #ifdef TLS_VARIANT_II 220ccd13c49SDoug Rabson 2213614156cSMarcel Moolenaar #define TLS_TCB_SIZE (3 * sizeof(Elf_Addr)) 2223614156cSMarcel Moolenaar 223ccd13c49SDoug Rabson /* 224ccd13c49SDoug Rabson * Free Static TLS using the Variant II method. 225ccd13c49SDoug Rabson */ 2260e1c7d0fSDoug Rabson void 22726896bdaSDavid Xu __libc_free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign) 2280e1c7d0fSDoug Rabson { 229ccd13c49SDoug Rabson size_t size; 230ccd13c49SDoug Rabson Elf_Addr* dtv; 231ccd13c49SDoug Rabson Elf_Addr tlsstart, tlsend; 232ccd13c49SDoug Rabson 233ccd13c49SDoug Rabson /* 234ccd13c49SDoug Rabson * Figure out the size of the initial TLS block so that we can 235ccd13c49SDoug Rabson * find stuff which ___tls_get_addr() allocated dynamically. 236ccd13c49SDoug Rabson */ 2376b2d5217SPedro F. Giffuni size = roundup2(tls_static_space, tcbalign); 238ccd13c49SDoug Rabson 239ccd13c49SDoug Rabson dtv = ((Elf_Addr**)tcb)[1]; 240ccd13c49SDoug Rabson tlsend = (Elf_Addr) tcb; 241ccd13c49SDoug Rabson tlsstart = tlsend - size; 2428584ed54SMichal Meloun free_aligned((void*)tlsstart); 243d0e79aa3SJason Evans __je_bootstrap_free(dtv); 244ccd13c49SDoug Rabson } 245ccd13c49SDoug Rabson 246ccd13c49SDoug Rabson /* 247ccd13c49SDoug Rabson * Allocate Static TLS using the Variant II method. 248ccd13c49SDoug Rabson */ 249ccd13c49SDoug Rabson void * 25026896bdaSDavid Xu __libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign) 251ccd13c49SDoug Rabson { 252ccd13c49SDoug Rabson size_t size; 253ccd13c49SDoug Rabson char *tls; 254ccd13c49SDoug Rabson Elf_Addr *dtv; 255ccd13c49SDoug Rabson Elf_Addr segbase, oldsegbase; 256ccd13c49SDoug Rabson 2576b2d5217SPedro F. Giffuni size = roundup2(tls_static_space, tcbalign); 258ccd13c49SDoug Rabson 2590031cdf4STim Kientzle if (tcbsize < 2 * sizeof(Elf_Addr)) 2600031cdf4STim Kientzle tcbsize = 2 * sizeof(Elf_Addr); 2618584ed54SMichal Meloun tls = malloc_aligned(size + tcbsize, tcbalign); 2628584ed54SMichal Meloun if (tls == NULL) { 2638584ed54SMichal Meloun tls_msg("__libc_allocate_tls: Out of memory.\n"); 2648584ed54SMichal Meloun abort(); 2658584ed54SMichal Meloun } 2668584ed54SMichal Meloun memset(tls, 0, size + tcbsize); 267d0e79aa3SJason Evans dtv = __je_bootstrap_malloc(3 * sizeof(Elf_Addr)); 2688584ed54SMichal Meloun if (dtv == NULL) { 2698584ed54SMichal Meloun tls_msg("__libc_allocate_tls: Out of memory.\n"); 2708584ed54SMichal Meloun abort(); 2718584ed54SMichal Meloun } 272ccd13c49SDoug Rabson 273ccd13c49SDoug Rabson segbase = (Elf_Addr)(tls + size); 274ccd13c49SDoug Rabson ((Elf_Addr*)segbase)[0] = segbase; 275ccd13c49SDoug Rabson ((Elf_Addr*)segbase)[1] = (Elf_Addr) dtv; 276ccd13c49SDoug Rabson 277ccd13c49SDoug Rabson dtv[0] = 1; 278ccd13c49SDoug Rabson dtv[1] = 1; 279ccd13c49SDoug Rabson dtv[2] = segbase - tls_static_space; 280ccd13c49SDoug Rabson 281ccd13c49SDoug Rabson if (oldtls) { 282ccd13c49SDoug Rabson /* 283ccd13c49SDoug Rabson * Copy the static TLS block over whole. 284ccd13c49SDoug Rabson */ 285ccd13c49SDoug Rabson oldsegbase = (Elf_Addr) oldtls; 286ccd13c49SDoug Rabson memcpy((void *)(segbase - tls_static_space), 287ccd13c49SDoug Rabson (const void *)(oldsegbase - tls_static_space), 288ccd13c49SDoug Rabson tls_static_space); 289ccd13c49SDoug Rabson 290ccd13c49SDoug Rabson /* 291ccd13c49SDoug Rabson * We assume that this block was the one we created with 292ccd13c49SDoug Rabson * allocate_initial_tls(). 293ccd13c49SDoug Rabson */ 294ccd13c49SDoug Rabson _rtld_free_tls(oldtls, 2*sizeof(Elf_Addr), sizeof(Elf_Addr)); 295ccd13c49SDoug Rabson } else { 296ccd13c49SDoug Rabson memcpy((void *)(segbase - tls_static_space), 297ccd13c49SDoug Rabson tls_init, tls_init_size); 298ccd13c49SDoug Rabson memset((void *)(segbase - tls_static_space + tls_init_size), 299ccd13c49SDoug Rabson 0, tls_static_space - tls_init_size); 300ccd13c49SDoug Rabson } 301ccd13c49SDoug Rabson 302ccd13c49SDoug Rabson return (void*) segbase; 303ccd13c49SDoug Rabson } 304ccd13c49SDoug Rabson 30526896bdaSDavid Xu #endif /* TLS_VARIANT_II */ 30626896bdaSDavid Xu 30726896bdaSDavid Xu #else 30826896bdaSDavid Xu 30926896bdaSDavid Xu void * 31026896bdaSDavid Xu __libc_allocate_tls(void *oldtls __unused, size_t tcbsize __unused, 31126896bdaSDavid Xu size_t tcbalign __unused) 31226896bdaSDavid Xu { 31326896bdaSDavid Xu return (0); 31426896bdaSDavid Xu } 31526896bdaSDavid Xu 31626896bdaSDavid Xu void 31726896bdaSDavid Xu __libc_free_tls(void *tcb __unused, size_t tcbsize __unused, 31826896bdaSDavid Xu size_t tcbalign __unused) 31926896bdaSDavid Xu { 32026896bdaSDavid Xu } 32126896bdaSDavid Xu 322294246bbSEd Maste #endif /* PIC */ 32326896bdaSDavid Xu 32426896bdaSDavid Xu extern char **environ; 325ccd13c49SDoug Rabson 326ccd13c49SDoug Rabson void 32755b6b759SCraig Rodrigues _init_tls(void) 328ccd13c49SDoug Rabson { 329294246bbSEd Maste #ifndef PIC 330ccd13c49SDoug Rabson Elf_Addr *sp; 331ccd13c49SDoug Rabson Elf_Auxinfo *aux, *auxp; 332ccd13c49SDoug Rabson Elf_Phdr *phdr; 333ccd13c49SDoug Rabson size_t phent, phnum; 334ccd13c49SDoug Rabson int i; 3350e7e4e5fSDoug Rabson void *tls; 336ccd13c49SDoug Rabson 337ccd13c49SDoug Rabson sp = (Elf_Addr *) environ; 338ccd13c49SDoug Rabson while (*sp++ != 0) 339ccd13c49SDoug Rabson ; 340ccd13c49SDoug Rabson aux = (Elf_Auxinfo *) sp; 341513004a2SPedro F. Giffuni phdr = NULL; 342ccd13c49SDoug Rabson phent = phnum = 0; 343ccd13c49SDoug Rabson for (auxp = aux; auxp->a_type != AT_NULL; auxp++) { 344ccd13c49SDoug Rabson switch (auxp->a_type) { 345ccd13c49SDoug Rabson case AT_PHDR: 346ccd13c49SDoug Rabson phdr = auxp->a_un.a_ptr; 347ccd13c49SDoug Rabson break; 348ccd13c49SDoug Rabson 349ccd13c49SDoug Rabson case AT_PHENT: 350ccd13c49SDoug Rabson phent = auxp->a_un.a_val; 351ccd13c49SDoug Rabson break; 352ccd13c49SDoug Rabson 353ccd13c49SDoug Rabson case AT_PHNUM: 354ccd13c49SDoug Rabson phnum = auxp->a_un.a_val; 355ccd13c49SDoug Rabson break; 356ccd13c49SDoug Rabson } 357ccd13c49SDoug Rabson } 358513004a2SPedro F. Giffuni if (phdr == NULL || phent != sizeof(Elf_Phdr) || phnum == 0) 359ccd13c49SDoug Rabson return; 360ccd13c49SDoug Rabson 36126896bdaSDavid Xu for (i = 0; (unsigned) i < phnum; i++) { 362ccd13c49SDoug Rabson if (phdr[i].p_type == PT_TLS) { 3636b2d5217SPedro F. Giffuni tls_static_space = roundup2(phdr[i].p_memsz, 364ccd13c49SDoug Rabson phdr[i].p_align); 365ccd13c49SDoug Rabson tls_init_size = phdr[i].p_filesz; 3668584ed54SMichal Meloun tls_init_align = phdr[i].p_align; 367ccd13c49SDoug Rabson tls_init = (void*) phdr[i].p_vaddr; 3688584ed54SMichal Meloun break; 369ccd13c49SDoug Rabson } 370ccd13c49SDoug Rabson } 371ccd13c49SDoug Rabson 3728584ed54SMichal Meloun tls = _rtld_allocate_tls(NULL, TLS_TCB_SIZE, 3738584ed54SMichal Meloun MAX(TLS_TCB_ALIGN, tls_init_align)); 374ccd13c49SDoug Rabson 375ccd13c49SDoug Rabson _set_tp(tls); 376ccd13c49SDoug Rabson #endif 3770e1c7d0fSDoug Rabson } 378