-// 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/mman.h>
+#include "header.h"
+#include "realfuncs.h"
+
#define CHECK_(val, fail_operator, expect, err_msg) \
if (val fail_operator expect) { \
fprintf(stderr, err_msg ", exiting (%d)\n", (int)(long)val); \
return 1; \
}
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-
typedef struct {
unsigned long start;
unsigned long end;
}
extern char **environ;
-extern void do_entry(Elf32_Addr entry, void *stack_frame, int stack_frame_size, void *exitf);
int main(int argc, char *argv[])
{
+ void *lowest_segment = (void *)-1;
Elf32_Ehdr hdr;
Elf32_Phdr *phdr;
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 <program>\n", argv[0]);
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s <program> [args]\n", argv[0]);
return 1;
}
for (i = 0; i < ARRAY_SIZE(maps); i++) {
ret = fscanf(fi, "%lx-%lx %*s %*s %*s %*s %*s\n", &maps[i].start, &maps[i].end);
- if (ret == 0)
+ if (ret <= 0)
break;
CHECK_EQ(ret, 2, "maps parse error");
}
}
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");
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;
FAIL_PERROR("fseek");
if (fread((char *)ptr + align, 1, phdr[i].p_filesz, fi) != phdr[i].p_filesz)
FAIL_PERROR("too small or");
+
+ if (phdr[i].p_flags & PF_X)
+ do_patches((char *)ptr + align, phdr[i].p_filesz);
}
+
+ if (map_ptr < lowest_segment)
+ lowest_segment = map_ptr;
}
- stack_frame[0] = 1; // argc
- stack_frame[1] = (long)argv[1];
- stack_frame[2] = 0;
- stack_frame[3] = (long)environ;
- stack_frame[4] = 0;
+ emu_init(lowest_segment);
- printf("entering %08x\n", hdr.e_entry);
- do_entry(hdr.e_entry, stack_frame, 5, NULL);
+ // generate stack frame: argc, argv[], NULL, env[], NULL
+ for (envc = 0; environ[envc] != NULL; envc++)
+ ;
- return 0;
+ stack_frame = calloc(argc + envc + 3, sizeof(stack_frame[0]));
+ if (stack_frame == NULL) {
+ fprintf(stderr, "stack_frame OOM\n");
+ return 1;
+ }
+
+ 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;
+
+ 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