Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3003 → Rev 3004

/branches/dynload/uspace/app/iloader/interp.s
0,0 → 1,7
#
# Provide a string to be included in a special DT_INTERP header, even though
# this is a statically-linked executable. This will mark te binary as
# the program loader.
#
.section .interp , ""
.string "kernel"
/branches/dynload/uspace/app/iloader/include/elf_load.h
48,8 → 48,11
/** Entry point */
entry_point_t entry;
 
/** ELF interpreter name or NULL if statically-linked */
char *interp;
 
/** Pointer to the dynamic section */
void *dynamic;
void *dynamic;
} elf_info_t;
 
/**
/branches/dynload/uspace/app/iloader/main.c
35,9 → 35,12
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <ipc/ipc.h>
#include <errno.h>
#include <as.h>
 
#include <elf.h>
46,21 → 49,54
 
#define RTLD_BIAS 0x80000
 
int main(int argc, char *argv[])
static char *pathname = NULL;
 
void iloader_set_pathname(ipc_callid_t rid, ipc_call_t *request)
{
// ipc_callid_t callid;
size_t len;
char *name_buf;
 
/* printf("iloader_set_pathname\n");
if (!ipc_data_write_receive(&callid, &len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
*/
len = IPC_GET_ARG2(*request);
printf("alloc %d bytes\n", len+1);
 
name_buf = malloc(len + 1);
if (!name_buf) {
// ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
 
printf("write_finalize\n");
ipc_data_write_finalize(rid, name_buf, len);
// ipc_answer_0(rid, EOK);
 
if (pathname != NULL) {
free(pathname);
pathname = NULL;
}
 
pathname = name_buf;
}
 
int iloader_run(ipc_callid_t rid, ipc_call_t *request)
{
int rc;
pcb_t *pcb;
 
elf_info_t prog_info;
elf_info_t interp_info;
char *file_name;
pcb_t *pcb;
int rc;
 
printf("This is loader\n");
getchar();
printf("Load program '%s'\n", pathname);
 
printf("Load program\n");
 
rc = elf_load_file("/dltest", 0, &prog_info);
// rc = elf_load_file("/tetris", 0, &prog_info);
rc = elf_load_file(pathname, 0, &prog_info);
if (rc < 0) {
printf("failed to load program\n");
return 1;
69,14 → 105,15
printf("Create PCB\n");
if (elf_create_pcb(&prog_info) < 0) return 1;
 
// elf_run(&prog_info);
if (prog_info.interp == NULL) {
/* Statically linked program */
printf("Run statically linked program\n");
elf_run(&prog_info);
return 0;
}
 
// getchar();
 
printf("Load dynamic linker\n");
file_name = "/rtld.so";
printf("open and read '%s'...\n", file_name);
rc = elf_load_file(file_name, RTLD_BIAS, &interp_info);
printf("Load dynamic linker '%s'\n", prog_info.interp);
rc = elf_load_file("/rtld.so", RTLD_BIAS, &interp_info);
if (rc < 0) {
printf("failed to load dynamic linker\n");
return 1;
83,7 → 120,7
}
 
/*
* Provide rtld with some useful data
* Provide dynamic linker with some useful data
*/
pcb = (pcb_t *)PCB_ADDRESS;
pcb->rtld_dynamic = interp_info.dynamic;
92,6 → 129,35
printf("run dynamic linker\n");
elf_run(&interp_info);
 
return 0;
}
 
int main(int argc, char *argv[])
{
ipc_callid_t callid;
ipc_call_t call;
int retval;
int len;
 
while (1) {
callid = ipc_wait_for_call(&call);
printf("received call, method=%d\n", IPC_GET_METHOD(call));
switch (IPC_GET_METHOD(call)) {
case IPC_M_DATA_WRITE:
iloader_set_pathname(callid, &call);
iloader_run(callid, &call);
exit(0);
continue;
default:
retval = ENOENT;
break;
}
if ((callid & IPC_CALLID_NOTIFICATION) == 0) {
printf("responding EINVAL to method %d\n", IPC_GET_METHOD(call));
ipc_answer_0(callid, EINVAL);
}
}
 
/* not reached */
return 0;
}
/branches/dynload/uspace/app/iloader/elf_load.c
181,6 → 181,8
elf->bias = 0;
 
printf("Bias set to 0x%x\n", elf->bias);
elf->info->interp = NULL;
elf->info->dynamic = NULL;
 
printf("parse segments\n");
 
201,7 → 203,6
}
 
printf("parse sections\n");
elf->info->dynamic = NULL;
 
/* Inspect all section headers and proccess them. */
for (i = 0; i < header->e_shnum; i++) {
256,8 → 257,11
case PT_LOAD:
return load_segment(elf, entry);
break;
case PT_INTERP:
/* Assume silently interp == "/rtld.so" */
elf->info->interp = "/rtld.so";
break;
case PT_DYNAMIC:
case PT_INTERP:
case PT_SHLIB:
case PT_NOTE:
case PT_LOPROC:
/branches/dynload/uspace/app/iloader/Makefile
40,7 → 40,7
 
CFLAGS += -Iinclude -D__32_BITS__
 
LIBS = $(LIBC_PREFIX)/libc.a
LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a
DEFS += -DRELEASE=\"$(RELEASE)\"
 
ifdef REVISION
57,7 → 57,8
OUTPUT = iloader
SOURCES = \
main.c \
elf_load.c
elf_load.c \
interp.s
 
OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
 
78,7 → 79,7
 
$(OUTPUT): $(OBJECTS) $(LIBS) arch/$(ARCH)/_link.ld
# $(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(OBJECTS) $(LIBS) -o $@ -Map $(OUTPUT).map
 
disasm:
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
/branches/dynload/uspace/app/iloader/arch/ia32/_link.ld.in
1,16 → 1,21
/*
* The only difference from _link.ld.in for regular statically-linked apps
* is the base address.
* The difference from _link.ld.in for regular statically-linked apps
* is the base address and the special interp section.
*/
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
ENTRY(__entry)
 
PHDRS {
text PT_LOAD FLAGS(5);
interp PT_INTERP;
text PT_LOAD FILEHDR PHDRS FLAGS(5);
data PT_LOAD FLAGS(6);
}
 
SECTIONS {
.interp : {
*(.interp);
} : interp
 
. = 0x70001000;
 
.init ALIGN(0x1000) : SUBALIGN(0x1000) {