Changeset 4f205248 in mainline for uspace/lib/c/generic/tls.c
- Timestamp:
- 2018-04-23T18:50:40Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a2eb85d
- Parents:
- 8d58fca
- git-author:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-04-23 17:47:09)
- git-committer:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-04-23 18:50:40)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/tls.c
r8d58fca r4f205248 36 36 */ 37 37 38 #include <assert.h> 38 39 #include <stddef.h> 39 40 #include <align.h> … … 41 42 #include <stdlib.h> 42 43 #include <str.h> 44 #include <macros.h> 43 45 #include <elf/elf.h> 44 46 … … 47 49 #endif 48 50 49 size_t tls_get_size(void) 50 { 51 #ifdef CONFIG_RTLD 52 if (runtime_env != NULL) 53 return runtime_env->tls_size; 51 #if !defined(CONFIG_TLS_VARIANT_1) && !defined(CONFIG_TLS_VARIANT_2) 52 #error Unknown TLS variant. 53 #endif 54 55 /** Get address of static TLS block */ 56 void *tls_get(void) 57 { 58 #ifdef CONFIG_RTLD 59 assert(runtime_env == NULL); 54 60 #endif 55 61 56 62 const elf_segment_header_t *tls = 57 63 elf_get_phdr(__executable_start, PT_TLS); 58 return tls->p_memsz; 59 } 60 61 /** Get address of static TLS block */ 62 void *tls_get(void) 63 { 64 65 if (tls == NULL) 66 return NULL; 67 64 68 #ifdef CONFIG_TLS_VARIANT_1 65 return (uint8_t *)__tcb_get() + sizeof(tcb_t);69 return (uint8_t *)__tcb_get() + ALIGN_UP(sizeof(tcb_t), tls->p_align); 66 70 #else /* CONFIG_TLS_VARIANT_2 */ 67 return (uint8_t *)__tcb_get() - tls_get_size();71 return (uint8_t *)__tcb_get() - ALIGN_UP(tls->p_memsz, tls->p_align); 68 72 #endif 69 73 } … … 89 93 90 94 uintptr_t bias = elf_get_bias(__executable_start); 91 92 tcb = tls_alloc_arch(&data, tls->p_memsz); 95 size_t align = max(tls->p_align, _Alignof(tcb_t)); 96 97 #ifdef CONFIG_TLS_VARIANT_1 98 tcb = tls_alloc_arch( 99 ALIGN_UP(sizeof(tcb_t), align) + tls->p_memsz, align); 100 data = (void *) tcb + ALIGN_UP(sizeof(tcb_t), align); 101 #else 102 tcb = tls_alloc_arch( 103 ALIGN_UP(tls->p_memsz, align) + sizeof(tcb_t), align); 104 data = (void *) tcb - ALIGN_UP(tls->p_memsz, tls->p_align); 105 #endif 93 106 94 107 /* … … 108 121 #ifdef CONFIG_RTLD 109 122 free(tcb->dtv); 110 #endif 111 tls_free_arch(tcb, tls_get_size()); 123 124 if (runtime_env != NULL) { 125 tls_free_arch(tcb, runtime_env->tls_size, runtime_env->tls_align); 126 return; 127 } 128 #endif 129 const elf_segment_header_t *tls = 130 elf_get_phdr(__executable_start, PT_TLS); 131 132 assert(tls != NULL); 133 tls_free_arch(tcb, 134 ALIGN_UP(tls->p_memsz, tls->p_align) + sizeof(tcb_t), 135 max(tls->p_align, _Alignof(tcb_t))); 112 136 } 113 137 … … 119 143 * @return Pointer to tcb_t structure. 120 144 */ 121 tcb_t *tls_alloc_variant_1(void **data, size_t size) 122 { 123 tcb_t *tcb; 124 125 tcb = malloc(sizeof(tcb_t) + size); 145 tcb_t *tls_alloc_variant_1(size_t size, size_t align) 146 { 147 tcb_t *tcb = memalign(align, size); 126 148 if (!tcb) 127 149 return NULL; 128 129 *data = ((void *) tcb) + sizeof(tcb_t); 130 #ifdef CONFIG_RTLD 131 tcb->dtv = NULL; 132 #endif 133 150 memset(tcb, 0, sizeof(tcb_t)); 134 151 return tcb; 135 152 } … … 140 157 * @param size This argument is ignored. 141 158 */ 142 void tls_free_variant_1(tcb_t *tcb, size_t size )159 void tls_free_variant_1(tcb_t *tcb, size_t size, size_t align) 143 160 { 144 161 free(tcb); … … 152 169 * actually an output argument. 153 170 * @param size Size of thread local data. 171 * @param align Alignment of thread local data. 154 172 * @return Pointer to TCB structure. 155 173 */ 156 tcb_t *tls_alloc_variant_2(void **data, size_t size) 157 { 158 tcb_t *tcb; 159 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); 164 if (*data == NULL) 165 return NULL; 166 tcb = (tcb_t *) (*data + size); 174 tcb_t *tls_alloc_variant_2(size_t size, size_t align) 175 { 176 void *data = memalign(align, size); 177 if (data == NULL) 178 return NULL; 179 180 tcb_t *tcb = (tcb_t *) (data + size - sizeof(tcb_t)); 181 memset(tcb, 0, sizeof(tcb_t)); 167 182 tcb->self = tcb; 168 #ifdef CONFIG_RTLD169 tcb->dtv = NULL;170 #endif171 172 183 return tcb; 173 184 } … … 177 188 * @param tcb Pointer to TCB structure. 178 189 * @param size Size of thread local data. 179 */ 180 void tls_free_variant_2(tcb_t *tcb, size_t size) 181 { 182 uintptr_t align = elf_get_phdr(__executable_start, PT_TLS)->p_align; 183 size = ALIGN_UP(size, align); 184 void *start = ((void *) tcb) - size; 185 free(start); 190 * @param align Alignment of thread local data. 191 */ 192 void tls_free_variant_2(tcb_t *tcb, size_t size, size_t align) 193 { 194 if (tcb != NULL) { 195 void *start = ((void *) tcb) + sizeof(tcb_t) - size; 196 free(start); 197 } 186 198 } 187 199 #endif
Note:
See TracChangeset
for help on using the changeset viewer.