X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=ginge.git;a=blobdiff_plain;f=loader%2Floader.c;h=84758c1ac8f31393ace15883ceb4150f9df3655f;hp=7e71d4d9693f6093bf642a10aa5a147d3321443c;hb=df608af11ff903836b8a2be235719511df03b025;hpb=499bf01c2f0e075caeb23714e3376a641c04eb7c diff --git a/loader/loader.c b/loader/loader.c index 7e71d4d..84758c1 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -8,10 +8,17 @@ #include #include #include +#include +#include +#include #include #include "header.h" #include "realfuncs.h" +#include "syscalls.h" + +char *bin_path; +char **g_argv; #define CHECK_(val, fail_operator, expect, err_msg) \ if (val fail_operator expect) { \ @@ -60,7 +67,7 @@ extern char **environ; int main(int argc, char *argv[]) { - void *lowest_segment = (void *)-1; + void *lowest_segments[2] = { NULL, NULL }; Elf32_Ehdr hdr; Elf32_Phdr *phdr; FILE *fi; @@ -68,12 +75,23 @@ int main(int argc, char *argv[]) int map_cnt; int i, ret, envc, sfp; long *stack_frame; + struct stat st; + char buf[64]; + long lret; if (argc < 2) { fprintf(stderr, "usage: %s [args]\n", argv[0]); return 1; } + g_argv = argv; + + lret = g_personality(-1); + if (g_syscall_error(lret) != -1) { + lret |= 0x0240000; // ADDR_COMPAT_LAYOUT | ADDR_NO_RANDOMIZE + g_personality(lret); + } + fi = fopen("/proc/self/maps", "r"); CHECK_NE(fi, NULL, "fopen maps"); @@ -150,11 +168,24 @@ int main(int argc, char *argv[]) do_patches((char *)ptr + align, phdr[i].p_filesz); } - if (map_ptr < lowest_segment) - lowest_segment = map_ptr; + if (lowest_segments[0] == NULL || map_ptr < lowest_segments[0]) + lowest_segments[0] = map_ptr; } - emu_init(lowest_segment); + // build self bin path + snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fileno(fi)); + if (lstat(buf, &st) != 0) + FAIL_PERROR("lstat bin_path"); + bin_path = malloc(st.st_size + 1); + CHECK_NE(bin_path, NULL, "bin_path"); + ret = readlink(buf, bin_path, st.st_size); + if (ret < 0) + FAIL_PERROR("readlink"); + bin_path[ret] = 0; + + fclose(fi); + + emu_init(lowest_segments, 0); // generate stack frame: argc, argv[], NULL, env[], NULL for (envc = 0; environ[envc] != NULL; envc++) @@ -166,6 +197,9 @@ int main(int argc, char *argv[]) return 1; } + // update the environment + setenv("_", bin_path, 1); + sfp = 0; stack_frame[sfp++] = argc - 1; for (i = 1; i < argc; i++)