Subversion Repositories HelenOS

Rev

Rev 4348 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4348 Rev 4691
Line 50... Line 50...
50
#include <fcntl.h>
50
#include <fcntl.h>
51
#include <sys/types.h>
51
#include <sys/types.h>
52
#include <ipc/ipc.h>
52
#include <ipc/ipc.h>
53
#include <ipc/services.h>
53
#include <ipc/services.h>
54
#include <ipc/loader.h>
54
#include <ipc/loader.h>
-
 
55
#include <ipc/ns.h>
-
 
56
#include <macros.h>
55
#include <loader/pcb.h>
57
#include <loader/pcb.h>
56
#include <console.h>
-
 
57
#include <errno.h>
58
#include <errno.h>
58
#include <async.h>
59
#include <async.h>
-
 
60
#include <string.h>
59
#include <as.h>
61
#include <as.h>
60
 
62
 
61
#include <elf.h>
63
#include <elf.h>
62
#include <elf_load.h>
64
#include <elf_load.h>
63
 
65
 
Line 76... Line 78...
76
/** Argument vector */
78
/** Argument vector */
77
static char **argv = NULL;
79
static char **argv = NULL;
78
/** Buffer holding all arguments */
80
/** Buffer holding all arguments */
79
static char *arg_buf = NULL;
81
static char *arg_buf = NULL;
80
 
82
 
-
 
83
/** Number of preset files */
-
 
84
static int filc = 0;
-
 
85
/** Preset files vector */
-
 
86
static fdi_node_t **filv = NULL;
-
 
87
/** Buffer holding all preset files */
-
 
88
static fdi_node_t *fil_buf = NULL;
-
 
89
 
81
static elf_info_t prog_info;
90
static elf_info_t prog_info;
82
static elf_info_t interp_info;
91
static elf_info_t interp_info;
83
 
92
 
84
static bool is_dyn_linked;
93
static bool is_dyn_linked;
85
 
94
 
86
/** Used to limit number of connections to one. */
95
/** Used to limit number of connections to one. */
87
static bool connected;
96
static bool connected;
88
 
97
 
