Changes in uspace/lib/c/generic/rtld/rtld.c [153c7a29:5035ba05] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/rtld/rtld.c
r153c7a29 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. */ 47 intrtld_init_static(void)48 void rtld_init_static(void) 48 49 { 49 int rc;50 51 50 runtime_env = &rt_env_static; 52 51 list_initialize(&runtime_env->modules); 53 list_initialize(&runtime_env->imodules);54 52 runtime_env->next_bias = 0x2000000; 55 53 runtime_env->program = NULL; 56 runtime_env->next_id = 1;57 58 rc = module_create_static_exec(runtime_env, NULL);59 if (rc != EOK)60 return rc;61 62 modules_process_tls(runtime_env);63 64 return EOK;65 54 } 66 55 … … 73 62 { 74 63 rtld_t *env; 75 module_t *prog;76 64 77 65 DPRINTF("Load dynamically linked program.\n"); … … 82 70 return ENOMEM; 83 71 84 env->next_id = 1;85 86 prog = calloc(1, sizeof(module_t));87 if (prog == NULL) {88 free(env);89 return ENOMEM;90 }91 92 72 /* 93 73 * First we need to process dynamic sections of the executable … … 96 76 97 77 DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic); 98 dynamic_parse(p_info->dynamic, 0, &prog->dyn); 99 prog->bias = 0; 100 prog->dyn.soname = "[program]"; 101 prog->rtld = env; 102 prog->id = rtld_get_next_id(env); 103 prog->exec = true; 104 prog->local = false; 105 106 prog->tdata = p_info->tls.tdata; 107 prog->tdata_size = p_info->tls.tdata_size; 108 prog->tbss_size = p_info->tls.tbss_size; 109 prog->tls_align = p_info->tls.tls_align; 110 111 DPRINTF("prog tdata at %p size %zu, tbss size %zu\n", 112 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; 113 84 114 85 /* Initialize list of loaded modules */ 115 86 list_initialize(&env->modules); 116 list_initialize(&env->imodules); 117 list_append(&prog->modules_link, &env->modules); 87 list_append(&prog_mod.modules_link, &env->modules); 118 88 119 89 /* Pointer to program module. Used as root of the module graph. */ 120 env->program = prog;90 env->program = &prog_mod; 121 91 122 92 /* Work around non-existent memory space allocation. */ … … 128 98 129 99 DPRINTF("Load all program dependencies\n"); 130 module_load_deps(prog, 0); 131 132 /* Compute static TLS size */ 133 modules_process_tls(env); 100 module_load_deps(&prog_mod, 0); 134 101 135 102 /* … … 139 106 /* Process relocations in all modules */ 140 107 DPRINTF("Relocate all modules\n"); 141 modules_process_relocs(env, prog);108 modules_process_relocs(env, &prog_mod); 142 109 143 110 *rre = env; … … 145 112 } 146 113 147 /** Create TLS (Thread Local Storage) data structures.148 *149 * @return Pointer to TCB.150 */151 tcb_t *rtld_tls_make(rtld_t *rtld)152 {153 void *data;154 tcb_t *tcb;155 size_t offset;156 void **dtv;157 size_t nmods;158 size_t i;159 160 tcb = tls_alloc_arch(&data, rtld->tls_size);161 if (tcb == NULL)162 return NULL;163 164 /** Allocate dynamic thread vector */165 nmods = list_count(&rtld->imodules);166 dtv = malloc((nmods + 1) * sizeof(void *));167 if (dtv == NULL) {168 tls_free(tcb);169 return NULL;170 }171 172 /*173 * We define generation number to be equal to vector length.174 * We start with a vector covering the initially loaded modules.175 */176 DTV_GN(dtv) = nmods;177 178 /*179 * Copy thread local data from the initialization images of initial180 * modules. Zero out thread-local uninitialized data.181 */182 183 #ifdef CONFIG_TLS_VARIANT_1184 /*185 * Ascending addresses186 */187 offset = 0; i = 1;188 list_foreach(rtld->imodules, imodules_link, module_t, m) {189 assert(i == m->id);190 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size);191 dtv[i++] = data + offset;192 memcpy(data + offset, m->tdata, m->tdata_size);193 offset += m->tdata_size;194 memset(data + offset, 0, m->tbss_size);195 offset += m->tbss_size;196 }197 #else /* CONFIG_TLS_VARIANT_2 */198 /*199 * Descending addresses200 */201 offset = 0; i = 1;202 list_foreach(rtld->imodules, imodules_link, module_t, m) {203 assert(i == m->id);204 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size);205 offset += m->tbss_size;206 memset(data + rtld->tls_size - offset, 0, m->tbss_size);207 offset += m->tdata_size;208 memcpy(data + rtld->tls_size - offset, m->tdata, m->tdata_size);209 dtv[i++] = data + rtld->tls_size - offset;210 }211 #endif212 213 tcb->dtv = dtv;214 return tcb;215 }216 217 unsigned long rtld_get_next_id(rtld_t *rtld)218 {219 return rtld->next_id++;220 }221 222 /** Get address of thread-local variable.223 *224 * @param rtld RTLD instance225 * @param tcb TCB of the thread whose instance to return226 * @param mod_id Module ID227 * @param offset Offset within TLS block of the module228 *229 * @return Address of thread-local variable230 */231 void *rtld_tls_get_addr(rtld_t *rtld, tcb_t *tcb, unsigned long mod_id,232 unsigned long offset)233 {234 module_t *m;235 size_t dtv_len;236 void *tls_block;237 238 dtv_len = DTV_GN(tcb->dtv);239 if (dtv_len < mod_id) {240 /* Vector is short */241 242 tcb->dtv = realloc(tcb->dtv, (1 + mod_id) * sizeof(void *));243 /* XXX This can fail if OOM */244 assert(tcb->dtv != NULL);245 /* Zero out new part of vector */246 memset(tcb->dtv + (1 + dtv_len), 0, (mod_id - dtv_len) *247 sizeof(void *));248 }249 250 if (tcb->dtv[mod_id] == NULL) {251 /* TLS block is not allocated */252 253 m = module_by_id(rtld, mod_id);254 assert(m != NULL);255 /* Should not be initial module, those have TLS pre-allocated */256 assert(!link_used(&m->imodules_link));257 258 tls_block = malloc(m->tdata_size + m->tbss_size);259 /* XXX This can fail if OOM */260 assert(tls_block != NULL);261 262 /* Copy tdata */263 memcpy(tls_block, m->tdata, m->tdata_size);264 /* Zero out tbss */265 memset(tls_block + m->tdata_size, 0, m->tbss_size);266 267 tcb->dtv[mod_id] = tls_block;268 }269 270 return (uint8_t *)(tcb->dtv[mod_id]) + offset;271 }272 273 114 /** @} 274 115 */
Note:
See TracChangeset
for help on using the changeset viewer.