Changes in / [32573ff:5035ba05] in mainline
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/abi/elf.h
r32573ff r5035ba05 170 170 #define PT_SHLIB 5 171 171 #define PT_PHDR 6 172 #define PT_TLS 7173 172 #define PT_LOPROC 0x70000000 174 173 #define PT_HIPROC 0x7fffffff -
kernel/generic/src/lib/elf.c
r32573ff r5035ba05 163 163 case PT_LOAD: 164 164 return load_segment(entry, elf, as); 165 case PT_TLS:166 break;167 165 case PT_DYNAMIC: 168 166 case PT_INTERP: -
uspace/lib/c/arch/ia32/_link.ld.in
r32573ff r5035ba05 12 12 #endif 13 13 data PT_LOAD FLAGS(6); 14 tls PT_TLS;15 14 #if defined(SHLIB) || defined(DLEXE) 16 15 dynamic PT_DYNAMIC; … … 96 95 #endif 97 96 97 #ifndef DLEXE 98 98 .tdata : { 99 #ifndef DLEXE100 99 _tdata_start = .; 101 #endif102 100 *(.tdata); 103 101 *(.gnu.linkonce.tb.*); 104 #ifndef DLEXE105 102 _tdata_end = .; 106 #endif107 } :data :tls108 .tbss : {109 #ifndef DLEXE110 103 _tbss_start = .; 111 #endif112 104 *(.tbss); 113 #ifndef DLEXE114 105 _tbss_end = .; 115 #endif 116 } :data :tls 106 } :data 117 107 118 #ifndef DLEXE119 108 _tls_alignment = ALIGNOF(.tdata); 120 109 #endif -
uspace/lib/c/arch/ia32/src/rtld/reloc.c
r32573ff r5035ba05 171 171 break; 172 172 173 // case R_386_TLS_DTPOFF32:174 // *r_ptr = sym_def->st_value;175 // break;176 177 173 case R_386_TLS_DTPMOD32: 178 *r_ptr = dest->id; 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"); 179 179 break; 180 180 -
uspace/lib/c/arch/ia32/src/tls.c
r32573ff r5035ba05 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2016 Jiri Svoboda4 3 * All rights reserved. 5 4 * … … 40 39 #include <align.h> 41 40 42 #ifdef CONFIG_RTLD43 #include <rtld/rtld.h>44 #endif45 46 41 tcb_t *tls_alloc_arch(void **data, size_t size) 47 42 { … … 73 68 74 69 /* Calculate size of TLS block */ 75 tls_size = tls_get_size();70 tls_size = ALIGN_UP(&_tbss_end - &_tdata_start, &_tls_alignment); 76 71 77 72 /* The TLS block is just before TCB */ 78 73 tls = (uint8_t *)__tcb_get() - tls_size; 79 74 80 #ifdef CONFIG_RTLD81 if (runtime_env != NULL) {82 return rtld_tls_get_addr(runtime_env, tls, ti->ti_module,83 ti->ti_offset);84 }85 #endif86 75 return tls + ti->ti_offset; 87 76 } -
uspace/lib/c/generic/elf/elf_mod.c
r32573ff r5035ba05 248 248 } 249 249 250 /** Process TLS program header.251 *252 * @param elf Pointer to loader state buffer.253 * @param hdr TLS program header254 * @param info Place to store TLS info255 */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 264 250 /** Process segment header. 265 251 * 266 * @param elf Pointer to loader state buffer.267 252 * @param entry Segment header. 268 253 * … … 292 277 case 0x70000000: 293 278 /* 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));300 279 break; 301 280 case PT_SHLIB: -
uspace/lib/c/generic/rtld/module.c
r32573ff r5035ba05 37 37 #include <adt/list.h> 38 38 #include <elf/elf_load.h> 39 #include <errno.h>40 39 #include <fcntl.h> 41 40 #include <loader/pcb.h> … … 136 135 137 136 m = calloc(1, sizeof(module_t)); 138 if ( m == NULL) {137 if (!m) { 139 138 printf("malloc failed\n"); 140 139 exit(1); … … 142 141 143 142 m->rtld = rtld; 144 m->id = rtld_get_next_id(rtld);145 146 143 if ((flags & mlf_local) != 0) 147 144 m->local = true; … … 184 181 /* Insert into the list of loaded modules */ 185 182 list_append(&m->modules_link, &rtld->modules); 186 187 /* Copy TLS info */188 m->tdata = info.tls.tdata;189 m->tdata_size = info.tls.tdata_size;190 m->tbss_size = info.tls.tbss_size;191 192 printf("tdata at %p size %zu, tbss size %zu\n",193 m->tdata, m->tdata_size, m->tbss_size);194 183 195 184 return m; … … 254 243 } 255 244 256 /** Find module structure by ID. */257 module_t *module_by_id(rtld_t *rtld, unsigned long id)258 {259 list_foreach(rtld->modules, modules_link, module_t, m) {260 if (m->id == id)261 return m;262 }263 264 return NULL;265 }266 267 245 /** Process relocations in modules. 268 246 * … … 282 260 } 283 261 284 void modules_process_tls(rtld_t *rtld)285 {286 list_foreach(rtld->modules, modules_link, module_t, m) {287 m->ioffs = rtld->tls_size;288 rtld->tls_size += m->tdata_size + m->tbss_size;289 }290 }291 292 262 /** Clear BFS tags of all modules. 293 263 */ -
uspace/lib/c/generic/rtld/rtld.c
r32573ff r5035ba05 43 43 rtld_t *runtime_env; 44 44 static rtld_t rt_env_static; 45 static module_t prog_mod; 45 46 46 47 /** Initialize the runtime linker for use in a statically-linked executable. */ … … 61 62 { 62 63 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 80 72 /* 81 73 * First we need to process dynamic sections of the executable … … 84 76 85 77 DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic); 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 prog->exec = true; 92 prog->local = false; 93 94 prog->tdata = p_info->tls.tdata; 95 prog->tdata_size = p_info->tls.tdata_size; 96 prog->tbss_size = p_info->tls.tbss_size; 97 98 printf("prog tdata at %p size %zu, tbss size %zu\n", 99 prog->tdata, prog->tdata_size, prog->tbss_size); 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; 82 prog_mod.exec = true; 83 prog_mod.local = false; 100 84 101 85 /* Initialize list of loaded modules */ 102 86 list_initialize(&env->modules); 103 list_append(&prog ->modules_link, &env->modules);87 list_append(&prog_mod.modules_link, &env->modules); 104 88 105 89 /* Pointer to program module. Used as root of the module graph. */ 106 env->program = prog;90 env->program = &prog_mod; 107 91 108 92 /* Work around non-existent memory space allocation. */ … … 114 98 115 99 DPRINTF("Load all program dependencies\n"); 116 module_load_deps( prog, 0);100 module_load_deps(&prog_mod, 0); 117 101 118 102 /* … … 122 106 /* Process relocations in all modules */ 123 107 DPRINTF("Relocate all modules\n"); 124 modules_process_relocs(env, prog); 125 126 modules_process_tls(env); 108 modules_process_relocs(env, &prog_mod); 127 109 128 110 *rre = env; … … 130 112 } 131 113 132 /** Create TLS (Thread Local Storage) data structures.133 *134 * @return Pointer to TCB.135 */136 tcb_t *rtld_tls_make(rtld_t *rtld)137 {138 void *data;139 tcb_t *tcb;140 size_t offset;141 142 tcb = tls_alloc_arch(&data, rtld->tls_size);143 if (tcb == NULL)144 return NULL;145 146 /*147 * Copy thread local data from the modules' initialization images.148 * Zero out thread-local uninitialized data.149 */150 151 offset = 0;152 list_foreach(rtld->modules, modules_link, module_t, m) {153 memcpy(data + offset, m->tdata, m->tdata_size);154 offset += m->tdata_size;155 memset(data + offset, 0, m->tbss_size);156 offset += m->tbss_size;157 }158 159 return tcb;160 }161 162 unsigned long rtld_get_next_id(rtld_t *rtld)163 {164 return rtld->next_id++;165 }166 167 void *rtld_tls_get_addr(rtld_t *rtld, void *tls, unsigned long mod_id,168 unsigned long offset)169 {170 module_t *m;171 172 m = module_by_id(rtld, mod_id);173 assert(m != NULL);174 175 return tls + m->ioffs + offset;176 }177 178 179 114 /** @} 180 115 */ -
uspace/lib/c/generic/tls.c
r32573ff r5035ba05 34 34 * Support for thread-local storage, as described in: 35 35 * Drepper U.: ELF Handling For Thread-Local Storage, 2005 36 */ 36 * 37 * Only static model is supported. 38 */ 37 39 38 40 #include <tls.h> 39 41 #include <malloc.h> 40 42 #include <str.h> 43 #include <align.h> 41 44 #include <unistd.h> 42 45 43 #ifdef CONFIG_RTLD44 #include <rtld/rtld.h>45 #endif46 47 size_t tls_get_size(void)48 {49 return &_tbss_end - &_tdata_start;50 }51 52 46 /** Create TLS (Thread Local Storage) data structures. 47 * 48 * The code requires, that sections .tdata and .tbss are adjacent. It may be 49 * changed in the future. 53 50 * 54 51 * @return Pointer to TCB. … … 59 56 tcb_t *tcb; 60 57 size_t tls_size = &_tbss_end - &_tdata_start; 61 62 #ifdef CONFIG_RTLD 63 if (runtime_env != NULL) 64 return rtld_tls_make(runtime_env); 65 #endif 58 66 59 tcb = tls_alloc_arch(&data, tls_size); 67 60 if (!tcb) 68 61 return NULL; 69 62 70 63 /* 71 64 * Copy thread local data from the initialization image. … … 84 77 { 85 78 size_t tls_size = &_tbss_end - &_tdata_start; 86 87 #ifdef CONFIG_RTLD88 if (runtime_env != NULL)89 tls_size = runtime_env->tls_size;90 #endif91 79 tls_free_arch(tcb, tls_size); 92 80 } … … 133 121 { 134 122 tcb_t *tcb; 135 136 *data = malloc(sizeof(tcb_t) + size); 137 if (*data == NULL) 123 124 size = ALIGN_UP(size, &_tls_alignment); 125 *data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size); 126 if (!*data) 138 127 return NULL; 139 128 tcb = (tcb_t *) (*data + size); … … 150 139 void tls_free_variant_2(tcb_t *tcb, size_t size) 151 140 { 141 size = ALIGN_UP(size, &_tls_alignment); 152 142 void *start = ((void *) tcb) - size; 153 143 free(start); -
uspace/lib/c/include/elf/elf_mod.h
r32573ff r5035ba05 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 70 60 /** 71 61 * Some data extracted from the headers are stored here … … 80 70 /** Pointer to the dynamic section */ 81 71 void *dynamic; 82 83 /** TLS info */84 elf_tls_info_t tls;85 72 } elf_finfo_t; 86 73 -
uspace/lib/c/include/rtld/module.h
r32573ff r5035ba05 46 46 extern module_t *module_load(rtld_t *, const char *, mlflags_t); 47 47 extern void module_load_deps(module_t *, mlflags_t); 48 extern module_t *module_by_id(rtld_t *, unsigned long);49 48 50 49 extern void modules_process_relocs(rtld_t *, module_t *); 51 extern void modules_process_tls(rtld_t *);52 50 extern void modules_untag(rtld_t *); 53 51 -
uspace/lib/c/include/rtld/rtld.h
r32573ff r5035ba05 41 41 42 42 #include <rtld/dynamic.h> 43 #include <tls.h>44 43 #include <types/rtld/rtld.h> 45 44 … … 48 47 extern void rtld_init_static(void); 49 48 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);53 49 54 50 #endif -
uspace/lib/c/include/tls.h
r32573ff r5035ba05 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);55 54 56 55 #ifdef CONFIG_TLS_VARIANT_1 -
uspace/lib/c/include/types/rtld/module.h
r32573ff r5035ba05 46 46 /** Dynamically linked module */ 47 47 typedef struct module { 48 /** Module ID */49 unsigned long id;50 /** Dynamic info for this module */51 48 dyn_info_t dyn; 52 /** Load bias */53 49 size_t bias; 54 55 /** tdata image start */56 void *tdata;57 /** tdata image size */58 size_t tdata_size;59 /** tbss size */60 size_t tbss_size;61 62 size_t ioffs;63 50 64 51 /** Containing rtld */ -
uspace/lib/c/include/types/rtld/rtld.h
r32573ff r5035ba05 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 56 50 /** List of all loaded modules including rtld and the program */ 57 51 list_t modules;
Note:
See TracChangeset
for help on using the changeset viewer.