wrap munmap to prevent unwanted unmaps
authornotaz <notasas@gmail.com>
Tue, 5 Jan 2016 01:30:08 +0000 (03:30 +0200)
committernotaz <notasas@gmail.com>
Tue, 5 Jan 2016 01:31:30 +0000 (03:31 +0200)
loader/emu.c
loader/ginge_dyn.symver
loader/header.h
loader/override.c
loader/patches.c
loader/realfuncs.h

index 8dc6d51..f14b0fc 100644 (file)
@@ -1081,7 +1081,7 @@ static void *emu_mmap_dev(unsigned int length, int prot, int flags, unsigned int
     err("warning: uppermem @ %08x overflows by %d bytes\n",
         offset, umem + length - umem_end);
 
-  dbg("upper mem @ %08x %d\n", offset, length);
+  dbg("upper mem @ %08x %x = %p\n", offset, length, umem);
   return umem;
 }
 
@@ -1101,6 +1101,19 @@ void *emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int
   return MAP_FAILED;
 }
 
+int emu_do_munmap(void *addr, unsigned int length)
+{
+  u8 *p = addr;
+
+  // don't allow to unmap upper mem
+  if ((u8 *)mmsp2.umem <= p && p < (u8 *)mmsp2.umem + 0x2000000) {
+    dbg("ignoring munmap: %p %x\n", addr, length);
+    return 0;
+  }
+
+  return -EAGAIN;
+}
+
 static void emu_sound_open(int fd)
 {
 #ifdef PND
index 20d2cd4..93b953b 100644 (file)
@@ -4,6 +4,7 @@ global:
        fopen;
        mmap;
        mmap2;
+       munmap;
        read;
        ioctl;
        sigaction;
index b5241f6..f24457f 100644 (file)
@@ -42,6 +42,7 @@ struct op_context;
 void  emu_init(void *map_bottom);
 void  emu_call_handle_op(struct op_context *op_ctx);
 void *emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int offset);
+int   emu_do_munmap(void *addr, unsigned int length);
 int   emu_do_ioctl(int fd, int request, void *argp);
 int   emu_read_gpiodev(void *buf, int count);
 void *emu_do_fopen(const char *path, const char *mode);
index 8c91644..86de405 100644 (file)
@@ -16,6 +16,7 @@
 #include <sys/ioctl.h>
 #include <signal.h>
 #include <termios.h>
+#include <errno.h>
 
 #include "realfuncs.h"
 #include "header.h"
@@ -99,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;
@@ -227,6 +240,7 @@ static int w_chdir(const char *path)
 #undef open
 #undef fopen
 #undef mmap
+#undef munmap
 #undef read
 #undef ioctl
 #undef sigaction
@@ -256,6 +270,7 @@ static int w_chdir(const char *path)
 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);
@@ -281,6 +296,7 @@ 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),
@@ -295,6 +311,7 @@ static const struct {
 #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
@@ -331,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);
index 673c3c5..5418c1c 100644 (file)
@@ -33,6 +33,13 @@ static const unsigned int sig_mmap[] = {
 };
 #define sig_mask_mmap sig_mask_all
 
+static const unsigned int sig_munmap[] = {
+  0xef90005b, // svc  0x90005b
+  0xe3700a01, // cmn  r0, #0x1000
+  0x312fff1e, // bxcc lr
+};
+#define sig_mask_munmap sig_mask_all
+
 static const unsigned int sig_mmap2[] = {
   0xe52d5004, // push {r5}
   0xe59d5008, // ldr  r5, [sp, #8]
@@ -132,6 +139,7 @@ static const struct {
   PATCH(open),
   PATCH(mmap),
   PATCH(mmap2), // mmap2 syscall
+  PATCH(munmap),
   PATCH(read),
   PATCH(ioctl),
   PATCH_(hw_ioctl, hw_ioctl, 1),
index 43d2ddf..8a4fb58 100644 (file)
@@ -13,6 +13,7 @@
 int   real_open(const char *pathname, int flags, ...);
 FILE *real_fopen(const char *path, const char *mode);
 void *real_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
+int   real_munmap(void *addr, size_t length);
 int   real_read(int fd, void *buf, size_t count);
 int   real_ioctl(int fd, int request, void *argp);
 int   real_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
@@ -27,6 +28,7 @@ int   real_chdir(const char *path);
 #define open real_open
 #define fopen real_fopen
 #define mmap real_mmap
+#define munmap real_munmap
 #define read real_read
 #define ioctl real_ioctl
 #define sigaction real_sigaction