Subversion Repositories HelenOS

Rev

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

Rev 3343 Rev 3492
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
 
-
 
87
static void loader_get_taskid(ipc_callid_t rid, ipc_call_t *request)
-
 
88
{
-
 
89
    ipc_callid_t callid;
-
 
90
    task_id_t task_id;
-
 
91
    size_t len;
-
 
92
 
-
 
93
    task_id = task_get_id();
-
 
94
 
-
 
95
    if (!ipc_data_read_receive(&callid, &len)) {
-
 
96
        ipc_answer_0(callid, EINVAL);
-
 
97
        ipc_answer_0(rid, EINVAL);
-
 
98
        return;
-
 
99
    }
-
 
100
 
-
 
101
    if (len > sizeof(task_id)) len = sizeof(task_id);
-
 
102
 
-
 
103
    ipc_data_read_finalize(callid, &task_id, len);
-
 
104
    ipc_answer_0(rid, EOK);
-
 
105
}
-
 
106
 
-
 
107
 
80
/** Receive a call setting pathname of the program to execute.
108
/** Receive a call setting pathname of the program to execute.
81
 *
109
 *
82
 * @param rid
110
 * @param rid
83
 * @param request
111
 * @param request
84
 */
112
 */
Line 189... Line 217...
189
 
217
 
190
    argc = n;
218
    argc = n;
191
    argv[n] = NULL;
219
    argv[n] = NULL;
192
}
220
}
193
 
221
 
194
 
-
 
195
/** Load and run the previously selected program.
222
/** Load the previously selected program.
196
 *
223
 *
197
 * @param rid
224
 * @param rid
198
 * @param request
225
 * @param request
199
 * @return 0 on success, !0 on error.
226
 * @return 0 on success, !0 on error.
200
 */
227
 */
201
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)
202
{
229
{
203
    int rc;
230
    int rc;
204
 
231
 
205
    elf_info_t prog_info;
-
 
206
    elf_info_t interp_info;
-
 
207
 
-
 
208
//  printf("Load program '%s'\n", pathname);
232
//  printf("Load program '%s'\n", pathname);
209
 
233
 
210
    rc = elf_load_file(pathname, 0, &prog_info);
234
    rc = elf_load_file(pathname, 0, &prog_info);
211
    if (rc < 0) {
235
    if (rc < 0) {
212
        printf("failed to load program\n");
236
        printf("failed to load program\n");
Line 222... Line 246...
222
 
246
 
223
    if (prog_info.interp == NULL) {
247
    if (prog_info.interp == NULL) {
224
        /* Statically linked program */
248
        /* Statically linked program */
225
//      printf("Run statically linked program\n");
249
//      printf("Run statically linked program\n");
226
//      printf("entry point: 0x%llx\n", prog_info.entry);
250
//      printf("entry point: 0x%llx\n", prog_info.entry);
-
 
251
        is_dyn_linked = false;
227
        ipc_answer_0(rid, EOK);
252
        ipc_answer_0(rid, EOK);
228
        close_console();
-
 
229
        elf_run(&prog_info, &pcb);
-
 
230
        return 0;
253
        return 0;
231
    }
254
    }
232
 
255
 
233
    printf("Load dynamic linker '%s'\n", prog_info.interp);
256
    printf("Load dynamic linker '%s'\n", prog_info.interp);
234
    rc = elf_load_file("/rtld.so", RTLD_BIAS, &interp_info);
257
    rc = elf_load_file("/rtld.so", RTLD_BIAS, &interp_info);
Line 242... Line 265...
242
     * Provide dynamic linker with some useful data
265
     * Provide dynamic linker with some useful data
243
     */
266
     */
244
    pcb.rtld_dynamic = interp_info.dynamic;
267
    pcb.rtld_dynamic = interp_info.dynamic;
245
    pcb.rtld_bias = RTLD_BIAS;
268
    pcb.rtld_bias = RTLD_BIAS;
246
 
269
 
247
    printf("run dynamic linker\n");
270
    is_dyn_linked = true;
248
    printf("entry point: 0x%llx\n", interp_info.entry);
-
 
249
    close_console();
-
 
250
 
-
 
251
    ipc_answer_0(rid, EOK);
271
    ipc_answer_0(rid, EOK);
252
    elf_run(&interp_info, &pcb);
-
 
253
 
272
 
254
    /* Not reached */
-
 
255
    return 0;
273
    return 0;
256
}
274
}
257
 
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
 
258
/** Handle loader connection.
304
/** Handle loader connection.
259
 *
305
 *
260
 * 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
261
 * to execute the loaded program).
307
 * to execute the loaded program).
262
 */
308
 */
Line 269... Line 315...
269
    /* Ignore parameters, the connection is already open */
315
    /* Ignore parameters, the connection is already open */
270
    (void)iid; (void)icall;
316
    (void)iid; (void)icall;
271
 
317
 
272
    while (1) {
318
    while (1) {
273
        callid = async_get_call(&call);
319
        callid = async_get_call(&call);
274
//      printf("received call from phone %d, method=%d\n",
-
 
275
//          call.in_phone_hash, IPC_GET_METHOD(call));
-
 
-
 
320
 
276
        switch (IPC_GET_METHOD(call)) {
321
        switch (IPC_GET_METHOD(call)) {
-
 
322
        case LOADER_GET_TASKID:
-
 
323
            loader_get_taskid(callid, &call);
-
 
324
            continue;
277
        case LOADER_SET_PATHNAME:
325
        case LOADER_SET_PATHNAME:
278
            loader_set_pathname(callid, &call);
326
            loader_set_pathname(callid, &call);
279
            continue;
327
            continue;
280
        case LOADER_SET_ARGS:
328
        case LOADER_SET_ARGS:
281
            loader_set_args(callid, &call);
329
            loader_set_args(callid, &call);
-
 
330
            continue;
-
 
331
        case LOADER_LOAD:
-
 
332
            loader_load(callid, &call);
-
 
333
            continue;
282
        case LOADER_RUN:
334
        case LOADER_RUN:
283
            loader_run(callid, &call);
335
            loader_run(callid, &call);
284
            exit(0);
-
 
285
            continue;
336
            /* Not reached */
286
        default:
337
        default:
287
            retval = ENOENT;
338
            retval = ENOENT;
288
            break;
339
            break;
289
        }
340
        }
290
        if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&
341
        if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&