From 306e06f738dc1b1585c7db7c0e7bc36e2ba90f13 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 13 Jul 2010 15:46:42 +0300 Subject: [PATCH] allow arguments and fix environment handling --- loader/loader.c | 40 +++++++++++++++++++++++++++------------- loader/loader_arm.s | 13 ++++++++++++- loader/tools/static.c | 13 +++++++++++-- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/loader/loader.c b/loader/loader.c index 530eed3..df50542 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -60,11 +60,11 @@ int main(int argc, char *argv[]) FILE *fi; maps_range maps[16]; int map_cnt; - int i, ret; - long stack_frame[5]; + int i, ret, envc, sfp; + long *stack_frame; - if (argc != 2) { - fprintf(stderr, "usage: %s \n", argv[0]); + if (argc < 2) { + fprintf(stderr, "usage: %s [args]\n", argv[0]); return 1; } @@ -95,7 +95,7 @@ int main(int argc, char *argv[]) } HDR_CHECK_EQ(e_type, ET_EXEC, "not executable"); -// HDR_CHECK_EQ(e_machine, EM_ARM, "not ARM"); + HDR_CHECK_EQ(e_machine, EM_ARM, "not ARM"); HDR_CHECK_EQ(e_phentsize, sizeof(Elf32_Phdr), "bad PH entry size"); HDR_CHECK_NE(e_phnum, 0, "no PH entries"); @@ -150,15 +150,29 @@ int main(int argc, char *argv[]) emu_init(lowest_segment); - stack_frame[0] = 1; // argc - stack_frame[1] = (long)argv[1]; - stack_frame[2] = 0; - stack_frame[3] = (long)environ; - stack_frame[4] = 0; + // generate stack frame: argc, argv[], NULL, env[], NULL + for (envc = 0; environ[envc] != NULL; envc++) + ; - printf("entering %08x\n", hdr.e_entry); - do_entry(hdr.e_entry, stack_frame, 5, NULL); + stack_frame = calloc(argc + envc + 3, sizeof(stack_frame[0])); + if (stack_frame == NULL) { + fprintf(stderr, "stack_frame OOM\n"); + return 1; + } - return 0; + sfp = 0; + stack_frame[sfp++] = argc - 1; + for (i = 1; i < argc; i++) + stack_frame[sfp++] = (long)argv[i]; + stack_frame[sfp++] = 0; + for (i = 0; i < envc; i++) + stack_frame[sfp++] = (long)environ[i]; + stack_frame[sfp++] = 0; + + printf("entering %08x, %d stack entries\n", hdr.e_entry, sfp); + do_entry(hdr.e_entry, stack_frame, sfp, NULL); + + fprintf(stderr, "do_entry failed!\n"); + return 1; } diff --git a/loader/loader_arm.s b/loader/loader_arm.s index eec1c75..1e5912c 100644 --- a/loader/loader_arm.s +++ b/loader/loader_arm.s @@ -1,6 +1,6 @@ .text -/* void do_entry(Elf32_Addr entry, void *stack_frame, int stack_frame_size, void *exitf); */ +/* void do_entry(Elf32_Addr entry, void *stack_frame, int stack_frame_elems, void *exitf); */ .globl do_entry do_entry: @@ -13,5 +13,16 @@ do_entry: str r0, [r4], #4 bgt 0b +/* + r0 - atexit func + sp - stack frame of: + argc + argv[0] + ... + NULL + envp[0] + ... + NULL +*/ mov r0, r3 bx r5 diff --git a/loader/tools/static.c b/loader/tools/static.c index 50a35c9..edf7139 100644 --- a/loader/tools/static.c +++ b/loader/tools/static.c @@ -1,18 +1,27 @@ #include +#include #include #include #include #include -int main() +int main(int argc, char *argv[]) { volatile void *memregs; int memdev; int i; - printf("hi\n"); + printf("hi, home=%s\n", getenv("HOME")); + + for (i = 0; i < argc; i++) + printf("%d \"%s\"\n", i, argv[i]); memdev = open("/dev/mem", O_RDWR); + if (memdev < 0) { + perror("open"); + return 1; + } + memregs = mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000); for (i = 0; i < 2; i++) -- 2.39.5