Changeset 4f205248 in mainline
- Timestamp:
- 2018-04-23T18:50:40Z (7 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)
- Location:
- uspace/lib/c
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/arch/abs32le/src/tls.c
r8d58fca r4f205248 34 34 #include <stdint.h> 35 35 36 tcb_t *tls_alloc_arch( void **data, size_t size)36 tcb_t *tls_alloc_arch(size_t size, size_t align) 37 37 { 38 return tls_alloc_variant_2( data, size);38 return tls_alloc_variant_2(size, align); 39 39 } 40 40 41 void tls_free_arch(tcb_t *tcb, size_t size )41 void tls_free_arch(tcb_t *tcb, size_t size, size_t align) 42 42 { 43 tls_free_variant_2(tcb, size );43 tls_free_variant_2(tcb, size, align); 44 44 } 45 45 -
uspace/lib/c/arch/amd64/src/tls.c
r8d58fca r4f205248 38 38 #include <stddef.h> 39 39 40 tcb_t *tls_alloc_arch( void **data, size_t size)40 tcb_t *tls_alloc_arch(size_t size, size_t align) 41 41 { 42 return tls_alloc_variant_2( data, size);42 return tls_alloc_variant_2(size, align); 43 43 } 44 44 45 void tls_free_arch(tcb_t *tcb, size_t size )45 void tls_free_arch(tcb_t *tcb, size_t size, size_t align) 46 46 { 47 tls_free_variant_2(tcb, size );47 tls_free_variant_2(tcb, size, align); 48 48 } 49 49 -
uspace/lib/c/arch/arm32/src/tls.c
r8d58fca r4f205248 38 38 #include <stddef.h> 39 39 40 tcb_t *tls_alloc_arch( void **data, size_t size)40 tcb_t *tls_alloc_arch(size_t size, size_t align) 41 41 { 42 return tls_alloc_variant_1( data, size);42 return tls_alloc_variant_1(size, align); 43 43 } 44 44 45 void tls_free_arch(tcb_t *tcb, size_t size )45 void tls_free_arch(tcb_t *tcb, size_t size, size_t align) 46 46 { 47 tls_free_variant_1(tcb, size );47 tls_free_variant_1(tcb, size, align); 48 48 } 49 49 -
uspace/lib/c/arch/ia32/src/rtld/reloc.c
r8d58fca r4f205248 181 181 case R_386_TLS_TPOFF: 182 182 DPRINTF("fixup R_386_TLS_TPOFF\n"); 183 *r_ptr = (dest->ioffs + sym_def->st_value) - dest->rtld->tls_size;183 *r_ptr = sym_def->st_value + dest->tpoff; 184 184 break; 185 185 -
uspace/lib/c/arch/ia32/src/tls.c
r8d58fca r4f205248 45 45 #endif 46 46 47 tcb_t *tls_alloc_arch( void **data, size_t size)47 tcb_t *tls_alloc_arch(size_t size, size_t align) 48 48 { 49 return tls_alloc_variant_2( data, size);49 return tls_alloc_variant_2(size, align); 50 50 } 51 51 52 void tls_free_arch(tcb_t *tcb, size_t size )52 void tls_free_arch(tcb_t *tcb, size_t size, size_t align) 53 53 { 54 tls_free_variant_2(tcb, size );54 tls_free_variant_2(tcb, size, align); 55 55 } 56 56 -
uspace/lib/c/arch/ia64/src/tls.c
r8d58fca r4f205248 37 37 #include <tls.h> 38 38 39 tcb_t *tls_alloc_arch( void **data, size_t size)39 tcb_t *tls_alloc_arch(size_t size, size_t align) 40 40 { 41 return tls_alloc_variant_1( data, size);41 return tls_alloc_variant_1(size, align); 42 42 } 43 43 44 void tls_free_arch(tcb_t *tcb, size_t size )44 void tls_free_arch(tcb_t *tcb, size_t size, size_t align) 45 45 { 46 tls_free_variant_1(tcb, size );46 tls_free_variant_1(tcb, size, align); 47 47 } 48 48 -
uspace/lib/c/arch/mips32/src/tls.c
r8d58fca r4f205248 37 37 #include <stddef.h> 38 38 39 tcb_t *tls_alloc_arch( void **data, size_t size)39 tcb_t *tls_alloc_arch(size_t size, size_t align) 40 40 { 41 return tls_alloc_variant_1( data, size);41 return tls_alloc_variant_1(size, align); 42 42 } 43 43 44 void tls_free_arch(tcb_t *tcb, size_t size )44 void tls_free_arch(tcb_t *tcb, size_t size, size_t align) 45 45 { 46 tls_free_variant_1(tcb, size );46 tls_free_variant_1(tcb, size, align); 47 47 } 48 48 -
uspace/lib/c/arch/ppc32/src/tls.c
r8d58fca r4f205248 36 36 #include <stddef.h> 37 37 38 tcb_t *tls_alloc_arch( void **data, size_t size)38 tcb_t *tls_alloc_arch(size_t size, size_t align) 39 39 { 40 return tls_alloc_variant_1( data, size);40 return tls_alloc_variant_1(size, align); 41 41 } 42 42 43 void tls_free_arch(tcb_t *tcb, size_t size )43 void tls_free_arch(tcb_t *tcb, size_t size, size_t align) 44 44 { 45 tls_free_variant_1(tcb, size );45 tls_free_variant_1(tcb, size, align); 46 46 } 47 47 -
uspace/lib/c/arch/riscv64/src/tls.c
r8d58fca r4f205248 33 33 #include <stddef.h> 34 34 35 tcb_t *tls_alloc_arch( void **data, size_t size)35 tcb_t *tls_alloc_arch(size_t size, size_t align) 36 36 { 37 return tls_alloc_variant_2( data, size);37 return tls_alloc_variant_2(size, align); 38 38 } 39 39 40 void tls_free_arch(tcb_t *tcb, size_t size )40 void tls_free_arch(tcb_t *tcb, size_t size, size_t align) 41 41 { 42 tls_free_variant_2(tcb, size );42 tls_free_variant_2(tcb, size, align); 43 43 } 44 44 -
uspace/lib/c/arch/sparc64/src/tls.c
r8d58fca r4f205248 38 38 #include <stddef.h> 39 39 40 tcb_t *tls_alloc_arch( void **data, size_t size)40 tcb_t *tls_alloc_arch(size_t size, size_t align) 41 41 { 42 return tls_alloc_variant_2( data, size);42 return tls_alloc_variant_2(size, align); 43 43 } 44 44 45 void tls_free_arch(tcb_t *tcb, size_t size )45 void tls_free_arch(tcb_t *tcb, size_t size, size_t align) 46 46 { 47 tls_free_variant_2(tcb, size );47 tls_free_variant_2(tcb, size, align); 48 48 } 49 49 -
uspace/lib/c/generic/rtld/module.c
r8d58fca r4f205248 35 35 */ 36 36 37 #include <align.h> 37 38 #include <adt/list.h> 38 39 #include <elf/elf_load.h> … … 42 43 #include <stdlib.h> 43 44 #include <str.h> 45 #include <macros.h> 44 46 45 47 #include <rtld/rtld.h> … … 72 74 const elf_segment_header_t *tls = 73 75 elf_get_phdr(__executable_start, PT_TLS); 74 uintptr_t bias = elf_get_bias(__executable_start); 75 76 module->tdata = (void *) (tls->p_vaddr + bias); 77 module->tdata_size = tls->p_filesz; 78 module->tbss_size = tls->p_memsz - tls->p_filesz; 79 module->tls_align = tls->p_align; 76 77 if (tls) { 78 uintptr_t bias = elf_get_bias(__executable_start); 79 module->tdata = (void *) (tls->p_vaddr + bias); 80 module->tdata_size = tls->p_filesz; 81 module->tbss_size = tls->p_memsz - tls->p_filesz; 82 module->tls_align = tls->p_align; 83 } else { 84 module->tdata = NULL; 85 module->tdata_size = 0; 86 module->tbss_size = 0; 87 module->tls_align = 1; 88 } 80 89 81 90 list_append(&module->modules_link, &rtld->modules); … … 324 333 { 325 334 #ifdef CONFIG_TLS_VARIANT_1 326 list_foreach(rtld->modules, modules_link, module_t, m) { 327 m->ioffs = rtld->tls_size; 328 list_append(&m->imodules_link, &rtmd->imodules); 335 rtld->tls_size = sizeof(tcb_t); 336 rtld->tls_align = _Alignof(tcb_t); 337 338 list_foreach(rtld->modules, modules_link, module_t, m) { 339 list_append(&m->imodules_link, &rtld->imodules); 340 rtld->tls_align = max(rtld->tls_align, m->tls_align); 341 342 rtld->tls_size = ALIGN_UP(rtld->tls_size, m->tls_align); 343 m->tpoff = rtld->tls_size; 329 344 rtld->tls_size += m->tdata_size + m->tbss_size; 330 345 } 331 #else /* CONFIG_TLS_VARIANT_2 */ 332 size_t offs; 333 334 list_foreach(rtld->modules, modules_link, module_t, m) { 346 347 #else 348 rtld->tls_size = 0; 349 rtld->tls_align = _Alignof(tcb_t); 350 351 list_foreach(rtld->modules, modules_link, module_t, m) { 352 list_append(&m->imodules_link, &rtld->imodules); 353 rtld->tls_align = max(rtld->tls_align, m->tls_align); 354 355 /* We are allocating spans "backwards", here, 356 * as described in U. Drepper's paper. 357 */ 335 358 rtld->tls_size += m->tdata_size + m->tbss_size; 336 } 337 338 offs = 0; 339 list_foreach(rtld->modules, modules_link, module_t, m) { 340 offs += m->tdata_size + m->tbss_size; 341 m->ioffs = rtld->tls_size - offs; 342 list_append(&m->imodules_link, &rtld->imodules); 343 } 359 rtld->tls_size = ALIGN_UP(rtld->tls_size, m->tls_align); 360 m->tpoff = -(ptrdiff_t) rtld->tls_size; 361 } 362 363 /* We are in negative offsets. In order for the alignments to 364 * be correct, "zero" offset (i.e. the total size) must be aligned 365 * to the strictest alignment present. 366 */ 367 rtld->tls_size = ALIGN_UP(rtld->tls_size, rtld->tls_align); 368 369 /* Space for the TCB. */ 370 rtld->tls_size += sizeof(tcb_t); 344 371 #endif 345 372 } -
uspace/lib/c/generic/rtld/rtld.c
r8d58fca r4f205248 152 152 tcb_t *rtld_tls_make(rtld_t *rtld) 153 153 { 154 void *data;155 154 tcb_t *tcb; 156 size_t offset;157 155 void **dtv; 158 156 size_t nmods; 159 157 size_t i; 160 158 161 tcb = tls_alloc_arch( &data, rtld->tls_size);159 tcb = tls_alloc_arch(rtld->tls_size, rtld->tls_align); 162 160 if (tcb == NULL) 163 161 return NULL; … … 182 180 */ 183 181 184 #ifdef CONFIG_TLS_VARIANT_1185 /*186 * Ascending addresses187 */188 offset = 0;189 182 i = 1; 190 183 list_foreach(rtld->imodules, imodules_link, module_t, m) { 191 assert(i == m->id); 192 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size); 193 dtv[i++] = data + offset; 194 memcpy(data + offset, m->tdata, m->tdata_size); 195 offset += m->tdata_size; 196 memset(data + offset, 0, m->tbss_size); 197 offset += m->tbss_size; 198 } 199 #else /* CONFIG_TLS_VARIANT_2 */ 200 /* 201 * Descending addresses 202 */ 203 offset = 0; 204 i = 1; 205 list_foreach(rtld->imodules, imodules_link, module_t, m) { 206 assert(i == m->id); 207 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size); 208 offset += m->tbss_size; 209 memset(data + rtld->tls_size - offset, 0, m->tbss_size); 210 offset += m->tdata_size; 211 memcpy(data + rtld->tls_size - offset, m->tdata, m->tdata_size); 212 dtv[i++] = data + rtld->tls_size - offset; 213 } 214 #endif 184 assert(i++ == m->id); 185 186 dtv[m->id] = (void *) tcb + m->tpoff; 187 188 assert(((uintptr_t) dtv[m->id]) % m->tls_align == 0); 189 190 memcpy(dtv[m->id], m->tdata, m->tdata_size); 191 memset(dtv[m->id] + m->tdata_size, 0, m->tbss_size); 192 } 215 193 216 194 tcb->dtv = dtv; … … 259 237 assert(!link_used(&m->imodules_link)); 260 238 261 tls_block = m alloc(m->tdata_size + m->tbss_size);239 tls_block = memalign(m->tls_align, m->tdata_size + m->tbss_size); 262 240 /* XXX This can fail if OOM */ 263 241 assert(tls_block != NULL); -
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 -
uspace/lib/c/include/tls.h
r8d58fca r4f205248 44 44 45 45 extern tcb_t *tls_make(void); 46 extern tcb_t *tls_alloc_arch( void **, size_t);46 extern tcb_t *tls_alloc_arch(size_t, size_t); 47 47 extern void tls_free(tcb_t *); 48 extern void tls_free_arch(tcb_t *, size_t); 49 extern size_t tls_get_size(void); 48 extern void tls_free_arch(tcb_t *, size_t, size_t); 50 49 extern void *tls_get(void); 51 50 52 51 #ifdef CONFIG_TLS_VARIANT_1 53 extern tcb_t *tls_alloc_variant_1( void **, size_t);54 extern void tls_free_variant_1(tcb_t *, size_t );52 extern tcb_t *tls_alloc_variant_1(size_t, size_t); 53 extern void tls_free_variant_1(tcb_t *, size_t, size_t); 55 54 #endif 56 55 57 56 #ifdef CONFIG_TLS_VARIANT_2 58 extern tcb_t *tls_alloc_variant_2( void **, size_t);59 extern void tls_free_variant_2(tcb_t *, size_t );57 extern tcb_t *tls_alloc_variant_2(size_t, size_t); 58 extern void tls_free_variant_2(tcb_t *, size_t, size_t); 60 59 #endif 61 60 -
uspace/lib/c/include/types/rtld/module.h
r8d58fca r4f205248 62 62 size_t tls_align; 63 63 64 size_t ioffs; 64 /** Offset of this module's TLS from the thread pointer. */ 65 ptrdiff_t tpoff; 65 66 66 67 /** Containing rtld */ -
uspace/lib/c/include/types/rtld/rtld.h
r8d58fca r4f205248 54 54 /** Size of initial TLS tdata + tbss */ 55 55 size_t tls_size; 56 size_t tls_align; 56 57 57 58 /** List of all loaded modules including rtld and the program */
Note:
See TracChangeset
for help on using the changeset viewer.