try to handle exec-gp2xmenu exit
authornotaz <notasas@gmail.com>
Sun, 10 Jan 2016 01:13:07 +0000 (03:13 +0200)
committernotaz <notasas@gmail.com>
Sun, 10 Jan 2016 01:13:07 +0000 (03:13 +0200)
loader/emu.c
loader/header.h
loader/host.c
loader/host_pnd.c
loader/host_wiz.c
loader/loader.c
loader/override.c
loader/patches.c
loader/syscalls.S
loader/syscalls.h

index 313bd06..38fea46 100644 (file)
@@ -1371,17 +1371,19 @@ int emu_do_system(const char *command)
   return ret;
 }
 
   return ret;
 }
 
-int emu_do_execve(const char *filename, char *const argv[], char *const envp[])
+long emu_do_execve(const char *filename, char * const argv[],
+                   char * const envp[])
 {
   const char **new_argv;
   char *prep_path;
 {
   const char **new_argv;
   char *prep_path;
-  int i, ret, argc;
+  int i, argc;
+  long ret;
 
   if (filename == NULL)
     return -1;
 
 
   if (filename == NULL)
     return -1;
 
-  if (strstr(filename, "/gp2xmenu") != NULL)
-    exit(0);
+  if (strstr(filename, "gp2xmenu") != NULL)
+    host_forced_exit(0);
 
   for (i = 0; argv[i] != NULL; i++)
     ;
 
   for (i = 0; argv[i] != NULL; i++)
     ;
@@ -1406,7 +1408,7 @@ int emu_do_execve(const char *filename, char *const argv[], char *const envp[])
 
   dbg("execve \"%s\" %s \"%s\"\n", new_argv[0], new_argv[1], new_argv[2]);
   ret = execve(new_argv[0], (char **)new_argv, envp);
 
   dbg("execve \"%s\" %s \"%s\"\n", new_argv[0], new_argv[1], new_argv[2]);
   ret = execve(new_argv[0], (char **)new_argv, envp);
-  perror("execve");
+  err("execve(%s): %ld\n", new_argv[0], ret);
   return ret;
 }
 
   return ret;
 }
 
index ec4a495..0641878 100644 (file)
@@ -49,11 +49,11 @@ long  emu_do_ioctl(int fd, int request, void *argp);
 long  emu_read_gpiodev(void *buf, int count);
 void *emu_do_fopen(const char *path, const char *mode);
 int   emu_do_system(const char *command);
 long  emu_read_gpiodev(void *buf, int count);
 void *emu_do_fopen(const char *path, const char *mode);
 int   emu_do_system(const char *command);
-int   emu_do_execve(const char *filename, char *const argv[], char *const envp[]);
+long  emu_do_execve(const char *filename, char *const argv[], char *const envp[]);
 
 int   host_init(void);
 int   host_read_btns(void);
 
 int   host_init(void);
 int   host_read_btns(void);
-void  host_forced_exit(void);
+void  host_forced_exit(int status);
 
 enum  { GP2X_UP = 0,      GP2X_LEFT = 2,      GP2X_DOWN = 4,  GP2X_RIGHT = 6,
         GP2X_START = 8,   GP2X_SELECT = 9,    GP2X_L = 10,    GP2X_R = 11,
 
 enum  { GP2X_UP = 0,      GP2X_LEFT = 2,      GP2X_DOWN = 4,  GP2X_RIGHT = 6,
         GP2X_START = 8,   GP2X_SELECT = 9,    GP2X_L = 10,    GP2X_R = 11,
@@ -61,6 +61,7 @@ enum  { GP2X_UP = 0,      GP2X_LEFT = 2,      GP2X_DOWN = 4,  GP2X_RIGHT = 6,
         GP2X_VOL_UP = 16, GP2X_VOL_DOWN = 17, GP2X_PUSH = 18 };
 
 extern char *bin_path;
         GP2X_VOL_UP = 16, GP2X_VOL_DOWN = 17, GP2X_PUSH = 18 };
 
 extern char *bin_path;
+extern char **g_argv;
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 
index 7df4f10..a6c2856 100644 (file)
@@ -26,9 +26,6 @@
 #include "host_wiz.c"
 #endif
 
 #include "host_wiz.c"
 #endif
 
-// for plat.c
-char **g_argv;
-
 int host_init(void)
 {
   in_init();
 int host_init(void)
 {
   in_init();
@@ -48,7 +45,7 @@ int host_read_btns(void)
   return actions[IN_BINDTYPE_PLAYER12];
 }
 
   return actions[IN_BINDTYPE_PLAYER12];
 }
 
-void host_forced_exit(void)
+void host_forced_exit(int status)
 {
   // exit() might not be enough because loader and app data is out of sync,
   // and other threads (which are really processes on this old glibc used)
 {
   // exit() might not be enough because loader and app data is out of sync,
   // and other threads (which are really processes on this old glibc used)
@@ -62,7 +59,7 @@ void host_forced_exit(void)
   usleep(300000);
   snprintf(cmd, sizeof(cmd), "killall -9 %s", g_argv[0]);
   system(cmd);
   usleep(300000);
   snprintf(cmd, sizeof(cmd), "killall -9 %s", g_argv[0]);
   system(cmd);
-  exit(1);
+  exit(status);
 }
 
 // vim:shiftwidth=2:expandtab
 }
 
 // vim:shiftwidth=2:expandtab
index 86e9910..83a0888 100644 (file)
@@ -32,7 +32,7 @@ static const struct in_pdata pandora_evdev_pdata = {
 static void host_actions(int actions[IN_BINDTYPE_COUNT])
 {
   if (actions[IN_BINDTYPE_EMU] & 1)
 static void host_actions(int actions[IN_BINDTYPE_COUNT])
 {
   if (actions[IN_BINDTYPE_EMU] & 1)
-    host_forced_exit();
+    host_forced_exit(1);
 }
 
 static void host_init_input(void)
 }
 
 static void host_init_input(void)
index 7763f35..3e08fe6 100644 (file)
@@ -133,7 +133,7 @@ static void host_actions(int actions[IN_BINDTYPE_COUNT])
       act |=   1 << GP2X_VOL_DOWN;
     }
     if (act & (1 << GP2X_Y))
       act |=   1 << GP2X_VOL_DOWN;
     }
     if (act & (1 << GP2X_Y))
