-// vim:shiftwidth=2:expandtab
+/*
+ * GINGE - GINGE Is Not Gp2x Emulator
+ * (C) notaz, 2010-2011
+ *
+ * This work is licensed under the MAME license, see COPYING file for details.
+ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <elf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <sys/mman.h>
#include "header.h"
#include "realfuncs.h"
+char *bin_path;
+
#define CHECK_(val, fail_operator, expect, err_msg) \
if (val fail_operator expect) { \
fprintf(stderr, err_msg ", exiting (%d)\n", (int)(long)val); \
int map_cnt;
int i, ret, envc, sfp;
long *stack_frame;
+ struct stat st;
+ char buf[64];
if (argc < 2) {
fprintf(stderr, "usage: %s <program> [args]\n", argv[0]);
return 1;
}
- printf("load %d %08x-%08x from %08x\n", phdr[i].p_type,
+ log("load %d %08x-%08x from %08x\n", phdr[i].p_type,
phdr[i].p_vaddr, end_addr, phdr[i].p_offset);
align = phdr[i].p_vaddr & 0xfff;
lowest_segment = map_ptr;
}
+ // 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_segment);
// generate stack frame: argc, argv[], NULL, env[], NULL
return 1;
}
+ // update the environment
+ setenv("_", bin_path, 1);
+
sfp = 0;
stack_frame[sfp++] = argc - 1;
for (i = 1; i < argc; i++)
stack_frame[sfp++] = (long)environ[i];
stack_frame[sfp++] = 0;
- printf("entering %08x, %d stack entries\n", hdr.e_entry, sfp);
+ log("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;
}
+// vim:shiftwidth=2:expandtab