Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/loader/main.c

    r8c3bc75 rbfdb5af1  
    5252#include <ipc/services.h>
    5353#include <ipc/loader.h>
    54 #include <ipc/ns.h>
    55 #include <macros.h>
     54#include <ns.h>
    5655#include <loader/pcb.h>
     56#include <entry_point.h>
    5757#include <errno.h>
    5858#include <async.h>
    5959#include <str.h>
    6060#include <as.h>
    61 
    62 #include <elf.h>
    63 #include <elf_load.h>
     61#include <elf/elf.h>
     62#include <elf/elf_load.h>
     63
     64#ifdef CONFIG_RTLD
     65#include <rtld/rtld.h>
     66#include <rtld/dynamic.h>
     67#include <rtld/module.h>
     68
     69static int ldr_load_dyn_linked(elf_info_t *p_info);
     70#endif
    6471
    6572#define DPRINTF(...)
     
    8996
    9097static elf_info_t prog_info;
    91 static elf_info_t interp_info;
    92 
    93 static bool is_dyn_linked;
    9498
    9599/** Used to limit number of connections to one. */
    96100static bool connected = false;
     101
     102#ifdef CONFIG_RTLD
     103/** State structure of the dynamic linker. */
     104runtime_env_t dload_re;
     105static module_t prog_mod;
     106#endif
    97107
    98108static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request)
     
    283293        int rc;
    284294       
    285         rc = elf_load_file(pathname, 0, &prog_info);
     295        rc = elf_load_file(pathname, 0, 0, &prog_info);
    286296        if (rc != EE_OK) {
    287297                DPRINTF("Failed to load executable '%s'.\n", pathname);
     
    302312        if (prog_info.interp == NULL) {
    303313                /* Statically linked program */
    304                 is_dyn_linked = false;
    305314                async_answer_0(rid, EOK);
    306315                return 0;
    307316        }
    308317       
    309         rc = elf_load_file(prog_info.interp, 0, &interp_info);
    310         if (rc != EE_OK) {
    311                 DPRINTF("Failed to load interpreter '%s.'\n",
    312                     prog_info.interp);
    313                 async_answer_0(rid, EINVAL);
    314                 return 1;
    315         }
    316        
    317         is_dyn_linked = true;
    318         async_answer_0(rid, EOK);
    319        
     318        DPRINTF("Binary is dynamically linked.\n");
     319#ifdef CONFIG_RTLD
     320        DPRINTF(" - pcb address: %p\n", &pcb);
     321        DPRINTF( "- prog dynamic: %p\n", prog_info.dynamic);
     322
     323        rc = ldr_load_dyn_linked(&prog_info);
     324#else
     325        rc = ENOTSUP;
     326#endif
     327        async_answer_0(rid, rc);
    320328        return 0;
    321329}
    322330
     331#ifdef CONFIG_RTLD
     332
     333static int ldr_load_dyn_linked(elf_info_t *p_info)
     334{
     335        runtime_env = &dload_re;
     336
     337        DPRINTF("Load dynamically linked program.\n");
     338
     339        /*
     340         * First we need to process dynamic sections of the executable
     341         * program and insert it into the module graph.
     342         */
     343
     344        DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
     345        dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn);
     346        prog_mod.bias = 0;
     347        prog_mod.dyn.soname = "[program]";
     348
     349        /* Initialize list of loaded modules */
     350        list_initialize(&runtime_env->modules);
     351        list_append(&prog_mod.modules_link, &runtime_env->modules);
     352
     353        /* Pointer to program module. Used as root of the module graph. */
     354        runtime_env->program = &prog_mod;
     355
     356        /* Work around non-existent memory space allocation. */
     357        runtime_env->next_bias = 0x1000000;
     358
     359        /*
     360         * Now we can continue with loading all other modules.
     361         */
     362
     363        DPRINTF("Load all program dependencies\n");
     364        module_load_deps(&prog_mod);
     365
     366        /*
     367         * Now relocate/link all modules together.
     368         */
     369
     370        /* Process relocations in all modules */
     371        DPRINTF("Relocate all modules\n");
     372        modules_process_relocs(&prog_mod);
     373
     374        /* Pass runtime evironment pointer through PCB. */
     375        pcb.rtld_runtime = (void *) runtime_env;
     376
     377        return 0;
     378}
     379#endif
    323380
    324381/** Run the previously loaded program.
     
    332389        const char *cp;
    333390       
     391        DPRINTF("Set task name\n");
     392
    334393        /* Set the task name. */
    335394        cp = str_rchr(pathname, '/');
     
    337396        task_set_name(cp);
    338397       
    339         if (is_dyn_linked == true) {
    340                 /* Dynamically linked program */
    341                 DPRINTF("Run ELF interpreter.\n");
    342                 DPRINTF("Entry point: %p\n", interp_info.entry);
    343                
    344                 async_answer_0(rid, EOK);
    345                 elf_run(&interp_info, &pcb);
    346         } else {
    347                 /* Statically linked program */
    348                 async_answer_0(rid, EOK);
    349                 elf_run(&prog_info, &pcb);
    350         }
     398        /* Run program */
     399        DPRINTF("Reply OK\n");
     400        async_answer_0(rid, EOK);
     401        DPRINTF("Jump to entry point at %p\n", pcb.entry);
     402        entry_point_jmp(prog_info.entry, &pcb);
    351403       
    352404        /* Not reached */
     
    358410 * to execute the loaded program).
    359411 */
    360 static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall)
    361 {
    362         ipc_callid_t callid;
    363         ipc_call_t call;
    364         int retval;
    365        
     412static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     413{
    366414        /* Already have a connection? */
    367415        if (connected) {
     
    376424       
    377425        /* Ignore parameters, the connection is already open */
    378         (void) iid;
    379426        (void) icall;
    380427       
    381         while (1) {
    382                 callid = async_get_call(&call);
     428        while (true) {
     429                int retval;
     430                ipc_call_t call;
     431                ipc_callid_t callid = async_get_call(&call);
     432               
     433                if (!IPC_GET_IMETHOD(call))
     434                        exit(0);
    383435               
    384436                switch (IPC_GET_IMETHOD(call)) {
    385                 case IPC_M_PHONE_HUNGUP:
    386                         exit(0);
    387437                case LOADER_GET_TASKID:
    388438                        ldr_get_taskid(callid, &call);
     
    411461                }
    412462               
    413                 if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP)
    414                         async_answer_0(callid, retval);
     463                async_answer_0(callid, retval);
    415464        }
    416465}
     
    425474        /* Introduce this task to the NS (give it our task ID). */
    426475        task_id_t id = task_get_id();
    427         int rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
     476        int rc = ns_intro(id);
    428477        if (rc != EOK)
    429478                return -1;
Note: See TracChangeset for help on using the changeset viewer.