Changeset 6adb775f in mainline for uspace/lib/c/generic/rtld/rtld.c


Ignore:
Timestamp:
2016-04-25T16:46:31Z (8 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
32573ff
Parents:
dc0d8b52
Message:

TLS for dynamically linked executables and initially loaded DSOs (but must not call dlopen or there will be trouble).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/rtld/rtld.c

    rdc0d8b52 r6adb775f  
    4343rtld_t *runtime_env;
    4444static rtld_t rt_env_static;
    45 static module_t prog_mod;
    4645
    4746/** Initialize the runtime linker for use in a statically-linked executable. */
     
    6261{
    6362        rtld_t *env;
     63        module_t *prog;
    6464
    6565        DPRINTF("Load dynamically linked program.\n");
     
    7070                return ENOMEM;
    7171
     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
    7280        /*
    7381         * First we need to process dynamic sections of the executable
     
    7684
    7785        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);
    8298
    8399        /* Initialize list of loaded modules */
    84100        list_initialize(&env->modules);
    85         list_append(&prog_mod.modules_link, &env->modules);
     101        list_append(&prog->modules_link, &env->modules);
    86102
    87103        /* Pointer to program module. Used as root of the module graph. */
    88         env->program = &prog_mod;
     104        env->program = prog;
    89105
    90106        /* Work around non-existent memory space allocation. */
     
    96112
    97113        DPRINTF("Load all program dependencies\n");
    98         module_load_deps(&prog_mod);
     114        module_load_deps(prog);
    99115
    100116        /*
     
    104120        /* Process relocations in all modules */
    105121        DPRINTF("Relocate all modules\n");
    106         modules_process_relocs(env, &prog_mod);
     122        modules_process_relocs(env, prog);
     123
     124        modules_process_tls(env);
    107125
    108126        *rre = env;
     
    110128}
    111129
     130/** Create TLS (Thread Local Storage) data structures.
     131 *
     132 * @return Pointer to TCB.
     133 */
     134tcb_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
     160unsigned long rtld_get_next_id(rtld_t *rtld)
     161{
     162        return rtld->next_id++;
     163}
     164
     165void *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
    112177/** @}
    113178 */
Note: See TracChangeset for help on using the changeset viewer.