Changeset d2bb25e7 in mainline for uspace/lib/c/generic/rtld/rtld.c
- Timestamp:
- 2016-05-17T22:51:37Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9c07c3d
- Parents:
- e2f26002
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/rtld/rtld.c
re2f26002 rd2bb25e7 143 143 tcb_t *tcb; 144 144 size_t offset; 145 void **dtv; 146 size_t nmods; 147 size_t i; 145 148 146 149 tcb = tls_alloc_arch(&data, rtld->tls_size); … … 148 151 return NULL; 149 152 150 /* 151 * Copy thread local data from the modules' initialization images. 152 * Zero out thread-local uninitialized data. 153 /** Allocate dynamic thread vector */ 154 nmods = list_count(&rtld->imodules); 155 dtv = malloc((nmods + 1) * sizeof(void *)); 156 if (dtv == NULL) { 157 tls_free(tcb); 158 return NULL; 159 } 160 161 /* 162 * We define generation number to be equal to vector length. 163 * We start with a vector covering the initially loaded modules. 164 */ 165 DTV_GN(dtv) = nmods; 166 167 /* 168 * Copy thread local data from the initialization images of initial 169 * modules. Zero out thread-local uninitialized data. 153 170 */ 154 171 … … 157 174 * Ascending addresses 158 175 */ 159 offset = 0; 176 offset = 0; i = 1; 160 177 list_foreach(rtld->imodules, imodules_link, module_t, m) { 178 assert(i == m->id); 161 179 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size); 180 dtv[i++] = data + offset; 162 181 memcpy(data + offset, m->tdata, m->tdata_size); 163 182 offset += m->tdata_size; … … 169 188 * Descending addresses 170 189 */ 171 offset = 0; 190 offset = 0; i = 1; 172 191 list_foreach(rtld->imodules, imodules_link, module_t, m) { 192 assert(i == m->id); 173 193 assert(offset + m->tdata_size + m->tbss_size <= rtld->tls_size); 174 194 offset += m->tbss_size; … … 176 196 offset += m->tdata_size; 177 197 memcpy(data + rtld->tls_size - offset, m->tdata, m->tdata_size); 198 dtv[i++] = data + rtld->tls_size - offset; 178 199 } 179 200 #endif 180 201 202 tcb->dtv = dtv; 181 203 return tcb; 182 204 } … … 187 209 } 188 210 189 void *rtld_tls_get_addr(rtld_t *rtld, unsigned long mod_id, 211 /** Get address of thread-local variable. 212 * 213 * @param rtld RTLD instance 214 * @param tcb TCB of the thread whose instance to return 215 * @param mod_id Module ID 216 * @param offset Offset within TLS block of the module 217 * 218 * @return Address of thread-local variable 219 */ 220 void *rtld_tls_get_addr(rtld_t *rtld, tcb_t *tcb, unsigned long mod_id, 190 221 unsigned long offset) 191 222 { 192 module_t *m; 193 uint8_t *tls; 194 195 m = module_by_id(rtld, mod_id); 196 assert(m != NULL); 197 198 if (!link_used(&m->imodules_link)) { 199 printf("module '%s' is not initial. aborting.\n", 200 m->dyn.soname); 223 if (DTV_GN(tcb->dtv) < mod_id || tcb->dtv[mod_id] == NULL) { 224 printf("Module is not initial. aborting.\n"); 201 225 abort(); 202 226 } 203 227 204 tls = tls_get(); 205 return tls + m->ioffs + offset; 206 } 207 228 return (uint8_t *)(tcb->dtv[mod_id]) + offset; 229 } 208 230 209 231 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.