Changeset 32254d6 in mainline


Ignore:
Timestamp:
2025-02-13T10:16:55Z (6 days ago)
Author:
GitHub <noreply@…>
Branches:
master
Children:
f455de0
Parents:
a7a16a2f
git-author:
Matěj Volf <git@…> (2025-02-13 10:16:55)
git-committer:
GitHub <noreply@…> (2025-02-13 10:16:55)
Message:

init RTLD runtime at load time even for statically linked binaries (#242)

init RTLD runtime at load time even for statically linked binaries

Location:
uspace
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/dltest/dltest.c

    ra7a16a2f r32254d6  
    944944                return 1;
    945945
    946 #ifndef STATIC_EXE
     946#ifndef STATIC_EXE // FIXME: this define is not set anywhere
    947947
    948948        if (!test_dlfcn_dl_get_private_fib_var())
  • uspace/lib/c/generic/elf/elf_load.c

    ra7a16a2f r32254d6  
    6060        rtld_t *env;
    6161#endif
    62         errno_t rc;
     62        errno_t rc = EOK;
     63        elf_finfo_t *finfo = &info->finfo;
    6364
    64         rc = elf_load_file(file, 0, &info->finfo);
     65        rc = elf_load_file(file, 0, finfo);
    6566        if (rc != EOK) {
    66                 DPRINTF("Failed to load executable '%s'.\n", file_name);
     67                DPRINTF("Failed to load executable.\n");
    6768                return rc;
    6869        }
    6970
     71#ifdef CONFIG_RTLD
     72        DPRINTF("- prog dynamic: %p\n", finfo->dynamic);
     73        rc = rtld_prog_process(finfo, &env);
     74        if (rc != EOK) {
     75                DPRINTF("Failed to process executable.\n");
     76                return rc;
     77        }
     78        info->env = env;
     79        return EOK;
     80#else
    7081        if (info->finfo.dynamic == NULL) {
    71                 /* Statically linked program */
    72                 DPRINTF("Binary is statically linked.\n");
    7382                info->env = NULL;
    7483                return EOK;
    7584        }
    7685
    77         DPRINTF("Binary is dynamically linked.\n");
    78 #ifdef CONFIG_RTLD
    79         DPRINTF("- prog dynamic: %p\n", info->finfo.dynamic);
    80 
    81         rc = rtld_prog_process(&info->finfo, &env);
    82         info->env = env;
    83 #else
    84         rc = ENOTSUP;
     86        DPRINTF("Error: trying to run a dynamically-linked executable with CONFIG_RTLD disabled.\n");
     87        return ENOTSUP;
    8588#endif
    86         return rc;
    8789}
    8890
  • uspace/lib/c/generic/libc.c

    ra7a16a2f r32254d6  
    9696
    9797#ifdef CONFIG_RTLD
    98         if (__pcb != NULL && __pcb->rtld_runtime != NULL) {
     98        if (__pcb == NULL) {
     99                /*
     100                 * A binary loaded by kernel, not the loader.
     101                 * Noop - code loaded by kernel doesn't need RTLD.
     102                 */
     103        } else {
     104                assert(__pcb->rtld_runtime != NULL);
    99105                runtime_env = (rtld_t *) __pcb->rtld_runtime;
    100         } else {
    101                 if (rtld_init_static() != EOK)
    102                         abort();
    103106        }
    104107#endif
  • uspace/lib/c/generic/rtld/module.c

    ra7a16a2f r32254d6  
    5555#include "../private/libc.h"
    5656
    57 /** Create module for static executable.
    58  *
     57/** Create the "entrypoint" module, of the program executable
     58 *
     59 * @param p_info Program ELF file info
    5960 * @param rtld Run-time dynamic linker
    6061 * @param rmodule Place to store pointer to new module or @c NULL
    6162 * @return EOK on success, ENOMEM if out of memory
    6263 */
    63 errno_t module_create_static_exec(rtld_t *rtld, module_t **rmodule)
     64errno_t module_create_entrypoint(elf_finfo_t *p_info, rtld_t *rtld, module_t **rmodule)
    6465{
    6566        module_t *module;
     67        bool is_dynamic = p_info->dynamic != NULL;
     68        DPRINTF("module_create_entrypoint\n");
    6669
    6770        module = calloc(1, sizeof(module_t));
    68         if (module == NULL) {
    69                 DPRINTF("malloc failed\n");
     71        if (module == NULL)
    7072                return ENOMEM;
    71         }
    72 
     73
     74        uintptr_t bias = elf_get_bias(p_info->base);
     75
     76        /*
     77         * First we need to process dynamic sections of the executable
     78         * program and insert it into the module graph.
     79         */
     80        if (is_dynamic) {
     81                DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
     82                dynamic_parse(p_info->dynamic, bias, &module->dyn);
     83        } else {
     84                DPRINTF("Executable is not dynamically linked\n");
     85        }
     86
     87        module->bias = bias;
    7388        module->id = rtld_get_next_id(rtld);
    7489        module->dyn.soname = "[program]";
     
    7691        module->rtld = rtld;
    7792        module->exec = true;
    78         module->local = true;
    79 
    80         const elf_segment_header_t *tls =
    81             elf_get_phdr(__progsymbols.elfstart, PT_TLS);
    82 
    83         if (tls) {
    84                 uintptr_t bias = elf_get_bias(__progsymbols.elfstart);
    85                 module->tdata = (void *) (tls->p_vaddr + bias);
    86                 module->tdata_size = tls->p_filesz;
    87                 module->tbss_size = tls->p_memsz - tls->p_filesz;
    88                 module->tls_align = tls->p_align;
    89         } else {
    90                 module->tdata = NULL;
    91                 module->tdata_size = 0;
    92                 module->tbss_size = 0;
    93                 module->tls_align = 1;
    94         }
     93        module->local = !is_dynamic;
     94
     95        module->tdata = p_info->tls.tdata;
     96        module->tdata_size = p_info->tls.tdata_size;
     97        module->tbss_size = p_info->tls.tbss_size;
     98        module->tls_align = p_info->tls.tls_align;
     99
     100        DPRINTF("prog tdata at %p size %zu, tbss size %zu\n",
     101        module->tdata, module->tdata_size, module->tbss_size);
    95102
    96103        list_append(&module->modules_link, &rtld->modules);
  • uspace/lib/c/generic/rtld/rtld.c

    ra7a16a2f r32254d6  
    4343
    4444rtld_t *runtime_env;
    45 static rtld_t rt_env_static;
    46 
    47 /** Initialize the runtime linker for use in a statically-linked executable. */
    48 errno_t rtld_init_static(void)
    49 {
    50         errno_t rc;
    51 
    52         runtime_env = &rt_env_static;
    53         list_initialize(&runtime_env->modules);
    54         list_initialize(&runtime_env->imodules);
    55         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 }
    66 
    67 /** Initialize and process a dynamically linked executable.
     45
     46/** Initialize and process an executable.
    6847 *
    6948 * @param p_info Program info
     
    7352{
    7453        rtld_t *env;
    75         module_t *prog;
    76 
    77         DPRINTF("Load dynamically linked program.\n");
     54        bool is_dynamic = p_info->dynamic != NULL;
     55        DPRINTF("rtld_prog_process\n");
    7856
    7957        /* Allocate new RTLD environment to pass to the loaded program */
     
    8260                return ENOMEM;
    8361
    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         /*
    93          * First we need to process dynamic sections of the executable
    94          * program and insert it into the module graph.
    95          */
    96 
    97         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);
    113 
    114         /* Initialize list of loaded modules */
    11562        list_initialize(&env->modules);
    11663        list_initialize(&env->imodules);
    117         list_append(&prog->modules_link, &env->modules);
     64        env->next_id = 1;
     65
     66        module_t *module;
     67        errno_t rc = module_create_entrypoint(p_info, env, &module);
     68        if (rc != EOK) {
     69                free(env);
     70                return rc;
     71        }
    11872
    11973        /* Pointer to program module. Used as root of the module graph. */
    120         env->program = prog;
     74        env->program = module;
    12175
    12276        /*
     
    12478         */
    12579
    126         DPRINTF("Load all program dependencies\n");
    127         errno_t rc = module_load_deps(prog, 0);
    128         if (rc != EOK) {
    129                 return rc;
     80        if (is_dynamic) {
     81                DPRINTF("Load all program dependencies\n");
     82                rc = module_load_deps(module, 0);
     83                if (rc != EOK) {
     84                        free(module);
     85                        free(env);
     86                        return rc;
     87                }
    13088        }
    13189
     
    13795         */
    13896
    139         /* Process relocations in all modules */
    140         DPRINTF("Relocate all modules\n");
    141         modules_process_relocs(env, prog);
    142 
    143         *rre = env;
     97        if (is_dynamic) {
     98                /* Process relocations in all modules */
     99                DPRINTF("Relocate all modules\n");
     100                modules_process_relocs(env, module);
     101        }
     102
     103        if (rre != NULL)
     104                *rre = env;
    144105        return EOK;
    145106}
  • uspace/lib/c/generic/thread/tls.c

    ra7a16a2f r32254d6  
    7474}
    7575
    76 /** Get address of static TLS block */
     76/** Get address of static TLS block - only when RTLD is not initialized  */
    7777void *tls_get(void)
    7878{
  • uspace/lib/c/include/rtld/module.h

    ra7a16a2f r32254d6  
    4141#include <types/rtld/rtld.h>
    4242
    43 extern errno_t module_create_static_exec(rtld_t *, module_t **);
     43extern errno_t module_create_entrypoint(elf_finfo_t *, rtld_t *, module_t **);
    4444extern void module_process_relocs(module_t *);
    4545extern module_t *module_find(rtld_t *, const char *);
  • uspace/lib/c/include/rtld/rtld.h

    ra7a16a2f r32254d6  
    4545extern rtld_t *runtime_env;
    4646
    47 extern errno_t rtld_init_static(void);
    4847extern errno_t rtld_prog_process(elf_finfo_t *, rtld_t **);
    4948extern tcb_t *rtld_tls_make(rtld_t *);
  • uspace/srv/loader/main.c

    ra7a16a2f r32254d6  
    300300
    301301#ifdef CONFIG_RTLD
    302         if (prog_info.env) {
    303                 pcb.tcb = rtld_tls_make(prog_info.env);
    304         } else {
    305                 pcb.tcb = tls_make(prog_info.finfo.base);
    306         }
     302        assert(prog_info.env != NULL);
     303        pcb.tcb = rtld_tls_make(prog_info.env);
    307304#else
    308305        pcb.tcb = tls_make(prog_info.finfo.base);
Note: See TracChangeset for help on using the changeset viewer.