Ignore:
File:
1 edited

Legend:

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

    r8a1fb09 rffa2c8ef  
    5555#include <macros.h>
    5656#include <loader/pcb.h>
    57 #include <entry_point.h>
    5857#include <errno.h>
    5958#include <async.h>
     
    6362#include <elf.h>
    6463#include <elf_load.h>
    65 
    66 #ifdef CONFIG_RTLD
    67 #include <rtld/rtld.h>
    68 #include <rtld/dynamic.h>
    69 #include <rtld/module.h>
    70 
    71 static int ldr_load_dyn_linked(elf_info_t *p_info);
    72 #endif
    7364
    7465#define DPRINTF(...)
     
    9889
    9990static elf_info_t prog_info;
     91static elf_info_t interp_info;
     92
     93static bool is_dyn_linked;
    10094
    10195/** Used to limit number of connections to one. */
    10296static bool connected = false;
    103 
    104 #ifdef CONFIG_RTLD
    105 /** State structure of the dynamic linker. */
    106 runtime_env_t dload_re;
    107 static module_t prog_mod;
    108 #endif
    10997
    11098static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request)
     
    295283        int rc;
    296284       
    297         rc = elf_load_file(pathname, 0, 0, &prog_info);
     285        rc = elf_load_file(pathname, 0, &prog_info);
    298286        if (rc != EE_OK) {
    299287                DPRINTF("Failed to load executable '%s'.\n", pathname);
     
    314302        if (prog_info.interp == NULL) {
    315303                /* Statically linked program */
     304                is_dyn_linked = false;
    316305                async_answer_0(rid, EOK);
    317306                return 0;
    318307        }
    319308       
    320         DPRINTF("Binary is dynamically linked.\n");
    321 #ifdef CONFIG_RTLD
    322         DPRINTF(" - pcb address: %p\n", &pcb);
    323         DPRINTF( "- prog dynamic: %p\n", prog_info.dynamic);
    324 
    325         rc = ldr_load_dyn_linked(&prog_info);
    326 #else
    327         rc = ENOTSUP;
    328 #endif
    329         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       
    330320        return 0;
    331321}
    332322
    333 #ifdef CONFIG_RTLD
    334 
    335 static int ldr_load_dyn_linked(elf_info_t *p_info)
    336 {
    337         runtime_env = &dload_re;
    338 
    339         DPRINTF("Load dynamically linked program.\n");
    340 
    341         /*
    342          * First we need to process dynamic sections of the executable
    343          * program and insert it into the module graph.
    344          */
    345 
    346         DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
    347         dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn);
    348         prog_mod.bias = 0;
    349         prog_mod.dyn.soname = "[program]";
    350 
    351         /* Initialize list of loaded modules */
    352         list_initialize(&runtime_env->modules_head);
    353         list_append(&prog_mod.modules_link, &runtime_env->modules_head);
    354 
    355         /* Pointer to program module. Used as root of the module graph. */
    356         runtime_env->program = &prog_mod;
    357 
    358         /* Work around non-existent memory space allocation. */
    359         runtime_env->next_bias = 0x1000000;
    360 
    361         /*
    362          * Now we can continue with loading all other modules.
    363          */
    364 
    365         DPRINTF("Load all program dependencies\n");
    366         module_load_deps(&prog_mod);
    367 
    368         /*
    369          * Now relocate/link all modules together.
    370          */
    371 
    372         /* Process relocations in all modules */
    373         DPRINTF("Relocate all modules\n");
    374         modules_process_relocs(&prog_mod);
    375 
    376         /* Pass runtime evironment pointer through PCB. */
    377         pcb.rtld_runtime = (void *) runtime_env;
    378 
    379         return 0;
    380 }
    381 #endif
    382323
    383324/** Run the previously loaded program.
     
    391332        const char *cp;
    392333       
    393         DPRINTF("Set task name\n");
    394 
    395334        /* Set the task name. */
    396335        cp = str_rchr(pathname, '/');
     
    398337        task_set_name(cp);
    399338       
    400         /* Run program */
    401         DPRINTF("Reply OK\n");
    402         async_answer_0(rid, EOK);
    403         DPRINTF("Jump to entry point at %p\n", pcb.entry);
    404         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        }
    405351       
    406352        /* Not reached */
     
    461407                        /* Not reached */
    462408                default:
    463                         retval = EINVAL;
     409                        retval = ENOENT;
    464410                        break;
    465411                }
    466                
    467                 if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP)
    468                         async_answer_0(callid, retval);
     412                if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP) {
     413                        DPRINTF("Responding EINVAL to method %d.\n",
     414                            IPC_GET_IMETHOD(call));
     415                        async_answer_0(callid, EINVAL);
     416                }
    469417        }
    470418}
Note: See TracChangeset for help on using the changeset viewer.