Changeset 6adb775f in mainline
- Timestamp:
- 2016-04-25T16:46:31Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 32573ff
- Parents:
- dc0d8b52
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/abi/elf.h
rdc0d8b52 r6adb775f 170 170 #define PT_SHLIB 5 171 171 #define PT_PHDR 6 172 #define PT_TLS 7 172 173 #define PT_LOPROC 0x70000000 173 174 #define PT_HIPROC 0x7fffffff -
kernel/generic/src/lib/elf.c
rdc0d8b52 r6adb775f 163 163 case PT_LOAD: 164 164 return load_segment(entry, elf, as); 165 case PT_TLS: 166 break; 165 167 case PT_DYNAMIC: 166 168 case PT_INTERP: -
uspace/lib/c/arch/ia32/_link.ld.in
rdc0d8b52 r6adb775f 12 12 #endif 13 13 data PT_LOAD FLAGS(6); 14 tls PT_TLS; 14 15 #if defined(SHLIB) || defined(DLEXE) 15 16 dynamic PT_DYNAMIC; … … 95 96 #endif 96 97 98 .tdata : { 97 99 #ifndef DLEXE 98 .tdata : {99 100 _tdata_start = .; 101 #endif 100 102 *(.tdata); 101 103 *(.gnu.linkonce.tb.*); 104 #ifndef DLEXE 102 105 _tdata_end = .; 106 #endif 107 } :data :tls 108 .tbss : { 109 #ifndef DLEXE 103 110 _tbss_start = .; 111 #endif 104 112 *(.tbss); 113 #ifndef DLEXE 105 114 _tbss_end = .; 106 } :data 115 #endif 116 } :data :tls 107 117 118 #ifndef DLEXE 108 119 _tls_alignment = ALIGNOF(.tdata); 109 120 #endif -
uspace/lib/c/arch/ia32/src/rtld/reloc.c
rdc0d8b52 r6adb775f 171 171 break; 172 172 173 // case R_386_TLS_DTPOFF32: 174 // *r_ptr = sym_def->st_value; 175 // break; 176 173 177 case R_386_TLS_DTPMOD32: 174 /* 175 * We can ignore this as long as the only module 176 * with TLS variables is libc.so. 177 */ 178 DPRINTF("Ignoring R_386_TLS_DTPMOD32\n"); 178 *r_ptr = dest->id; 179 179 break; 180 180 -
uspace/lib/c/arch/ia32/src/tls.c
rdc0d8b52 r6adb775f 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2016 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 39 40 #include <align.h> 40 41 42 #ifdef CONFIG_RTLD 43 #include <rtld/rtld.h> 44 #endif 45 41 46 tcb_t *tls_alloc_arch(void **data, size_t size) 42 47 { … … 68 73 69 74 /* Calculate size of TLS block */ 70 tls_size = ALIGN_UP(&_tbss_end - &_tdata_start, &_tls_alignment);75 tls_size = tls_get_size(); 71 76 72 77 /* The TLS block is just before TCB */ 73 78 tls = (uint8_t *)__tcb_get() - tls_size; 74 79 80 #ifdef CONFIG_RTLD 81 if (runtime_env != NULL) { 82 return rtld_tls_get_addr(runtime_env, tls, ti->ti_module, 83 ti->ti_offset); 84 } 85 #endif 75 86 return tls + ti->ti_offset; 76 87 } -
uspace/lib/c/generic/elf/elf_mod.c
rdc0d8b52 r6adb775f 248 248 } 249 249 250 /** Process TLS program header. 251 * 252 * @param elf Pointer to loader state buffer. 253 * @param hdr TLS program header 254 * @param info Place to store TLS info 255 */ 256 static void tls_program_header(elf_ld_t *elf, elf_segment_header_t *hdr, 257 elf_tls_info_t *info) 258 { 259 info->tdata = (void *)((uint8_t *)hdr->p_vaddr + elf->bias); 260 info->tdata_size = hdr->p_filesz; 261 info->tbss_size = hdr->p_memsz - hdr->p_filesz; 262 } 263 250 264 /** Process segment header. 251 265 * 266 * @param elf Pointer to loader state buffer. 252 267 * @param entry Segment header. 253 268 * … … 277 292 case 0x70000000: 278 293 /* FIXME: MIPS reginfo */ 294 break; 295 case PT_TLS: 296 /* Parse TLS program header */ 297 tls_program_header(elf, entry, &elf->info->tls); 298 DPRINTF("TLS header found at %p\n", 299 (void *)((uint8_t *)entry->p_vaddr + elf->bias)); 279 300 break; 280 301 case PT_SHLIB: -
uspace/lib/c/generic/rtld/module.c
rdc0d8b52 r6adb775f 37 37 #include <adt/list.h> 38 38 #include <elf/elf_load.h> 39 #include <errno.h> 39 40 #include <fcntl.h> 40 41 #include <loader/pcb.h> … … 129 130 int rc; 130 131 131 m = malloc(sizeof(module_t));132 if ( !m) {132 m = calloc(1, sizeof(module_t)); 133 if (m == NULL) { 133 134 printf("malloc failed\n"); 134 135 exit(1); … … 136 137 137 138 m->rtld = rtld; 139 m->id = rtld_get_next_id(rtld); 138 140 139 141 if (str_size(name) > NAME_BUF_SIZE - 2) { … … 174 176 /* Insert into the list of loaded modules */ 175 177 list_append(&m->modules_link, &rtld->modules); 178 179 /* Copy TLS info */ 180 m->tdata = info.tls.tdata; 181 m->tdata_size = info.tls.tdata_size; 182 m->tbss_size = info.tls.tbss_size; 183 184 printf("tdata at %p size %zu, tbss size %zu\n", 185 m->tdata, m->tdata_size, m->tbss_size); 176 186 177 187 return m; … … 236 246 } 237 247 248 /** Find module structure by ID. */ 249 module_t *module_by_id(rtld_t *rtld, unsigned long id) 250 { 251 list_foreach(rtld->modules, modules_link, module_t, m) { 252 if (m->id == id) 253 return m; 254 } 255 256 return NULL; 257 } 258 238 259 /** Process relocations in modules. 239 260 * … … 253 274 } 254 275 276 void modules_process_tls(rtld_t *rtld) 277 { 278 list_foreach(rtld->modules, modules_link, module_t, m) { 279 m->ioffs = rtld->tls_size; 280 rtld->tls_size += m->tdata_size + m->tbss_size; 281 } 282 } 283 255 284 /** Clear BFS tags of all modules. 256 285 */ -
uspace/lib/c/generic/rtld/rtld.c
rdc0d8b52 r6adb775f 43 43 rtld_t *runtime_env; 44 44 static rtld_t rt_env_static; 45 static module_t prog_mod;46 45 47 46 /** Initialize the runtime linker for use in a statically-linked executable. */ … … 62 61 { 63 62 rtld_t *env; 63 module_t *prog; 64 64 65 65 DPRINTF("Load dynamically linked program.\n"); … … 70 70 return ENOMEM; 71 71 72 env->next_id = 1; 73 74 prog = calloc(1, sizeof(module_t)); 75 if (prog == NULL) { 76 free(env); 77 return ENOMEM; 78 } 79 72 80 /* 73 81 * First we need to process dynamic sections of the executable … … 76 84 77 85 DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic); 78 dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn); 79 prog_mod.bias = 0; 80 prog_mod.dyn.soname = "[program]"; 81 prog_mod.rtld = env; 86 dynamic_parse(p_info->dynamic, 0, &prog->dyn); 87 prog->bias = 0; 88 prog->dyn.soname = "[program]"; 89 prog->rtld = env; 90 prog->id = rtld_get_next_id(env); 91 92 prog->tdata = p_info->tls.tdata; 93 prog->tdata_size = p_info->tls.tdata_size; 94 prog->tbss_size = p_info->tls.tbss_size; 95 96 printf("prog tdata at %p size %zu, tbss size %zu\n", 97 prog->tdata, prog->tdata_size, prog->tbss_size); 82 98 83 99 /* Initialize list of loaded modules */ 84 100 list_initialize(&env->modules); 85 list_append(&prog _mod.modules_link, &env->modules);101 list_append(&prog->modules_link, &env->modules); 86 102 87 103 /* Pointer to program module. Used as root of the module graph. */ 88 env->program = &prog_mod;104 env->program = prog; 89 105 90 106 /* Work around non-existent memory space allocation. */ … … 96 112 97 113 DPRINTF("Load all program dependencies\n"); 98 module_load_deps( &prog_mod);114 module_load_deps(prog); 99 115 100 116 /* … … 104 120 /* Process relocations in all modules */ 105 121 DPRINTF("Relocate all modules\n"); 106 modules_process_relocs(env, &prog_mod); 122 modules_process_relocs(env, prog); 123 124 modules_process_tls(env); 107 125 108 126 *rre = env; … … 110 128 } 111 129 130 /** Create TLS (Thread Local Storage) data structures. 131 * 132 * @return Pointer to TCB. 133 */ 134 tcb_t *rtld_tls_make(rtld_t *rtld) 135 { 136 void *data; 137 tcb_t *tcb; 138 size_t offset; 139 140 tcb = tls_alloc_arch(&data, rtld->tls_size); 141 if (tcb == NULL) 142 return NULL; 143 144 /* 145 * Copy thread local data from the modules' initialization images. 146 * Zero out thread-local uninitialized data. 147 */ 148 149 offset = 0; 150 list_foreach(rtld->modules, modules_link, module_t, m) { 151 memcpy(data + offset, m->tdata, m->tdata_size); 152 offset += m->tdata_size; 153 memset(data + offset, 0, m->tbss_size); 154 offset += m->tbss_size; 155 } 156 157 return tcb; 158 } 159 160 unsigned long rtld_get_next_id(rtld_t *rtld) 161 { 162 return rtld->next_id++; 163 } 164 165 void *rtld_tls_get_addr(rtld_t *rtld, void *tls, unsigned long mod_id, 166 unsigned long offset) 167 { 168 module_t *m; 169 170 m = module_by_id(rtld, mod_id); 171 assert(m != NULL); 172 173 return tls + m->ioffs + offset; 174 } 175 176 112 177 /** @} 113 178 */ -
uspace/lib/c/generic/tls.c
rdc0d8b52 r6adb775f 34 34 * Support for thread-local storage, as described in: 35 35 * Drepper U.: ELF Handling For Thread-Local Storage, 2005 36 * 37 * Only static model is supported. 38 */ 36 */ 39 37 40 38 #include <tls.h> 41 39 #include <malloc.h> 42 40 #include <str.h> 43 #include <align.h>44 41 #include <unistd.h> 45 42 43 #ifdef CONFIG_RTLD 44 #include <rtld/rtld.h> 45 #endif 46 47 size_t tls_get_size(void) 48 { 49 return &_tbss_end - &_tdata_start; 50 } 51 46 52 /** Create TLS (Thread Local Storage) data structures. 47 *48 * The code requires, that sections .tdata and .tbss are adjacent. It may be49 * changed in the future.50 53 * 51 54 * @return Pointer to TCB. … … 56 59 tcb_t *tcb; 57 60 size_t tls_size = &_tbss_end - &_tdata_start; 58 61 62 #ifdef CONFIG_RTLD 63 if (runtime_env != NULL) 64 return rtld_tls_make(runtime_env); 65 #endif 59 66 tcb = tls_alloc_arch(&data, tls_size); 60 67 if (!tcb) 61 68 return NULL; 62 69 63 70 /* 64 71 * Copy thread local data from the initialization image. … … 77 84 { 78 85 size_t tls_size = &_tbss_end - &_tdata_start; 86 87 #ifdef CONFIG_RTLD 88 if (runtime_env != NULL) 89 tls_size = runtime_env->tls_size; 90 #endif 79 91 tls_free_arch(tcb, tls_size); 80 92 } … … 121 133 { 122 134 tcb_t *tcb; 123 124 size = ALIGN_UP(size, &_tls_alignment); 125 *data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size); 126 if (!*data) 135 136 *data = malloc(sizeof(tcb_t) + size); 137 if (*data == NULL) 127 138 return NULL; 128 139 tcb = (tcb_t *) (*data + size); … … 139 150 void tls_free_variant_2(tcb_t *tcb, size_t size) 140 151 { 141 size = ALIGN_UP(size, &_tls_alignment);142 152 void *start = ((void *) tcb) - size; 143 153 free(start); -
uspace/lib/c/include/elf/elf_mod.h
rdc0d8b52 r6adb775f 58 58 } eld_flags_t; 59 59 60 /** TLS info for a module */ 61 typedef struct { 62 /** tdata section image */ 63 void *tdata; 64 /** Size of tdata section image in bytes */ 65 size_t tdata_size; 66 /** Size of tbss section */ 67 size_t tbss_size; 68 } elf_tls_info_t; 69 60 70 /** 61 71 * Some data extracted from the headers are stored here … … 70 80 /** Pointer to the dynamic section */ 71 81 void *dynamic; 82 83 /** TLS info */ 84 elf_tls_info_t tls; 72 85 } elf_finfo_t; 73 86 -
uspace/lib/c/include/rtld/module.h
rdc0d8b52 r6adb775f 46 46 extern module_t *module_load(rtld_t *, const char *); 47 47 extern void module_load_deps(module_t *); 48 extern module_t *module_by_id(rtld_t *, unsigned long); 48 49 49 50 extern void modules_process_relocs(rtld_t *, module_t *); 51 extern void modules_process_tls(rtld_t *); 50 52 extern void modules_untag(rtld_t *); 51 53 -
uspace/lib/c/include/rtld/rtld.h
rdc0d8b52 r6adb775f 41 41 42 42 #include <rtld/dynamic.h> 43 #include <tls.h> 43 44 #include <types/rtld/rtld.h> 44 45 … … 47 48 extern void rtld_init_static(void); 48 49 extern int rtld_prog_process(elf_finfo_t *, rtld_t **); 50 extern tcb_t *rtld_tls_make(rtld_t *); 51 extern unsigned long rtld_get_next_id(rtld_t *); 52 extern void *rtld_tls_get_addr(rtld_t *, void *, unsigned long, unsigned long); 49 53 50 54 #endif -
uspace/lib/c/include/tls.h
rdc0d8b52 r6adb775f 52 52 extern void tls_free(tcb_t *); 53 53 extern void tls_free_arch(tcb_t *, size_t); 54 extern size_t tls_get_size(void); 54 55 55 56 #ifdef CONFIG_TLS_VARIANT_1 -
uspace/lib/c/include/types/rtld/module.h
rdc0d8b52 r6adb775f 40 40 41 41 typedef struct module { 42 /** Module ID */ 43 unsigned long id; 44 /** Dynamic info for this module */ 42 45 dyn_info_t dyn; 46 /** Load bias */ 43 47 size_t bias; 48 49 /** tdata image start */ 50 void *tdata; 51 /** tdata image size */ 52 size_t tdata_size; 53 /** tbss size */ 54 size_t tbss_size; 55 56 size_t ioffs; 44 57 45 58 /** Containing rtld */ -
uspace/lib/c/include/types/rtld/rtld.h
rdc0d8b52 r6adb775f 48 48 module_t *program; 49 49 50 /** Next module ID */ 51 unsigned long next_id; 52 53 /** Size of initial TLS tdata + tbss */ 54 size_t tls_size; 55 50 56 /** List of all loaded modules including rtld and the program */ 51 57 list_t modules;
Note:
See TracChangeset
for help on using the changeset viewer.