-      host_forced_exit();
+      host_forced_exit(1);
     actions[IN_BINDTYPE_PLAYER12] = act;
   }
 }
     actions[IN_BINDTYPE_PLAYER12] = act;
   }
 }
index 2d7d3d2..27ea856 100644 (file)
@@ -17,6 +17,7 @@
 #include "realfuncs.h"
 
 char *bin_path;
 #include "realfuncs.h"
 
 char *bin_path;
+char **g_argv;
 
 #define CHECK_(val, fail_operator, expect, err_msg) \
   if (val fail_operator expect) { \
 
 #define CHECK_(val, fail_operator, expect, err_msg) \
   if (val fail_operator expect) { \
@@ -81,6 +82,8 @@ int main(int argc, char *argv[])
     return 1;
   }
 
     return 1;
   }
 
+  g_argv = argv;
+
   fi = fopen("/proc/self/maps", "r");
   CHECK_NE(fi, NULL, "fopen maps");
 
   fi = fopen("/proc/self/maps", "r");
   CHECK_NE(fi, NULL, "fopen maps");
 
index 5a722d9..1e0d415 100644 (file)
@@ -251,15 +251,20 @@ static UNUSED int w_execvp(const char *file, char *const argv[])
   return emu_do_execve(file, argv, environ);
 }
 
   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[])
+long w_execve_raw(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);
 }
 
 {
   strace("execve(%s, %p, %p) = ?\n", filename, argv, envp);
   return emu_do_execve(filename, argv, envp);
 }
 