89
static void loader_get_taskid(ipc_callid_t rid, ipc_call_t *request)
98
static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request)
90
{
99
{
91
    ipc_callid_t callid;
100
    ipc_callid_t callid;
92
    task_id_t task_id;
101
    task_id_t task_id;
93
    size_t len;
102
    size_t len;
94
   
103
   
Line 111... Line 120...
111
/** Receive a call setting pathname of the program to execute.
120
/** Receive a call setting pathname of the program to execute.
112
 *
121
 *
113
 * @param rid
122
 * @param rid
114
 * @param request
123
 * @param request
115
 */
124
 */
116
static void loader_set_pathname(ipc_callid_t rid, ipc_call_t *request)
125
static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request)
117
{
126
{
118
    ipc_callid_t callid;
127
    ipc_callid_t callid;
119
    size_t len;
128
    size_t len;
120
    char *name_buf;
129
    char *name_buf;
121
   
130
   
Line 147... Line 156...
147
/** Receive a call setting arguments of the program to execute.
156
/** Receive a call setting arguments of the program to execute.
148
 *
157
 *
149
 * @param rid
158
 * @param rid
150
 * @param request
159
 * @param request
151
 */
160
 */
152
static void loader_set_args(ipc_callid_t rid, ipc_call_t *request)
161
static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request)
153
{
162
{
154
    ipc_callid_t callid;
163
    ipc_callid_t callid;
155
    size_t buf_size, arg_size;
164
    size_t buf_size, arg_size;
156
    char *p;
165
    char *p;
157
    int n;
166
    int n;
Line 220... Line 229...
220
    argv[n] = NULL;
229
    argv[n] = NULL;
221
 
230
 
222
    ipc_answer_0(rid, EOK);
231
    ipc_answer_0(rid, EOK);
223
}
232
}
224
 
233
 
-
 
234
/** Receive a call setting preset files of the program to execute.
-
 
235
 *
-
 
236
 * @param rid
-
 
237
 * @param request
-
 
238
 */
-
 
239
static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
-
 
240
{
-
 
241
    ipc_callid_t callid;
-
 
242
    size_t buf_size;
-
 
243
    if (!ipc_data_write_receive(&callid, &buf_size)) {
-
 
244
        ipc_answer_0(callid, EINVAL);
-
 
245
        ipc_answer_0(rid, EINVAL);
-
 
246
        return;
-
 
247
    }
-
 
248
   
-
 
249
    if ((buf_size % sizeof(fdi_node_t)) != 0) {
-
 
250
        ipc_answer_0(callid, EINVAL);
-
 
251
        ipc_answer_0(rid, EINVAL);
-
 
252
        return;
-
 
253
    }
-
 
254
   
-
 
255
    if (fil_buf != NULL) {
-
 
256
        free(fil_buf);
-
 
257
        fil_buf = NULL;
-
 
258
    }
-
 
259
   
-
 
260
    if (filv != NULL) {
-
 
261
        free(filv);
-
 
262
        filv = NULL;
-
 
263
    }
-
 
264
   
-
 
265
    fil_buf = malloc(buf_size);
-
 
266
    if (!fil_buf) {
-
 
267
        ipc_answer_0(callid, ENOMEM);
-
 
268
        ipc_answer_0(rid, ENOMEM);
-
 
269
        return;
-
 
270
    }
-
 
271
   
-
 
272
    ipc_data_write_finalize(callid, fil_buf, buf_size);
-
 
273
   
-
 
274
    int count = buf_size / sizeof(fdi_node_t);
-
 
275
   
-
 
276
    /* Allocate filvv */
-
 
277
    filv = malloc((count + 1) * sizeof(fdi_node_t *));
-
 
278
   
-
 
279
    if (filv == NULL) {
-
 
280
        free(fil_buf);
-
 
281
        ipc_answer_0(rid, ENOMEM);
-
 
282
        return;
-
 
283
    }
-
 
284
   
-
 
285
    /*
-
 
286
     * Fill filv with argument pointers
-
 
287
     */
-
 
288
    int i;
-
 
289
    for (i = 0; i < count; i++)
-
 
290
        filv[i] = &fil_buf[i];
-
 
291
   
-
 
292
    filc = count;
-
 
293
    filv[count] = NULL;
-
 
294
   
-
 
295
    ipc_answer_0(rid, EOK);
-
 
296
}
-
 
297
 
225
/** Load the previously selected program.
298
/** Load the previously selected program.
226
 *
299
 *
227
 * @param rid
300
 * @param rid
228
 * @param request
301
 * @param request
229
 * @return 0 on success, !0 on error.
302
 * @return 0 on success, !0 on error.
230
 */
303
 */
231
static int loader_load(ipc_callid_t rid, ipc_call_t *request)
304
static int ldr_load(ipc_callid_t rid, ipc_call_t *request)
232
{
305
{
233
    int rc;
306
    int rc;
234
   
307
   
235
    rc = elf_load_file(pathname, 0, 0, &prog_info);
308
    rc = elf_load_file(pathname, 0, 0, &prog_info);
236
    if (rc != EE_OK) {
309
    if (rc != EE_OK) {
Line 242... Line 315...
242
    elf_create_pcb(&prog_info, &pcb);
315
    elf_create_pcb(&prog_info, &pcb);
243
   
316
   
244
    pcb.argc = argc;
317
    pcb.argc = argc;
245
    pcb.argv = argv;
318
    pcb.argv = argv;
246
   
319
   
-
 
320
    pcb.filc = filc;
-
 
321
    pcb.filv = filv;
-
 
322
   
247
    if (prog_info.interp == NULL) {
323
    if (prog_info.interp == NULL) {
248
        /* Statically linked program */
324
        /* Statically linked program */
249
        is_dyn_linked = false;
325
        is_dyn_linked = false;
250
        ipc_answer_0(rid, EOK);
326
        ipc_answer_0(rid, EOK);
251
        return 0;
327
        return 0;
Line 276... Line 352...
276
 *
352
 *
277
 * @param rid
353
 * @param rid
278
 * @param request
354
 * @param request
279
 * @return 0 on success, !0 on error.
355
 * @return 0 on success, !0 on error.
280
 */
356
 */
281
static void loader_run(ipc_callid_t rid, ipc_call_t *request)
357
static void ldr_run(ipc_callid_t rid, ipc_call_t *request)
282
{
358
{
283
    const char *cp;
359
    const char *cp;
284
   
360
   
285
    /* Set the task name. */
361
    /* Set the task name. */
286
    cp = str_rchr(pathname, '/');
362
    cp = str_rchr(pathname, '/');
Line 289... Line 365...
289
   
365
   
290
    if (is_dyn_linked == true) {
366
    if (is_dyn_linked == true) {
291
        /* Dynamically linked program */
367
        /* Dynamically linked program */
292
        DPRINTF("Run ELF interpreter.\n");
368
        DPRINTF("Run ELF interpreter.\n");
293
        DPRINTF("Entry point: 0x%lx\n", interp_info.entry);
369
        DPRINTF("Entry point: 0x%lx\n", interp_info.entry);
294
        console_close();
-
 
295
       
370
       
296
        ipc_answer_0(rid, EOK);
371
        ipc_answer_0(rid, EOK);
297
        program_run(interp_info.entry, &pcb);
372
        program_run(interp_info.entry, &pcb);
298
    } else {
373
    } else {
299
        /* Statically linked program */
374
        /* Statically linked program */
300
        console_close();
-
 
301
        ipc_answer_0(rid, EOK);
375
        ipc_answer_0(rid, EOK);
302
        program_run(prog_info.entry, &pcb);
376
        program_run(prog_info.entry, &pcb);
303
    }
377
    }
304
 
378
   
305
    /* Not reached */
379
    /* Not reached */
306
}
380
}
307
 
381
 
308
/** Handle loader connection.
382
/** Handle loader connection.
309
 *
383
 *
310
 * Receive and carry out commands (of which the last one should be
384
 * Receive and carry out commands (of which the last one should be
311
 * to execute the loaded program).
385
 * to execute the loaded program).
312
 */
386
 */
313
static void loader_connection(ipc_callid_t iid, ipc_call_t *icall)
387
static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall)
314
{
388
{
315
    ipc_callid_t callid;
389
    ipc_callid_t callid;
316
    ipc_call_t call;
390
    ipc_call_t call;
317
    int retval;
391
    int retval;
318
   
392
   
Line 336... Line 410...
336
       
410
       
337
        switch (IPC_GET_METHOD(call)) {
411
        switch (IPC_GET_METHOD(call)) {
338
        case IPC_M_PHONE_HUNGUP:
412
        case IPC_M_PHONE_HUNGUP:
339
            exit(0);
413
            exit(0);
340
        case LOADER_GET_TASKID:
414
        case LOADER_GET_TASKID:
341
            loader_get_taskid(callid, &call);
415
            ldr_get_taskid(callid, &call);
342
            continue;
416
            continue;
343
        case LOADER_SET_PATHNAME:
417
        case LOADER_SET_PATHNAME:
344
            loader_set_pathname(callid, &call);
418
            ldr_set_pathname(callid, &call);
345
            continue;
419
            continue;
346
        case LOADER_SET_ARGS:
420
        case LOADER_SET_ARGS:
347
            loader_set_args(callid, &call);
421
            ldr_set_args(callid, &call);
-
 
422
            continue;
-
 
423
        case LOADER_SET_FILES:
-
 
424
            ldr_set_files(callid, &call);
348
            continue;
425
            continue;
349
        case LOADER_LOAD:
426
        case LOADER_LOAD:
350
            loader_load(callid, &call);
427
            ldr_load(callid, &call);
351
            continue;
428
            continue;
352
        case LOADER_RUN:
429
        case LOADER_RUN:
353
            loader_run(callid, &call);
430
            ldr_run(callid, &call);
354
            /* Not reached */
431
            /* Not reached */
355
        default:
432
        default:
356
            retval = ENOENT;
433
            retval = ENOENT;
357
            break;
434
            break;
358
        }
435
        }
Line 368... Line 445...
368
/** Program loader main function.
445
/** Program loader main function.
369
 */
446
 */
370
int main(int argc, char *argv[])
447
int main(int argc, char *argv[])
371
{
448
{
372
    ipcarg_t phonead;
449
    ipcarg_t phonead;
-
 
450
    task_id_t id;
-
 
451
    int rc;
373
   
452
 
374
    connected = false;
453
    connected = false;
375
   
454
 
-
 
455
    /* Introduce this task to the NS (give it our task ID). */
-
 
456
    id = task_get_id();
-
 
457
    rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
-
 
458
    if (rc != EOK)
-
 
459
        return -1;
-
 
460
 
376
    /* Set a handler of incomming connections. */
461
    /* Set a handler of incomming connections. */
377
    async_set_client_connection(loader_connection);
462
    async_set_client_connection(ldr_connection);
378
   
463
   
379
    /* Register at naming service. */
464
    /* Register at naming service. */
380
    if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)
465
    if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)
381
        return -1;
466
        return -2;
382
   
467
 
383
    async_manager();
468
    async_manager();
384
   
469
   
385
    /* Never reached */
470
    /* Never reached */
386
    return 0;
471
    return 0;
387
}
472
}