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;
- int i, ret, argc;
+ int i, argc;
+ long ret;
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++)
;
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;
}
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);
-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,
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]))
#include "host_wiz.c"
#endif
-// for plat.c
-char **g_argv;
-
int host_init(void)
{
in_init();
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)
usleep(300000);
snprintf(cmd, sizeof(cmd), "killall -9 %s", g_argv[0]);
system(cmd);
- exit(1);
+ exit(status);
}
// vim:shiftwidth=2:expandtab
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)
act |= 1 << GP2X_VOL_DOWN;
}
if (act & (1 << GP2X_Y))
- host_forced_exit();
+ host_forced_exit(1);
actions[IN_BINDTYPE_PLAYER12] = act;
}
}
#include "realfuncs.h"
char *bin_path;
+char **g_argv;
#define CHECK_(val, fail_operator, expect, err_msg) \
if (val fail_operator expect) { \
return 1;
}
+ g_argv = argv;
+
fi = fopen("/proc/self/maps", "r");
CHECK_NE(fi, NULL, "fopen maps");
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);
}
+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;
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")));
REAL_FUNC_NP(tcsetattr),
REAL_FUNC_NP(system),
// exec* - skipped
- REAL_FUNC_NP(execve),
+ //REAL_FUNC_NP(execve),
//REAL_FUNC_NP(chdir),
};
#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
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)
};
#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
};
-#define sig_mask_execve2 sig_mask_all
+#define sig_mask_hw_execve sig_mask_all
static const unsigned int sig_chdir[] = {
0xef90000c, // svc 0x90000c
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)
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),
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
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);