Changeset 6adb775f in mainline for uspace/lib/c/generic
- Timestamp:
- 2016-04-25T16:46:31Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 32573ff
- Parents:
- dc0d8b52
- Location:
- uspace/lib/c/generic
- Files:
-
- 4 edited
-
elf/elf_mod.c (modified) (2 diffs)
-
rtld/module.c (modified) (6 diffs)
-
rtld/rtld.c (modified) (7 diffs)
-
tls.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
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);
Note:
See TracChangeset
for help on using the changeset viewer.
