Ignore:
File:
1 edited

Legend:

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

    r9d58539 r58563585  
    3737#include <adt/list.h>
    3838#include <elf/elf_load.h>
     39#include <errno.h>
    3940#include <fcntl.h>
    4041#include <loader/pcb.h>
     
    4950#include <rtld/module.h>
    5051
     52/** Create module for static executable.
     53 *
     54 * @param rtld Run-time dynamic linker
     55 * @param rmodule Place to store pointer to new module or @c NULL
     56 * @return EOK on success, ENOMEM if out of memory
     57 */
     58int module_create_static_exec(rtld_t *rtld, module_t **rmodule)
     59{
     60        module_t *module;
     61
     62        module = calloc(1, sizeof(module_t));
     63        if (module == NULL)
     64                return ENOMEM;
     65
     66        module->id = rtld_get_next_id(rtld);
     67        module->dyn.soname = "[program]";
     68
     69        module->rtld = rtld;
     70        module->exec = true;
     71        module->local = true;
     72
     73        module->tdata = &_tdata_start;
     74        module->tdata_size = &_tdata_end - &_tdata_start;
     75        module->tbss_size = &_tbss_end - &_tbss_start;
     76        module->tls_align = (uintptr_t)&_tls_alignment;
     77
     78        list_append(&module->modules_link, &rtld->modules);
     79
     80        if (rmodule != NULL)
     81                *rmodule = module;
     82        return EOK;
     83}
     84
    5185/** (Eagerly) process all relocation tables in a module.
    5286 *
     
    6296        module_process_pre_arch(m);
    6397
    64         if (m->dyn.plt_rel == DT_REL) {
    65                 DPRINTF("table type DT_REL\n");
    66                 if (m->dyn.rel != NULL) {
    67                         DPRINTF("non-empty\n");
    68                         rel_table_process(m, m->dyn.rel, m->dyn.rel_sz);
     98        /* jmp_rel table */
     99        if (m->dyn.jmp_rel != NULL) {
     100                DPRINTF("jmp_rel table\n");
     101                if (m->dyn.plt_rel == DT_REL) {
     102                        DPRINTF("jmp_rel table type DT_REL\n");
     103                        rel_table_process(m, m->dyn.jmp_rel, m->dyn.plt_rel_sz);
     104                } else {
     105                        assert(m->dyn.plt_rel == DT_RELA);
     106                        DPRINTF("jmp_rel table type DT_RELA\n");
     107                        rela_table_process(m, m->dyn.jmp_rel, m->dyn.plt_rel_sz);
    69108                }
    70                 /* FIXME: this seems wrong */
    71                 if (m->dyn.jmp_rel != NULL) {
    72                 DPRINTF("table type jmp-rel\n");
    73                         DPRINTF("non-empty\n");
    74                         rel_table_process(m, m->dyn.jmp_rel, m->dyn.plt_rel_sz);
    75                 }
    76         } else { /* (m->dyn.plt_rel == DT_RELA) */
    77                 DPRINTF("table type DT_RELA\n");
    78                 if (m->dyn.rela != NULL) {
    79                         DPRINTF("non-empty\n");
    80                         rela_table_process(m, m->dyn.rela, m->dyn.rela_sz);
    81                 }
     109        }
     110
     111        /* rel table */
     112        if (m->dyn.rel != NULL) {
     113                DPRINTF("rel table\n");
     114                rel_table_process(m, m->dyn.rel, m->dyn.rel_sz);
     115        }
     116
     117        /* rela table */
     118        if (m->dyn.rela != NULL) {
     119                DPRINTF("rela table\n");
     120                rela_table_process(m, m->dyn.rela, m->dyn.rela_sz);
    82121        }
    83122
     
    91130 * path components are ignored.
    92131 */
    93 module_t *module_find(const char *name)
    94 {
    95         module_t *m;
     132module_t *module_find(rtld_t *rtld, const char *name)
     133{
    96134        const char *p, *soname;
    97135
     
    107145
    108146        /* Traverse list of all modules. Not extremely fast, but simple */
    109         list_foreach(runtime_env->modules, cur) {
    110                 DPRINTF("cur = %p\n", cur);
    111                 m = list_get_instance(cur, module_t, modules_link);
     147        list_foreach(rtld->modules, modules_link, module_t, m) {
     148                DPRINTF("m = %p\n", m);
    112149                if (str_cmp(m->dyn.soname, soname) == 0) {
    113150                        return m; /* Found */
     
    124161 * Currently this trivially tries to load '/<name>'.
    125162 */
    126 module_t *module_load(const char *name)
    127 {
    128         elf_info_t info;
     163module_t *module_load(rtld_t *rtld, const char *name, mlflags_t flags)
     164{
     165        elf_finfo_t info;
    129166        char name_buf[NAME_BUF_SIZE];
    130167        module_t *m;
    131168        int rc;
    132169       
    133         m = malloc(sizeof(module_t));
    134         if (!m) {
     170        m = calloc(1, sizeof(module_t));
     171        if (m == NULL) {
    135172                printf("malloc failed\n");
    136173                exit(1);
    137174        }
     175       
     176        m->rtld = rtld;
     177        m->id = rtld_get_next_id(rtld);
     178
     179        if ((flags & mlf_local) != 0)
     180                m->local = true;
    138181
    139182        if (str_size(name) > NAME_BUF_SIZE - 2) {
     
    147190
    148191        /* FIXME: need to real allocation of address space */
    149         m->bias = runtime_env->next_bias;
    150         runtime_env->next_bias += 0x100000;
     192        m->bias = rtld->next_bias;
     193        rtld->next_bias += 0x100000;
    151194
    152195        DPRINTF("filename:'%s'\n", name_buf);
     
    173216
    174217        /* Insert into the list of loaded modules */
    175         list_append(&m->modules_link, &runtime_env->modules);
     218        list_append(&m->modules_link, &rtld->modules);
     219       
     220        /* Copy TLS info */
     221        m->tdata = info.tls.tdata;
     222        m->tdata_size = info.tls.tdata_size;
     223        m->tbss_size = info.tls.tbss_size;
     224        m->tls_align = info.tls.tls_align;
     225       
     226        DPRINTF("tdata at %p size %zu, tbss size %zu\n",
     227            m->tdata, m->tdata_size, m->tbss_size);
    176228
    177229        return m;
     
    180232/** Load all modules on which m (transitively) depends.
    181233 */
    182 void module_load_deps(module_t *m)
     234void module_load_deps(module_t *m, mlflags_t flags)
    183235{
    184236        elf_dyn_t *dp;
     
    223275
    224276                        DPRINTF("%s needs %s\n", m->dyn.soname, dep_name);
    225                         dm = module_find(dep_name);
     277                        dm = module_find(m->rtld, dep_name);
    226278                        if (!dm) {
    227                                 dm = module_load(dep_name);
    228                                 module_load_deps(dm);
     279                                dm = module_load(m->rtld, dep_name, flags);
     280                                module_load_deps(dm, flags);
    229281                        }
    230282
     
    236288}
    237289
     290/** Find module structure by ID. */
     291module_t *module_by_id(rtld_t *rtld, unsigned long id)
     292{
     293        list_foreach(rtld->modules, modules_link, module_t, m) {
     294                if (m->id == id)
     295                        return m;
     296        }
     297
     298        return NULL;
     299}
     300
    238301/** Process relocations in modules.
    239302 *
     
    243306 * @param       start   The module where to start from.
    244307 */
    245 void modules_process_relocs(module_t *start)
    246 {
    247         module_t *m;
    248 
    249         list_foreach(runtime_env->modules, cur) {
    250                 m = list_get_instance(cur, module_t, modules_link);
    251 
    252                 /* Skip rtld, since it has already been processed */
    253                 if (m != &runtime_env->rtld) {
     308void modules_process_relocs(rtld_t *rtld, module_t *start)
     309{
     310        list_foreach(rtld->modules, modules_link, module_t, m) {
     311                /* Skip rtld module, since it has already been processed */
     312                if (m != &rtld->rtld) {
    254313                        module_process_relocs(m);
    255314                }
     
    257316}
    258317
     318void modules_process_tls(rtld_t *rtld)
     319{
     320#ifdef CONFIG_TLS_VARIANT_1
     321        list_foreach(rtld->modules, modules_link, module_t, m) {
     322                m->ioffs = rtld->tls_size;
     323                list_append(&m->imodules_link, &rtmd->imodules);
     324                rtld->tls_size += m->tdata_size + m->tbss_size;
     325        }
     326#else /* CONFIG_TLS_VARIANT_2 */
     327        size_t offs;
     328
     329        list_foreach(rtld->modules, modules_link, module_t, m) {
     330                rtld->tls_size += m->tdata_size + m->tbss_size;
     331        }
     332
     333        offs = 0;
     334        list_foreach(rtld->modules, modules_link, module_t, m) {
     335                offs += m->tdata_size + m->tbss_size;
     336                m->ioffs = rtld->tls_size - offs;
     337                list_append(&m->imodules_link, &rtld->imodules);
     338        }
     339#endif
     340}
     341
    259342/** Clear BFS tags of all modules.
    260343 */
    261 void modules_untag(void)
    262 {
    263         module_t *m;
    264 
    265         list_foreach(runtime_env->modules, cur) {
    266                 m = list_get_instance(cur, module_t, modules_link);
     344void modules_untag(rtld_t *rtld)
     345{
     346        list_foreach(rtld->modules, modules_link, module_t, m) {
    267347                m->bfs_tag = false;
    268348        }
Note: See TracChangeset for help on using the changeset viewer.