Ignore:
File:
1 edited

Legend:

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

    rbfdb5af1 r8c3bc75  
    5252#include <ipc/services.h>
    5353#include <ipc/loader.h>
    54 #include <ns.h>
     54#include <ipc/ns.h>
     55#include <macros.h>
    5556#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 #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 
    69 static int ldr_load_dyn_linked(elf_info_t *p_info);
    70 #endif
     61
     62#include <elf.h>
     63#include <elf_load.h>
    7164
    7265#define DPRINTF(...)
     
    9689
    9790static elf_info_t prog_info;
     91static elf_info_t interp_info;
     92
     93static bool is_dyn_linked;
    9894
    9995/** Used to limit number of connections to one. */
    10096static bool connected = false;
    101 
    102 #ifdef CONFIG_RTLD
    103 /** State structure of the dynamic linker. */
    104 runtime_env_t dload_re;
    105 static module_t prog_mod;
    106 #endif
    10797
    10898static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request)
     
    293283        int rc;
    294284       
    295         rc = elf_load_file(pathname, 0, 0, &prog_info);
     285        rc = elf_load_file(pathname, 0, &prog_info);
    296286        if (rc != EE_OK) {
    297287                DPRINTF("Failed to load executable '%s'.\n", pathname);
     
    312302        if (prog_info.interp == NULL) {
    313303                /* Statically linked program */
     304                is_dyn_linked = false;
    314305                async_answer_0(rid, EOK);
    315306                return 0;
    316307        }
    317308       
    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);
     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       
    328320        return 0;
    329321}
    330322
    331 #ifdef CONFIG_RTLD
    332 
    333 static 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
    380323
    381324/** Run the previously loaded program.
     
    389332        const char *cp;
    390333       
    391         DPRINTF("Set task name\n");
    392 
    393334        /* Set the task name. */
    394335        cp = str_rchr(pathname, '/');
     
    396337        task_set_name(cp);
    397338       
    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);
     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        }
    403351       
    404352        /* Not reached */
     
    410358 * to execute the loaded program).
    411359 */
    412 static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    413 {
     360static 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       
    414366        /* Already have a connection? */
    415367        if (connected) {
     
    424376       
    425377        /* Ignore parameters, the connection is already open */
     378        (void) iid;
    426379        (void) icall;
    427380       
    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))
     381        while (1) {
     382                callid = async_get_call(&call);
     383               
     384                switch (IPC_GET_IMETHOD(call)) {
     385                case IPC_M_PHONE_HUNGUP:
    434386                        exit(0);
    435                
    436                 switch (IPC_GET_IMETHOD(call)) {
    437387                case LOADER_GET_TASKID:
    438388                        ldr_get_taskid(callid, &call);
     
    461411                }
    462412               
    463                 async_answer_0(callid, retval);
     413                if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP)
     414                        async_answer_0(callid, retval);
    464415        }
    465416}
     
    474425        /* Introduce this task to the NS (give it our task ID). */
    475426        task_id_t id = task_get_id();
    476         int rc = ns_intro(id);
     427        int rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
    477428        if (rc != EOK)
    478429                return -1;
Note: See TracChangeset for help on using the changeset viewer.