-// 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;
+char **g_argv;
+
#define CHECK_(val, fail_operator, expect, err_msg) \
if (val fail_operator expect) { \
fprintf(stderr, err_msg ", exiting (%d)\n", (int)(long)val); \
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;
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;
}
+ g_argv = argv;
+
fi = fopen("/proc/self/maps", "r");
CHECK_NE(fi, NULL, "fopen maps");
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++)
return 1;
}
+ // update the environment
+ setenv("_", bin_path, 1);
+
sfp = 0;
stack_frame[sfp++] = argc - 1;
for (i = 1; i < argc; i++)
return 1;
}
+// vim:shiftwidth=2:expandtab