Ignore:
File:
1 edited

Legend:

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

    r27b76ca rffa2c8ef  
    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 #include <vfs/vfs.h>
    64 
    65 #ifdef CONFIG_RTLD
    66 #include <rtld/rtld.h>
    67 #include <rtld/dynamic.h>
    68 #include <rtld/module.h>
    69 
    70 static int ldr_load_dyn_linked(elf_info_t *p_info);
    71 #endif
     61
     62#include <elf.h>
     63#include <elf_load.h>
    7264
    7365#define DPRINTF(...)
     
    9082
    9183/** Number of preset files */
    92 static unsigned int filc = 0;
     84static int filc = 0;
     85/** Preset files vector */
     86static fdi_node_t **filv = NULL;
     87/** Buffer holding all preset files */
     88static fdi_node_t *fil_buf = NULL;
    9389
    9490static elf_info_t prog_info;
     91static elf_info_t interp_info;
     92
     93static bool is_dyn_linked;
    9594
    9695/** Used to limit number of connections to one. */
    9796static bool connected = false;
    98 
    99 #ifdef CONFIG_RTLD
    100 /** State structure of the dynamic linker. */
    101 runtime_env_t dload_re;
    102 static module_t prog_mod;
    103 #endif
    10497
    10598static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request)
     
    236229static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
    237230{
    238         size_t count = IPC_GET_ARG1(*request);
    239 
    240         async_exch_t *vfs_exch = vfs_exchange_begin();
    241 
    242         for (filc = 0; filc < count; filc++) {
    243                 ipc_callid_t callid;
    244                 int fd;
    245 
    246                 if (!async_state_change_receive(&callid, NULL, NULL, NULL)) {
    247                         async_answer_0(callid, EINVAL);
    248                         break;
    249                 }
    250                 async_state_change_finalize(callid, vfs_exch);
    251                 fd = fd_wait();
    252                 assert(fd == (int) filc);
    253         }
    254 
    255         vfs_exchange_end(vfs_exch);
    256 
     231        fdi_node_t *buf;
     232        size_t buf_size;
     233        int rc = async_data_write_accept((void **) &buf, false, 0, 0,
     234            sizeof(fdi_node_t), &buf_size);
     235       
     236        if (rc == EOK) {
     237                int count = buf_size / sizeof(fdi_node_t);
     238               
     239                /*
     240                 * Allocate new filv
     241                 */
     242                fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *));
     243                if (_filv == NULL) {
     244                        free(buf);
     245                        async_answer_0(rid, ENOMEM);
     246                        return;
     247                }
     248               
     249                /*
     250                 * Fill the new filv with argument pointers
     251                 */
     252                int i;
     253                for (i = 0; i < count; i++)
     254                        _filv[i] = &buf[i];
     255               
     256                _filv[count] = NULL;
     257               
     258                /*
     259                 * Copy temporary data to global variables
     260                 */
     261                if (fil_buf != NULL)
     262                        free(fil_buf);
     263               
     264                if (filv != NULL)
     265                        free(filv);
     266               
     267                filc = count;
     268                fil_buf = buf;
     269                filv = _filv;
     270        }
     271       
    257272        async_answer_0(rid, EOK);
    258273}
     
    268283        int rc;
    269284       
    270         rc = elf_load_file(pathname, 0, 0, &prog_info);
     285        rc = elf_load_file(pathname, 0, &prog_info);
    271286        if (rc != EE_OK) {
    272287                DPRINTF("Failed to load executable '%s'.\n", pathname);
     
    283298       
    284299        pcb.filc = filc;
     300        pcb.filv = filv;
    285301       
    286302        if (prog_info.interp == NULL) {
    287303                /* Statically linked program */
     304                is_dyn_linked = false;
    288305                async_answer_0(rid, EOK);
    289306                return 0;
    290307        }
    291308       
    292         DPRINTF("Binary is dynamically linked.\n");
    293 #ifdef CONFIG_RTLD
    294         DPRINTF(" - pcb address: %p\n", &pcb);
    295         DPRINTF( "- prog dynamic: %p\n", prog_info.dynamic);
    296 
    297         rc = ldr_load_dyn_linked(&prog_info);
    298 #else
    299         rc = ENOTSUP;
    300 #endif
    301         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       
    302320        return 0;
    303321}
    304322
    305 #ifdef CONFIG_RTLD
    306 
    307 static int ldr_load_dyn_linked(elf_info_t *p_info)
    308 {
    309         runtime_env = &dload_re;
    310 
    311         DPRINTF("Load dynamically linked program.\n");
    312 
    313         /*
    314          * First we need to process dynamic sections of the executable
    315          * program and insert it into the module graph.
    316          */
    317 
    318         DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
    319         dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn);
    320         prog_mod.bias = 0;
    321         prog_mod.dyn.soname = "[program]";
    322 
    323         /* Initialize list of loaded modules */
    324         list_initialize(&runtime_env->modules);
    325         list_append(&prog_mod.modules_link, &runtime_env->modules);
    326 
    327         /* Pointer to program module. Used as root of the module graph. */
    328         runtime_env->program = &prog_mod;
    329 
    330         /* Work around non-existent memory space allocation. */
    331         runtime_env->next_bias = 0x1000000;
    332 
    333         /*
    334          * Now we can continue with loading all other modules.
    335          */
    336 
    337         DPRINTF("Load all program dependencies\n");
    338         module_load_deps(&prog_mod);
    339 
    340         /*
    341          * Now relocate/link all modules together.
    342          */
    343 
    344         /* Process relocations in all modules */
    345         DPRINTF("Relocate all modules\n");
    346         modules_process_relocs(&prog_mod);
    347 
    348         /* Pass runtime evironment pointer through PCB. */
    349         pcb.rtld_runtime = (void *) runtime_env;
    350 
    351         return 0;
    352 }
    353 #endif
    354323
    355324/** Run the previously loaded program.
     
    363332        const char *cp;
    364333       
    365         DPRINTF("Set task name\n");
    366 
    367334        /* Set the task name. */
    368335        cp = str_rchr(pathname, '/');
     
    370337        task_set_name(cp);
    371338       
    372         /* Run program */
    373         DPRINTF("Reply OK\n");
    374         async_answer_0(rid, EOK);
    375         DPRINTF("Jump to entry point at %p\n", pcb.entry);
    376         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        }
    377351       
    378352        /* Not reached */
     
    384358 * to execute the loaded program).
    385359 */
    386 static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    387 {
     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       
    388366        /* Already have a connection? */
    389367        if (connected) {
     
    398376       
    399377        /* Ignore parameters, the connection is already open */
     378        (void) iid;
    400379        (void) icall;
    401380       
    402         while (true) {
    403                 int retval;
    404                 ipc_call_t call;
    405                 ipc_callid_t callid = async_get_call(&call);
    406                
    407                 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:
    408386                        exit(0);
    409                
    410                 switch (IPC_GET_IMETHOD(call)) {
    411387                case LOADER_GET_TASKID:
    412388                        ldr_get_taskid(callid, &call);
     
    431407                        /* Not reached */
    432408                default:
    433                         retval = EINVAL;
     409                        retval = ENOENT;
    434410                        break;
    435411                }
    436                
    437                 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                }
    438417        }
    439418}
     
    448427        /* Introduce this task to the NS (give it our task ID). */
    449428        task_id_t id = task_get_id();
    450         int rc = ns_intro(id);
     429        int rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
    451430        if (rc != EOK)
    452431                return -1;
Note: See TracChangeset for help on using the changeset viewer.