+static UNUSED int w_execve(const char *filename, char * const argv[],
+                           char * const envp[])
+{
+  long ret = w_execve_raw(filename, argv, envp);
+  return g_syscall_error(ret);
+}
+
 static int w_chdir(const char *path)
 {
   long ret;
 static int w_chdir(const char *path)
 {
   long ret;
@@ -338,7 +343,7 @@ MAKE_WRAP_SYM_N(execlp);
 MAKE_WRAP_SYM_N(execle);
 MAKE_WRAP_SYM_N(execv);
 MAKE_WRAP_SYM_N(execvp);
 MAKE_WRAP_SYM_N(execle);
 MAKE_WRAP_SYM_N(execv);
 MAKE_WRAP_SYM_N(execvp);
-MAKE_WRAP_SYM(execve);
+MAKE_WRAP_SYM_N(execve);
 MAKE_WRAP_SYM_N(chdir);
 MAKE_WRAP_SYM_N(readlink);
 typeof(mmap) mmap2 __attribute__((alias("w_mmap")));
 MAKE_WRAP_SYM_N(chdir);
 MAKE_WRAP_SYM_N(readlink);
 typeof(mmap) mmap2 __attribute__((alias("w_mmap")));
@@ -361,7 +366,7 @@ static const struct {
   REAL_FUNC_NP(tcsetattr),
   REAL_FUNC_NP(system),
   // exec* - skipped
   REAL_FUNC_NP(tcsetattr),
   REAL_FUNC_NP(system),
   // exec* - skipped
-  REAL_FUNC_NP(execve),
+  //REAL_FUNC_NP(execve),
   //REAL_FUNC_NP(chdir),
 };
 
   //REAL_FUNC_NP(chdir),
 };
 
@@ -375,7 +380,7 @@ static const struct {
 #define tcgetattr p_real_tcgetattr
 #define tcsetattr p_real_tcsetattr
 #define system p_real_system
 #define tcgetattr p_real_tcgetattr
 #define tcsetattr p_real_tcsetattr
 #define system p_real_system
-#define execve p_real_execve
+//#define execve p_real_execve
 //#define chdir p_real_chdir
 
 #undef MAKE_WRAP_SYM
 //#define chdir p_real_chdir
 
 #undef MAKE_WRAP_SYM
@@ -458,7 +463,8 @@ int real_system(const char *command)
 int real_execve(const char *filename, char *const argv[],
                   char *const envp[])
 {
 int real_execve(const char *filename, char *const argv[],
                   char *const envp[])
 {
-  return execve(filename, argv, envp);
+  long ret = g_execve_raw(filename, argv, envp);
+  return g_syscall_error(ret);
 }
 
 int real_chdir(const char *path)
 }
 
 int real_chdir(const char *path)
index b7ea613..d272b56 100644 (file)
@@ -113,12 +113,12 @@ static const unsigned int sig_execve[] = {
 };
 #define sig_mask_execve sig_mask_all
 
 };
 #define sig_mask_execve sig_mask_all
 
-static const unsigned int sig_execve2[] = {
+static const unsigned int sig_hw_execve[] = {
   0xef90000b, // svc 0x90000b
   0xe3700a01, // cmn r0, #4096
   0xe1a04000, // mov r4, r0
 };
   0xef90000b, // svc 0x90000b
   0xe3700a01, // cmn r0, #4096
   0xe1a04000, // mov r4, r0
 };
-#define sig_mask_execve2 sig_mask_all
+#define sig_mask_hw_execve sig_mask_all
 
 static const unsigned int sig_chdir[] = {
   0xef90000c, // svc  0x90000c
 
 static const unsigned int sig_chdir[] = {
   0xef90000c, // svc  0x90000c
@@ -172,6 +172,7 @@ asm( \
 
 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_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)
 
 #define PATCH_(p, f, t) { sig_##p, sig_mask_##p, ARRAY_SIZE(sig_##p), t, f, #p }
 #define PATCH(f) PATCH_(f, w_##f, 0)
 
 #define PATCH_(p, f, t) { sig_##p, sig_mask_##p, ARRAY_SIZE(sig_##p), t, f, #p }
 #define PATCH(f) PATCH_(f, w_##f, 0)
@@ -195,7 +196,7 @@ static const struct {
   PATCH (ioctl),
   PATCH_(hw_ioctl, hw_ioctl, 1),
   PATCH (sigaction),
   PATCH (ioctl),
   PATCH_(hw_ioctl, hw_ioctl, 1),
   PATCH (sigaction),
-//  PATCH_(execve, execve2, 0), // hangs
+  PATCH_(hw_execve, hw_execve, 1),
   PATCH (chdir),
   PATCH (readlink),
   PATCH_(cache1, NULL, 2),
   PATCH (chdir),
   PATCH (readlink),
   PATCH_(cache1, NULL, 2),
index 7c57ef2..ab5800b 100644 (file)
@@ -89,6 +89,7 @@ raw_syscall_easy g_chdir_raw,          __NR_chdir
 raw_syscall_easy g_futex_raw,          __NR_futex
 raw_syscall_easy g_nanosleep_raw,      __NR_nanosleep
 raw_syscall_easy g_readlink_raw,       __NR_readlink
 raw_syscall_easy g_futex_raw,          __NR_futex
 raw_syscall_easy g_nanosleep_raw,      __NR_nanosleep
 raw_syscall_easy g_readlink_raw,       __NR_readlink
+raw_syscall_easy g_execve_raw,         __NR_execve
 raw_syscall_easy g_clock_gettime_raw,  __NR_clock_gettime
 raw_syscall_easy g_rt_sigprocmask_raw, __NR_rt_sigprocmask
 raw_syscall_easy g_exit_group_raw,     __NR_exit_group
 raw_syscall_easy g_clock_gettime_raw,  __NR_clock_gettime
 raw_syscall_easy g_rt_sigprocmask_raw, __NR_rt_sigprocmask
 raw_syscall_easy g_exit_group_raw,     __NR_exit_group
index d5a8048..3dfc44a 100644 (file)
@@ -25,6 +25,8 @@ 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);
 long g_readlink_raw(const char *pathname, char *buf, size_t bufsiz);
                  const struct timespec *timeout);
 long g_nanosleep_raw(const struct timespec *req, struct timespec *rem);
 long g_readlink_raw(const char *pathname, char *buf, size_t bufsiz);
+long g_execve_raw(const char *filename, char * const argv[],
+                  char * const envp[]);
 long g_clock_gettime_raw(int clk_id, const struct timespec *tp);
 long g_rt_sigprocmask_raw(int how, const void *set, void *oldset,
                           size_t sigsetsize);
 long g_clock_gettime_raw(int clk_id, const struct timespec *tp);
 long g_rt_sigprocmask_raw(int how, const void *set, void *oldset,
                           size_t sigsetsize);