wrap munmap to prevent unwanted unmaps
[ginge.git] / loader / override.c
index 42b52ab..86de405 100644 (file)
@@ -1,4 +1,9 @@
-// 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 <stdarg.h>
@@ -11,6 +16,7 @@
 #include <sys/ioctl.h>
 #include <signal.h>
 #include <termios.h>
+#include <errno.h>
 
 #include "realfuncs.h"
 #include "header.h"
@@ -31,8 +37,11 @@ static const struct dev_fd_t takeover_devs[] = {
   { "/dev/fb1",     FAKEDEV_FB1 },
   { "/dev/fb/1",    FAKEDEV_FB1 },
   { "/dev/mmuhack", FAKEDEV_MMUHACK },
-  { "/dev/tty",     -1 }, // XXX hmh..
+  { "/dev/tty",     FAKEDEV_TTY0 },
   { "/dev/tty0",    FAKEDEV_TTY0 },
+#ifdef PND
+  { "/dev/input/event*", -1 }, // hide for now, may cause dupe events
+#endif
 };
 
 static int w_open(const char *pathname, int flags, mode_t mode)
@@ -40,7 +49,17 @@ static int w_open(const char *pathname, int flags, mode_t mode)
   int i, ret;
 
   for (i = 0; i < ARRAY_SIZE(takeover_devs); i++) {
-    if (strcmp(pathname, takeover_devs[i].name) == 0) {
+    const char *p, *oname;
+    int len;
+
+    oname = takeover_devs[i].name;
+    p = strchr(oname, '*');
+    if (p != NULL)
+      len = p - oname;
+    else
+      len = strlen(oname) + 1;
+
+    if (strncmp(pathname, oname, len) == 0) {
       ret = takeover_devs[i].fd;
       break;
     }
@@ -51,8 +70,11 @@ static int w_open(const char *pathname, int flags, mode_t mode)
 
   if (ret >= 0) {
     for (i = 0; emu_interesting_fds[i].name != NULL; i++) {
-      if (strcmp(pathname, emu_interesting_fds[i].name) == 0) {
-        emu_interesting_fds[i].fd = ret;
+      struct dev_fd_t *eifd = &emu_interesting_fds[i];
+      if (strcmp(pathname, eifd->name) == 0) {
+        eifd->fd = ret;
+        if (eifd->open_cb != NULL)
+          eifd->open_cb(ret);
         break;
       }
     }
@@ -78,6 +100,18 @@ static void *w_mmap(void *addr, size_t length, int prot, int flags, int fd, off_
 }
 #define w_mmap2 w_mmap
 
+static int w_munmap(void *addr, size_t length)
+{
+  int ret;
+  ret = emu_do_munmap(addr, length);
+  if (ret == -EAGAIN)
+    ret = munmap(addr, length);
+
+  if (((long)&ret & 0xf0000000) == 0xb0000000)
+    strace("munmap(%p, %x) = %d\n", addr, length, ret);
+  return ret;
+}
+
 static ssize_t w_read(int fd, void *buf, size_t count)
 {
   ssize_t ret;
@@ -150,21 +184,85 @@ static UNUSED int w_system(const char *command)
   return ret;
 }
 
+extern char **environ;
+
+static UNUSED int w_execl(const char *path, const char *arg, ...)
+{
+  // don't allow exec (for now)
+  strace("execl(%s, %s, ...) = ?\n", path, arg);
+  exit(1);
+}
+
+static UNUSED int w_execlp(const char *file, const char *arg, ...)
+{
+  strace("execlp(%s, %s, ...) = ?\n", file, arg);
+  exit(1);
+}
+
+static UNUSED int w_execle(const char *path, const char *arg, ...)
+{
+  strace("execle(%s, %s, ...) = ?\n", path, arg);
+  exit(1);
+}
+
+static UNUSED int w_execv(const char *path, char *const argv[])
+{
+  strace("execv(%s, %p) = ?\n", path, argv);
+  return emu_do_execve(path, argv, environ);
+}
+
+static UNUSED int w_execvp(const char *file, char *const argv[])
+{
+  strace("execvp(%s, %p) = ?\n", file, argv);
+  return emu_do_execve(file, argv, environ);
+}
+
+// static note: this can't safely return because of the way it's patched in
+// static note2: can't be used, execve hangs?
+static UNUSED int w_execve(const char *filename, char *const argv[],
+                  char *const envp[])
+{
+  strace("execve(%s, %p, %p) = ?\n", filename, argv, envp);
+  return emu_do_execve(filename, argv, envp);
+}
+
+static int w_chdir(const char *path)
+{
+  int ret;
+  if (path != NULL && strstr(path, "/usr/gp2x") != NULL)
+    ret = 0;
+  else
+    ret = chdir(path);
+  strace("chdir(%s) = %d\n", path, ret);
+  return ret;
+}
+
 #undef open
 #undef fopen
 #undef mmap
+#undef munmap
 #undef read
 #undef ioctl
 #undef sigaction
 #undef tcgetattr
 #undef tcsetattr
 #undef system
+#undef execl
+#undef execlp
+#undef execle
+#undef execv
+#undef execvp
+#undef execve
+#undef chdir
 
 #ifdef DL
 
-#define MAKE_WRAP_SYM(sym) \
+#define MAKE_WRAP_SYM_N(sym) \
   /* alias wrap symbols to real names */ \
-  typeof(sym) sym __attribute__((alias("w_" #sym))); \
+  typeof(sym) sym __attribute__((alias("w_" #sym)))
+
+#define MAKE_WRAP_SYM(sym) \
+  MAKE_WRAP_SYM_N(sym); \
   /* wrapper to real functions, to be set up on load */ \
   static typeof(sym) *p_real_##sym
 
@@ -172,12 +270,20 @@ static UNUSED int w_system(const char *command)
 MAKE_WRAP_SYM(open);
 MAKE_WRAP_SYM(fopen);
 MAKE_WRAP_SYM(mmap);
+MAKE_WRAP_SYM(munmap);
 MAKE_WRAP_SYM(read);
 MAKE_WRAP_SYM(ioctl);
 MAKE_WRAP_SYM(sigaction);
 MAKE_WRAP_SYM(tcgetattr);
 MAKE_WRAP_SYM(tcsetattr);
 MAKE_WRAP_SYM(system);
+MAKE_WRAP_SYM_N(execl);
+MAKE_WRAP_SYM_N(execlp);
+MAKE_WRAP_SYM_N(execle);
+MAKE_WRAP_SYM_N(execv);
+MAKE_WRAP_SYM_N(execvp);
+MAKE_WRAP_SYM(execve);
+MAKE_WRAP_SYM(chdir);
 typeof(mmap) mmap2 __attribute__((alias("w_mmap")));
 
 #define REAL_FUNC_NP(name) \
@@ -190,23 +296,30 @@ static const struct {
   REAL_FUNC_NP(open),
   REAL_FUNC_NP(fopen),
   REAL_FUNC_NP(mmap),
+  REAL_FUNC_NP(munmap),
   REAL_FUNC_NP(read),
   REAL_FUNC_NP(ioctl),
   REAL_FUNC_NP(sigaction),
   REAL_FUNC_NP(tcgetattr),
   REAL_FUNC_NP(tcsetattr),
   REAL_FUNC_NP(system),
+  // exec* - skipped
+  REAL_FUNC_NP(execve),
+  REAL_FUNC_NP(chdir),
 };
 
 #define open p_real_open
 #define fopen p_real_fopen
 #define mmap p_real_mmap
+#define munmap p_real_munmap
 #define read p_real_read
 #define ioctl p_real_ioctl
 #define sigaction p_real_sigaction
 #define tcgetattr p_real_tcgetattr
 #define tcsetattr p_real_tcsetattr
 #define system p_real_system
+#define execve p_real_execve
+#define chdir p_real_chdir
 
 #undef MAKE_WRAP_SYM
 #undef REAL_FUNC_NP
@@ -235,6 +348,11 @@ void *real_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t of
   return mmap(addr, length, prot, flags, fd, offset);
 }
 
+int real_munmap(void *addr, size_t length)
+{
+  return munmap(addr, length);
+}
+
 int real_read(int fd, void *buf, size_t count)
 {
   return read(fd, buf, count);
@@ -265,3 +383,18 @@ int real_system(const char *command)
 {
   return system(command);
 }
+
+// real_exec* is missing intentionally - we don't need them
+
+int real_execve(const char *filename, char *const argv[],
+                  char *const envp[])
+{
+  return execve(filename, argv, envp);
+}
+
+int real_chdir(const char *path)
+{
+  return chdir(path);
+}
+
+// vim:shiftwidth=2:expandtab