Subversion Repositories HelenOS

Rev

Rev 3447 | Rev 3475 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3447 Rev 3470
Line 44... Line 44...
44
 */
44
 */
45
 
45
 
46
#include <stdio.h>
46
#include <stdio.h>
47
#include <stdlib.h>
47
#include <stdlib.h>
48
#include <unistd.h>
48
#include <unistd.h>
-
 
49
#include <bool.h>
49
#include <fcntl.h>
50
#include <fcntl.h>
50
#include <sys/types.h>
51
#include <sys/types.h>
51
#include <ipc/ipc.h>
52
#include <ipc/ipc.h>
52
#include <ipc/loader.h>
53
#include <ipc/loader.h>
53
#include <loader/pcb.h>
54
#include <loader/pcb.h>
Line 75... Line 76...
75
/** Argument vector */
76
/** Argument vector */
76
static char **argv = NULL;
77
static char **argv = NULL;
77
/** Buffer holding all arguments */
78
/** Buffer holding all arguments */
78
static char *arg_buf = NULL;
79
static char *arg_buf = NULL;
79
 
80
 
-
 
81
static elf_info_t prog_info;
-
 
82
static elf_info_t interp_info;
-
 
83
 
-
 
84
static bool is_dyn_linked;
-
 
85
 
-
 
86
 
80
static int loader_get_taskid(ipc_callid_t rid, ipc_call_t *request)
87
static void loader_get_taskid(ipc_callid_t rid, ipc_call_t *request)
81
{
88
{
82
    ipc_callid_t callid;
89
    ipc_callid_t callid;
83
    task_id_t task_id;
90
    task_id_t task_id;
84
    size_t len;
91
    size_t len;
85
 
92
 
Line 210... Line 217...
210
 
217
 
211
    argc = n;
218
    argc = n;
212
    argv[n] = NULL;
219
    argv[n] = NULL;
213
}
220
}
214
 
221
 
215
 
-
 
216
/** Load and run the previously selected program.
222
/** Load the previously selected program.
217
 *
223
 *
218
 * @param rid
224
 * @param rid
219
 * @param request
225
 * @param request
220
 * @return 0 on success, !0 on error.
226
 * @return 0 on success, !0 on error.
221
 */
227
 */
