do yet more path wrapping
authornotaz <notasas@gmail.com>
Tue, 12 Jan 2016 01:48:50 +0000 (03:48 +0200)
committernotaz <notasas@gmail.com>
Tue, 12 Jan 2016 01:48:50 +0000 (03:48 +0200)
loader/emu.c
loader/header.h
loader/override.c
loader/patches.c
loader/syscalls.S
loader/syscalls.h

index 5adcc5d..77f9a6d 100644 (file)
@@ -1319,13 +1319,15 @@ static const struct {
   const char *to;
 } path_map[] = {
   { "/mnt/tmp", "./tmp" },
+  { "/mnt/sd", "./mntsd" },
 };
 
-static const char *wrap_path(const char *path)
+const char *emu_wrap_path(const char *path)
 {
   char *buff, *p;
   size_t size;
   int i, len;
+  long ret;
 
   // do only path mapping for now
   for (i = 0; i < ARRAY_SIZE(path_map); i++) {
@@ -1340,6 +1342,11 @@ static const char *wrap_path(const char *path)
       snprintf(buff + len, size - len, "%s%s", path_map[i].to,
         path + len + strlen(path_map[i].from));
       dbg("mapped path \"%s\" -> \"%s\"\n", path, buff);
+
+      ret = g_mkdir_raw(path_map[i].to, 0666);
+      if (ret != 0 && ret != -EEXIST)
+        err("mkdir(%s): %ld\n", path_map[i].to, ret);
+
       return buff;
     }
   }
@@ -1347,7 +1354,7 @@ static const char *wrap_path(const char *path)
   return path;
 }
 
-static void wrap_path_free(const char *w_path, const char *old_path)
+void emu_wrap_path_free(const char *w_path, const char *old_path)
 {
   if (w_path != old_path)
     free((void *)w_path);
@@ -1358,9 +1365,9 @@ void *emu_do_fopen(const char *path, const char *mode)
   const char *w_path;
   FILE *ret;
 
-  w_path = wrap_path(path);
+  w_path = emu_wrap_path(path);
   ret = fopen(w_path, mode);
-  wrap_path_free(w_path, path);
+  emu_wrap_path_free(w_path, path);
 
   return ret;
 }
@@ -1387,7 +1394,7 @@ int emu_do_system(const char *command)
     // absolute path, but not a system command
     need_ginge = 1;
 
-  p2 = wrap_path(command);
+  p2 = emu_wrap_path(command);
   if (need_ginge) {
     make_local_path(tmp_path, sizeof(tmp_path), "ginge_prep");
     p = tmp_path + strlen(tmp_path);
@@ -1396,7 +1403,7 @@ int emu_do_system(const char *command)
   }
   else
     snprintf(tmp_path, sizeof(tmp_path), "%s", p2);
-  wrap_path_free(p2, command);
+  emu_wrap_path_free(p2, command);
 
   dbg("system: \"%s\"\n", tmp_path);
 
@@ -1436,7 +1443,7 @@ long emu_do_execve(const char *filename, char * const argv[],
   make_local_path(prep_path, 512, "ginge_prep");
   new_argv[0] = prep_path;
   new_argv[1] = "--nomenu";
-  new_argv[2] = wrap_path(filename);
+  new_argv[2] = emu_wrap_path(filename);
 
   if (argv[0] != NULL)
     for (i = 1; argv[i] != NULL; i++)
index 7bff116..29841ea 100644 (file)
@@ -52,6 +52,8 @@ long  emu_do_read(int fd, void *buf, int count);
 void *emu_do_fopen(const char *path, const char *mode);
 int   emu_do_system(const char *command);
 long  emu_do_execve(const char *filename, char *const argv[], char *const envp[]);
+const char *emu_wrap_path(const char *path);
+void  emu_wrap_path_free(const char *w_path, const char *old_path);
 
 int   host_init(void);
 int   host_read_btns(void);
index 3d0d0cc..f98a4db 100644 (file)
@@ -48,7 +48,7 @@ static const struct dev_fd_t takeover_devs[] = {
 #endif
 };
 
-static long w_open_raw(const char *pathname, int flags, mode_t mode)
+long w_open_raw(const char *pathname, int flags, mode_t mode)
 {
   long ret;
   int i;
@@ -70,8 +70,11 @@ static long w_open_raw(const char *pathname, int flags, mode_t mode)
     }
   }
 
-  if (i == ARRAY_SIZE(takeover_devs))
-    ret = g_open_raw(pathname, flags, mode);
+  if (i == ARRAY_SIZE(takeover_devs)) {
+    const char *w_path = emu_wrap_path(pathname);
+    ret = g_open_raw(w_path, flags, mode);
+    emu_wrap_path_free(w_path, pathname);
+  }
 
   if (ret >= 0) {
     for (i = 0; emu_interesting_fds[i].name != NULL; i++) {
index d272b56..901de51 100644 (file)
@@ -31,6 +31,13 @@ static const unsigned int sig_open_a1[] = {
 };
 #define sig_mask_open_a1 sig_mask_all
 
+static const unsigned int sig_hw_open[] = {
+  0xef900005, // svc  0x900005
+  0xe3700a01, // cmn  r0, #0x1000
+  0xe1a04000, // mov  r4, r0
+};
+#define sig_mask_hw_open sig_mask_all
+
 static const unsigned int sig_mmap[] = {
   0xe92d000f, // push {r0, r1, r2, r3}
   0xe1a0000d, // mov  r0, sp
@@ -170,6 +177,7 @@ asm( \
 "  ldmfd sp!, {r1-r3,r12,lr,pc}\n" \
 );
 
+SVC_CMN_R0_MOV_R4_WRAPPER(hw_open, w_open_raw)
 SVC_CMN_R0_MOV_R4_WRAPPER(hw_read, w_read_raw)
 SVC_CMN_R0_MOV_R4_WRAPPER(hw_ioctl, w_ioctl_raw)
 SVC_CMN_R0_MOV_R4_WRAPPER(hw_execve, w_execve_raw)
@@ -187,6 +195,7 @@ static const struct {
 } patches[] = {
   PATCH (open),
   PATCH_(open_a1, w_open, 0),
+  PATCH_(hw_open, hw_open, 1),
   PATCH (mmap),
   PATCH (mmap2), // mmap2 syscall
   PATCH (munmap),
index 6d48fbd..d478582 100644 (file)
@@ -96,6 +96,7 @@ raw_syscall_easy g_munmap_raw,         __NR_munmap
 raw_syscall_easy g_ioctl_raw,          __NR_ioctl
 raw_syscall_easy g_close_raw,          __NR_close
 raw_syscall_easy g_chdir_raw,          __NR_chdir
+raw_syscall_easy g_mkdir_raw,          __NR_mkdir
 raw_syscall_easy g_futex_raw,          __NR_futex
 raw_syscall_easy g_nanosleep_raw,      __NR_nanosleep
 raw_syscall_easy g_readlink_raw,       __NR_readlink
index 3dfc44a..9978532 100644 (file)
@@ -21,6 +21,7 @@ long g_munmap_raw(void *addr, size_t length);
 long g_ioctl_raw(int fd, unsigned long request, ...);
 long g_close_raw(int fd);
 long g_chdir_raw(const char *path);
+long g_mkdir_raw(const char *pathname, unsigned int mode);
 long g_futex_raw(int *uaddr, int op, int val,
                  const struct timespec *timeout);
 long g_nanosleep_raw(const struct timespec *req, struct timespec *rem);