Changes in / [5035ba05:32573ff] in mainline
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/abi/elf.h
r5035ba05 r32573ff 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
r5035ba05 r32573ff 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
r5035ba05 r32573ff 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
r5035ba05 r32573ff 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
r5035ba05 r32573ff 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
r5035ba05 r32573ff 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
r5035ba05 r32573ff 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> … … 135 136 136 137 m = calloc(1, sizeof(module_t)); 137 if ( !m) {138 if (m == NULL) { 138 139 printf("malloc failed\n"); 139 140 exit(1); … … 141 142 142 143 m->rtld = rtld; 144 m->id = rtld_get_next_id(rtld); 145 143 146 if ((flags & mlf_local) != 0) 144 147 m->local = true; … … 181 184 /* Insert into the list of loaded modules */ 182 185 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); 183 194 184 195 return m; … … 243 254 } 244 255 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 245 267 /** Process relocations in modules. 246 268 * … … 260 282 } 261 283 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 262 292 /** Clear BFS tags of all modules. 263 293 */ -
uspace/lib/c/generic/rtld/rtld.c
r5035ba05 r32573ff 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; 82 prog_mod.exec = true; 83 prog_mod.local = false; 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); 84 100 85 101 /* Initialize list of loaded modules */ 86 102 list_initialize(&env->modules); 87 list_append(&prog _mod.modules_link, &env->modules);103 list_append(&prog->modules_link, &env->modules); 88 104 89 105 /* Pointer to program module. Used as root of the module graph. */ 90 env->program = &prog_mod;106 env->program = prog; 91 107 92 108 /* Work around non-existent memory space allocation. */ … … 98 114 99 115 DPRINTF("Load all program dependencies\n"); 100 module_load_deps( &prog_mod, 0);116 module_load_deps(prog, 0); 101 117 102 118 /* … … 106 122 /* Process relocations in all modules */ 107 123 DPRINTF("Relocate all modules\n"); 108 modules_process_relocs(env, &prog_mod); 124 modules_process_relocs(env, prog); 125 126 modules_process_tls(env); 109 127 110 128 *rre = env; … … 112 130 } 113 131 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 114 179 /** @} 115 180 */ -
uspace/lib/c/generic/tls.c
r5035ba05 r32573ff 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
r5035ba05 r32573ff 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
r5035ba05 r32573ff 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); 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
r5035ba05 r32573ff 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
r5035ba05 r32573ff 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
r5035ba05 r32573ff 46 46 /** Dynamically linked module */ 47 47 typedef struct module { 48 /** Module ID */ 49 unsigned long id; 50 /** Dynamic info for this module */ 48 51 dyn_info_t dyn; 52 /** Load bias */ 49 53 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; 50 63 51 64 /** Containing rtld */ -
uspace/lib/c/include/types/rtld/rtld.h
r5035ba05 r32573ff 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.