Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3491 → Rev 3492

/branches/sparc/uspace/srv/loader/main.c
46,6 → 46,7
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <bool.h>
#include <fcntl.h>
#include <sys/types.h>
#include <ipc/ipc.h>
77,6 → 78,33
/** Buffer holding all arguments */
static char *arg_buf = NULL;
 
static elf_info_t prog_info;
static elf_info_t interp_info;
 
static bool is_dyn_linked;
 
 
static void loader_get_taskid(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
task_id_t task_id;
size_t len;
 
task_id = task_get_id();
 
if (!ipc_data_read_receive(&callid, &len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
if (len > sizeof(task_id)) len = sizeof(task_id);
 
ipc_data_read_finalize(callid, &task_id, len);
ipc_answer_0(rid, EOK);
}
 
 
/** Receive a call setting pathname of the program to execute.
*
* @param rid
191,20 → 219,16
argv[n] = NULL;
}
 
 
/** Load and run the previously selected program.
/** Load the previously selected program.
*
* @param rid
* @param request
* @return 0 on success, !0 on error.
*/
static int loader_run(ipc_callid_t rid, ipc_call_t *request)
static int loader_load(ipc_callid_t rid, ipc_call_t *request)
{
int rc;
 
elf_info_t prog_info;
elf_info_t interp_info;
 
// printf("Load program '%s'\n", pathname);
 
rc = elf_load_file(pathname, 0, &prog_info);
224,9 → 248,8
/* Statically linked program */
// printf("Run statically linked program\n");
// printf("entry point: 0x%llx\n", prog_info.entry);
is_dyn_linked = false;
ipc_answer_0(rid, EOK);
close_console();
elf_run(&prog_info, &pcb);
return 0;
}
 
244,17 → 267,40
pcb.rtld_dynamic = interp_info.dynamic;
pcb.rtld_bias = RTLD_BIAS;
 
printf("run dynamic linker\n");
printf("entry point: 0x%llx\n", interp_info.entry);
close_console();
 
is_dyn_linked = true;
ipc_answer_0(rid, EOK);
elf_run(&interp_info, &pcb);
 
/* Not reached */
return 0;
}
 
 
/** Run the previously loaded program.
*
* @param rid
* @param request
* @return 0 on success, !0 on error.
*/
static void loader_run(ipc_callid_t rid, ipc_call_t *request)
{
if (is_dyn_linked == true) {
/* Dynamically linked program */
printf("run dynamic linker\n");
printf("entry point: 0x%llx\n", interp_info.entry);
close_console();
 
ipc_answer_0(rid, EOK);
elf_run(&interp_info, &pcb);
 
} else {
/* Statically linked program */
close_console();
ipc_answer_0(rid, EOK);
elf_run(&prog_info, &pcb);
}
 
/* Not reached */
}
 
/** Handle loader connection.
*
* Receive and carry out commands (of which the last one should be
271,18 → 317,23
 
while (1) {
callid = async_get_call(&call);
// printf("received call from phone %d, method=%d\n",
// call.in_phone_hash, IPC_GET_METHOD(call));
 
switch (IPC_GET_METHOD(call)) {
case LOADER_GET_TASKID:
loader_get_taskid(callid, &call);
continue;
case LOADER_SET_PATHNAME:
loader_set_pathname(callid, &call);
continue;
case LOADER_SET_ARGS:
loader_set_args(callid, &call);
continue;
case LOADER_LOAD:
loader_load(callid, &call);
continue;
case LOADER_RUN:
loader_run(callid, &call);
exit(0);
continue;
/* Not reached */
default:
retval = ENOENT;
break;