source: mainline/uspace/lib/c/generic/tls.c@ 2c4e1cc

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2c4e1cc was 2c4e1cc, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

Define TLS consistently in linker scripts, and remove nonstandard symbols.

Read the program header to find TLS instead.

  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[fa23560]1/*
2 * Copyright (c) 2006 Jakub Jermar
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 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/** @file
33 *
34 * Support for thread-local storage, as described in:
35 * Drepper U.: ELF Handling For Thread-Local Storage, 2005
[6adb775f]36 */
[fa23560]37
[582a0b8]38#include <stddef.h>
[118a872]39#include <align.h>
[fa23560]40#include <tls.h>
[38d150e]41#include <stdlib.h>
[19f857a]42#include <str.h>
[2c4e1cc]43#include <elf/elf.h>
[fa23560]44
[6adb775f]45#ifdef CONFIG_RTLD
46#include <rtld/rtld.h>
47#endif
48
49size_t tls_get_size(void)
50{
[91e4567]51#ifdef CONFIG_RTLD
52 if (runtime_env != NULL)
53 return runtime_env->tls_size;
54#endif
[2c4e1cc]55
56 const elf_segment_header_t *tls =
57 elf_get_phdr(__executable_start, PT_TLS);
58 return tls->p_memsz;
[6adb775f]59}
60
[e2f26002]61/** Get address of static TLS block */
62void *tls_get(void)
63{
64#ifdef CONFIG_TLS_VARIANT_1
65 return (uint8_t *)__tcb_get() + sizeof(tcb_t);
66#else /* CONFIG_TLS_VARIANT_2 */
67 return (uint8_t *)__tcb_get() - tls_get_size();
68#endif
69}
70
[fa23560]71/** Create TLS (Thread Local Storage) data structures.
72 *
73 * @return Pointer to TCB.
74 */
[31399f3]75tcb_t *tls_make(void)
[fa23560]76{
77 void *data;
78 tcb_t *tcb;
[a35b458]79
[6adb775f]80#ifdef CONFIG_RTLD
81 if (runtime_env != NULL)
82 return rtld_tls_make(runtime_env);
83#endif
[a35b458]84
[2c4e1cc]85 const elf_segment_header_t *tls =
86 elf_get_phdr(__executable_start, PT_TLS);
87 if (tls == NULL)
[0d57c3e]88 return NULL;
[a35b458]89
[2c4e1cc]90 uintptr_t bias = elf_get_bias(__executable_start);
91
92 tcb = tls_alloc_arch(&data, tls->p_memsz);
93
[fa23560]94 /*
95 * Copy thread local data from the initialization image.
96 */
[2c4e1cc]97 memcpy(data, (void *)(tls->p_vaddr + bias), tls->p_filesz);
[fa23560]98 /*
99 * Zero out the thread local uninitialized data.
100 */
[2c4e1cc]101 memset(data + tls->p_filesz, 0, tls->p_memsz - tls->p_filesz);
[fa23560]102
103 return tcb;
104}
105
[31399f3]106void tls_free(tcb_t *tcb)
[fa23560]107{
[3a9414e]108#ifdef CONFIG_RTLD
[d2bb25e7]109 free(tcb->dtv);
[3a9414e]110#endif
[91e4567]111 tls_free_arch(tcb, tls_get_size());
[fa23560]112}
113
114#ifdef CONFIG_TLS_VARIANT_1
115/** Allocate TLS variant 1 data structures.
116 *
117 * @param data Start of TLS section. This is an output argument.
118 * @param size Size of tdata + tbss section.
119 * @return Pointer to tcb_t structure.
120 */
121tcb_t *tls_alloc_variant_1(void **data, size_t size)
122{
[d2bb25e7]123 tcb_t *tcb;
[fa23560]124
[d2bb25e7]125 tcb = malloc(sizeof(tcb_t) + size);
126 if (!tcb)
[0d57c3e]127 return NULL;
[a35b458]128
[58563585]129 *data = ((void *) tcb) + sizeof(tcb_t);
[3a9414e]130#ifdef CONFIG_RTLD
[d2bb25e7]131 tcb->dtv = NULL;
[3a9414e]132#endif
[0d57c3e]133
[d2bb25e7]134 return tcb;
[fa23560]135}
136
137/** Free TLS variant I data structures.
138 *
139 * @param tcb Pointer to TCB structure.
140 * @param size This argument is ignored.
141 */
142void tls_free_variant_1(tcb_t *tcb, size_t size)
143{
144 free(tcb);
145}
146#endif
147
148#ifdef CONFIG_TLS_VARIANT_2
149/** Allocate TLS variant II data structures.
150 *
151 * @param data Pointer to pointer to thread local data. This is
152 * actually an output argument.
153 * @param size Size of thread local data.
154 * @return Pointer to TCB structure.
155 */
156tcb_t * tls_alloc_variant_2(void **data, size_t size)
157{
158 tcb_t *tcb;
[a35b458]159
[2c4e1cc]160 uintptr_t align = elf_get_phdr(__executable_start, PT_TLS)->p_align;
161
162 size = ALIGN_UP(size, align);
163 *data = memalign(align, sizeof(tcb_t) + size);
[6adb775f]164 if (*data == NULL)
[0d57c3e]165 return NULL;
[fa23560]166 tcb = (tcb_t *) (*data + size);
167 tcb->self = tcb;
[3a9414e]168#ifdef CONFIG_RTLD
[d2bb25e7]169 tcb->dtv = NULL;
[3a9414e]170#endif
[fa23560]171
172 return tcb;
173}
174
175/** Free TLS variant II data structures.
176 *
177 * @param tcb Pointer to TCB structure.
178 * @param size Size of thread local data.
179 */
180void tls_free_variant_2(tcb_t *tcb, size_t size)
181{
[2c4e1cc]182 uintptr_t align = elf_get_phdr(__executable_start, PT_TLS)->p_align;
183 size = ALIGN_UP(size, align);
[fa23560]184 void *start = ((void *) tcb) - size;
185 free(start);
186}
187#endif
188
189/** @}
190 */
Note: See TracBrowser for help on using the repository browser.