222
static int loader_run(ipc_callid_t rid, ipc_call_t *request)
228
static int loader_load(ipc_callid_t rid, ipc_call_t *request)
223
{
229
{
224
    int rc;
230
    int rc;
225
 
231
 
226
    elf_info_t prog_info;
-
 
227
    elf_info_t interp_info;
-
 
228
 
-
 
229
//  printf("Load program '%s'\n", pathname);
232
//  printf("Load program '%s'\n", pathname);
230
 
233
 
231
    rc = elf_load_file(pathname, 0, &prog_info);
234
    rc = elf_load_file(pathname, 0, &prog_info);
232
    if (rc < 0) {
235
    if (rc < 0) {
233
        printf("failed to load program\n");
236
        printf("failed to load program\n");
Line 243... Line 246...
243
 
246
 
244
    if (prog_info.interp == NULL) {
247
    if (prog_info.interp == NULL) {
245
        /* Statically linked program */
248
        /* Statically linked program */
246
//      printf("Run statically linked program\n");
249
//      printf("Run statically linked program\n");
247
//      printf("entry point: 0x%llx\n", prog_info.entry);
250
//      printf("entry point: 0x%llx\n", prog_info.entry);
-
 
251
        is_dyn_linked = false;
248
        ipc_answer_0(rid, EOK);
252
        ipc_answer_0(rid, EOK);
249
        close_console();
-
 
250
        elf_run(&prog_info, &pcb);
-
 
251
        return 0;
253
        return 0;
252
    }
254
    }
253
 
255
 
254
    printf("Load dynamic linker '%s'\n", prog_info.interp);
256
    printf("Load dynamic linker '%s'\n", prog_info.interp);
255
    rc = elf_load_file("/rtld.so", RTLD_BIAS, &interp_info);
257
    rc = elf_load_file("/rtld.so", RTLD_BIAS, &interp_info);
Line 263... Line 265...
263
     * Provide dynamic linker with some useful data
265
     * Provide dynamic linker with some useful data
264
     */
266
     */
265
    pcb.rtld_dynamic = interp_info.dynamic;
267
    pcb.rtld_dynamic = interp_info.dynamic;
266
    pcb.rtld_bias = RTLD_BIAS;
268
    pcb.rtld_bias = RTLD_BIAS;
267
 
269
 
268
    printf("run dynamic linker\n");
270
    is_dyn_linked = true;
269
    printf("entry point: 0x%llx\n", interp_info.entry);
-
 
270
    close_console();
-
 
271
 
-
 
272
    ipc_answer_0(rid, EOK);
271
    ipc_answer_0(rid, EOK);
273
    elf_run(&interp_info, &pcb);
-
 
274
 
272
 
275
    /* Not reached */
-
 
276
    return 0;
273
    return 0;
277
}
274
}
278
 
275
 
-
 
276
 
-
 
277
/** Run the previously loaded program.
-
 
278
 *
-
 
279
 * @param rid
-
 
280
 * @param request
-
 
281
 * @return 0 on success, !0 on error.
-
 
282
 */
-
 
283
static void loader_run(ipc_callid_t rid, ipc_call_t *request)
-
 
284
{
-
 
285
    if (is_dyn_linked == true) {
-
 
286
        /* Dynamically linked program */
-
 
287
        printf("run dynamic linker\n");
-
 
288
        printf("entry point: 0x%llx\n", interp_info.entry);
-
 
289
        close_console();
-
 
290
 
-
 
291
        ipc_answer_0(rid, EOK);
-
 
292
        elf_run(&interp_info, &pcb);
-
 
293
 
-
 
294
    } else {
-
 
295
        /* Statically linked program */
-
 
296
        close_console();
-
 
297
        ipc_answer_0(rid, EOK);
-
 
298
        elf_run(&prog_info, &pcb);
-
 
299
    }
-
 
300
 
-
 
301
    /* Not reached */
-
 
302
}
-
 
303
 
279
/** Handle loader connection.
304
/** Handle loader connection.
280
 *
305
 *
281
 * Receive and carry out commands (of which the last one should be
306
 * Receive and carry out commands (of which the last one should be
282
 * to execute the loaded program).
307
 * to execute the loaded program).
283
 */
308
 */
Line 290... Line 315...
290
    /* Ignore parameters, the connection is already open */
315
    /* Ignore parameters, the connection is already open */
291
    (void)iid; (void)icall;
316
    (void)iid; (void)icall;
292
 
317
 
293
    while (1) {
318
    while (1) {
294
        callid = async_get_call(&call);
319
        callid = async_get_call(&call);
295
//      printf("received call from phone %d, method=%d\n",
-
 
296
//          call.in_phone_hash, IPC_GET_METHOD(call));
-
 
-
 
320
 
297
        switch (IPC_GET_METHOD(call)) {
321
        switch (IPC_GET_METHOD(call)) {
298
        case LOADER_GET_TASKID:
322
        case LOADER_GET_TASKID:
299
            loader_get_taskid(callid, &call);
323
            loader_get_taskid(callid, &call);
300
            continue;
324
            continue;
301
        case LOADER_SET_PATHNAME:
325
        case LOADER_SET_PATHNAME:
302
            loader_set_pathname(callid, &call);
326
            loader_set_pathname(callid, &call);
303
            continue;
327
            continue;
304
        case LOADER_SET_ARGS:
328
        case LOADER_SET_ARGS:
305
            loader_set_args(callid, &call);
329
            loader_set_args(callid, &call);
-
 
330
            continue;
-
 
331
        case LOADER_LOAD:
-
 
332
            loader_load(callid, &call);
-
 
333
            continue;
306
        case LOADER_RUN:
334
        case LOADER_RUN:
307
            loader_run(callid, &call);
335
            loader_run(callid, &call);
308
            exit(0);
-
 
309
            continue;
336
            /* Not reached */
310
        default:
337
        default:
311
            retval = ENOENT;
338
            retval = ENOENT;
312
            break;
339
            break;
313
        }
340
        }
314
        if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&
341
        if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&