From db9191ed7ea2e1c190b4445bf3c576b206c88b36 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 1 Aug 2010 01:11:40 +0300 Subject: [PATCH] wiz r1 relese --- dist/ginge_dyn_oabi.sh | 2 +- loader/emu.c | 27 ++++++- loader/ginge_dyn.symver | 4 ++ loader/override.c | 69 +++++++++++++++++- loader/patches.c | 21 +++++- loader/realfuncs.h | 7 ++ loader/tools/static.c | 7 ++ make_wiz.sh | 24 ++++--- readme.txt | 154 +++++++++++++++++++++------------------- 9 files changed, 227 insertions(+), 88 deletions(-) diff --git a/dist/ginge_dyn_oabi.sh b/dist/ginge_dyn_oabi.sh index 180d0da..739dfee 100755 --- a/dist/ginge_dyn_oabi.sh +++ b/dist/ginge_dyn_oabi.sh @@ -3,7 +3,7 @@ root=$1 shift -#export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${root}lib" +export LD_LIBRARY_PATH="${root}lib" export LD_PRELOAD="${root}ginge_dyn" export GINGE_ROOT="${root}" diff --git a/loader/emu.c b/loader/emu.c index 993ed55..5c24120 100644 --- a/loader/emu.c +++ b/loader/emu.c @@ -309,6 +309,8 @@ static void mlc_flip(void *src, int bpp) } \ } +static int fb_sync_thread_paused; + static void *fb_sync_thread(void *arg) { int invalid_fb_addr = 1; @@ -345,6 +347,10 @@ static void *fb_sync_thread(void *arg) sleep(1); continue; } + if (fb_sync_thread_paused) { + ts_add_nsec(ts, 100000000); + continue; + } if (wait_ret != ETIMEDOUT) { clock_gettime(CLOCK_REALTIME, &ts); @@ -375,6 +381,19 @@ static void *fb_sync_thread(void *arg) } } +static void fb_thread_pause(void) +{ + fb_sync_thread_paused = 1; + // wait until it finishes last refresh + // that it might be doing now + usleep(10000); +} + +static void fb_thread_resume(void) +{ + fb_sync_thread_paused = 0; +} + static u32 xread8(u32 a) { iolog("r8 ", a, 0, 8); @@ -1049,6 +1068,7 @@ int emu_do_system(const char *command) static char tmp_path[512]; const char *p2; char *p; + int ret; if (command == NULL) return -1; @@ -1068,6 +1088,11 @@ int emu_do_system(const char *command) free((void *)p2); dbg("system: \"%s\"\n", tmp_path); - return system(tmp_path); + + // the app might want the screen too.. + fb_thread_pause(); + ret = system(tmp_path); + fb_thread_resume(); + return ret; } diff --git a/loader/ginge_dyn.symver b/loader/ginge_dyn.symver index c0c70c1..cb50f2b 100644 --- a/loader/ginge_dyn.symver +++ b/loader/ginge_dyn.symver @@ -10,6 +10,10 @@ global: tcgetattr; tcsetattr; system; + execl; + execlp; + execve; + chdir; local: *; diff --git a/loader/override.c b/loader/override.c index 42b52ab..75b8eeb 100644 --- a/loader/override.c +++ b/loader/override.c @@ -150,6 +150,42 @@ static UNUSED int w_system(const char *command) return ret; } +// 4 functions bellow are efforts to prevent gp2xmenu from being started.. +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(0); +} + +static UNUSED int w_execlp(const char *file, const char *arg, ...) +{ + strace("execlp(%s, %s, ...) = ?\n", file, arg); + exit(0); +} + +// 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); + if (filename != NULL && strstr(filename, "/gp2xmenu") != NULL) + exit(0); + return 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 @@ -159,12 +195,19 @@ static UNUSED int w_system(const char *command) #undef tcgetattr #undef tcsetattr #undef system +#undef execl +#undef execlp +#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 @@ -178,6 +221,10 @@ 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(execve); +MAKE_WRAP_SYM(chdir); typeof(mmap) mmap2 __attribute__((alias("w_mmap"))); #define REAL_FUNC_NP(name) \ @@ -196,6 +243,9 @@ static const struct { 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 @@ -207,6 +257,8 @@ static const struct { #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 @@ -265,3 +317,16 @@ 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); +} diff --git a/loader/patches.c b/loader/patches.c index 7d8cf97..0504909 100644 --- a/loader/patches.c +++ b/loader/patches.c @@ -45,8 +45,25 @@ static const unsigned int sig_mask_sigaction[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000 }; +static const unsigned int sig_execve[] = { + 0xef90000b, 0xe1a04000, 0xe3700a01 +}; +#define sig_mask_execve sig_mask_all + +static const unsigned int sig_execve2[] = { + 0xef90000b, 0xe3700a01, 0xe1a04000 +}; +#define sig_mask_execve2 sig_mask_all + +static const unsigned int sig_chdir[] = { + 0xef90000c, 0xe3700a01, 0x312fff1e, 0xea0004bb +}; +static const unsigned int sig_mask_chdir[] = { + 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000 +}; -#define PATCH(f) { sig_##f, sig_mask_##f, ARRAY_SIZE(sig_##f), w_##f } +#define PATCH_(f,p) { sig_##p, sig_mask_##p, ARRAY_SIZE(sig_##p), w_##f } +#define PATCH(f) PATCH_(f,f) static const struct { const unsigned int *sig; @@ -60,6 +77,8 @@ static const struct { PATCH(read), PATCH(ioctl), PATCH(sigaction), +// PATCH_(execve, execve2), // hangs + PATCH(chdir), }; void do_patches(void *ptr, unsigned int size) diff --git a/loader/realfuncs.h b/loader/realfuncs.h index bda599a..38e3fce 100644 --- a/loader/realfuncs.h +++ b/loader/realfuncs.h @@ -20,6 +20,9 @@ typedef struct sigaction sigaction_t; int real_tcgetattr(int fd, struct termios *termios_p); int real_tcsetattr(int fd, int optional_actions, const struct termios *termios_p); int real_system(const char *command); +// exec* - skipped +int real_execve(const char *filename, char *const argv[], char *const envp[]); +int real_chdir(const char *path); #define open real_open #define fopen real_fopen @@ -30,4 +33,8 @@ int real_system(const char *command); #define tcgetattr real_tcgetattr #define tcsetattr real_tcsetattr #define system real_system +#define execl real_execl +#define execlp real_execlp +#define execve real_execve +#define chdir real_chdir diff --git a/loader/tools/static.c b/loader/tools/static.c index 257a147..a244d5d 100644 --- a/loader/tools/static.c +++ b/loader/tools/static.c @@ -8,6 +8,7 @@ #include #include #include +#include static int open_(const char *name) { @@ -41,6 +42,12 @@ int main(int argc, char *argv[]) ioctl(-1, 0); signal(7, SIG_DFL); + system("buhbuh"); + execl("bah", "bah", NULL); + execlp("bah", "bah", NULL); + if (argc == 1000) + fork(); + chdir("wuhahaha!"); // tcgetattr(-1, NULL); // tcsetattr(-1, 0, NULL); diff --git a/make_wiz.sh b/make_wiz.sh index cc8f2b0..bea9af7 100755 --- a/make_wiz.sh +++ b/make_wiz.sh @@ -2,12 +2,18 @@ set -e -dist/make_cmn.sh out_wiz -mkdir -p out_wiz/tools -cp dist/ginge.gpe out_wiz/ -cp dist/ginge32.png out_wiz/ginge.png -cp dist/ginge_dyn_oabi.sh out_wiz/ginge_dyn.sh -cp tools/cramfsck_oabi out_wiz/tools/cramfsck -cp tools/warm_2.6.24.ko out_wiz/tools/ - -dd if=/dev/zero of=out_wiz/swapfile bs=1M count=16 +out=out_wiz + +dist/make_cmn.sh ${out} +mkdir -p ${out}/tools ${out}/lib +cp dist/ginge.gpe ${out}/ +cp dist/ginge32.png ${out}/ginge.png +cp dist/ginge_dyn_oabi.sh ${out}/ginge_dyn.sh +cp lib/libSDL-1.2.so.0.7.0 ${out}/lib/libSDL-1.2.so.0 +cp tools/cramfsck_oabi ${out}/tools/cramfsck +cp tools/warm_2.6.24.ko ${out}/tools/ + +dd if=/dev/zero of=${out}/swapfile bs=1M count=16 + +cd ${out} +zip -9r ../ginge_wiz.zip * diff --git a/readme.txt b/readme.txt index 8f2671e..18f3ee0 100644 --- a/readme.txt +++ b/readme.txt @@ -1,74 +1,80 @@ - -GINGE - Ginge Is Not GP2X Emulator - -(C) notaz, 2010 -http://notaz.gp2x.de/ - - -About ------ - -Ginge is an application that can run many GP2X F100/F200 games on other ARM -Linux platforms, which currently includes Wiz. It is not a full hardware -emulator like MAME, PicoDrive or similar, it does not emulate the CPU. It can -be considered as compatibility layer similar to Wine on PC Linux, however it -does emulate small portion of MMSP2 system-on-chip. It operates by hooking -certain system calls and using realtime patching of code that accesses memory -mapped hardware directly. - - -Usage ------ - -Ginge comes with a launcher that is started when you run Ginge. The launcher -can then be used to start GP2X software, which will either run if it's -compatible, or just return back to the menu if it is not. In some cases it -might hang though. - - -Structure ---------- - -Ginge actually consists of 4 independent executables and a few scripts: - -+ ginge_sloader - loader of static executables -+ ginge_dyn - dynamic executable handler -+ ginge_prep - .gpe parser that selects the right handler from above -+ gp2xmenu - the launcher/menu program -+ ginge_dyn.sh - environment setup script for ginge_dyn -+ ginge.sh/gpe - menu launcher script - -The menu is optional and can be replaced or bypassed completely. The only thing -it does is running ginge_prep on GP2X .gpe program, ginge_prep handles the rest. - - -License -------- - -gp2xmenu is based on GPH GPL source (http://www.gnu.org/licenses/gpl.html). -Source is available at - -Remaining portion is released under custom closed source license. It is not -derived from gp2xmenu and is completely standalone, the menu is only included -for user's convenience. - -Redistribution and use of program's binaries and helper scripts, with or without -modification, is permitted provided that the following conditions are met: - * This readme is included in unmodified form. - * The program in any of it's forms is not sold or used as part of any - commercial package, including pre-installed or included in any kind of - portable device. - * It is not bundled or distributed with any GP2X program without respective - program's author's permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + +GINGE - Ginge Is Not GP2X Emulator +release 1 + +(C) notaz, 2010 +http://notaz.gp2x.de/ + + +About +----- + +Ginge is an application that can run many GP2X F100/F200 games on other ARM +Linux platforms, which currently includes Wiz. It is not a full hardware +emulator like MAME, PicoDrive or similar, it does not emulate the CPU. It can +be considered as compatibility layer similar to Wine on PC Linux, however it +does emulate small portion of MMSP2 system-on-chip. It operates by hooking +certain system calls and using realtime patching of code that accesses memory +mapped hardware directly. + + +Usage +----- + +Ginge comes with a launcher that is started when you run Ginge. The launcher +can then be used to start GP2X software, which will either run if it's +compatible, or just return back to the menu if it is not. In some cases it +might hang though. + + +Structure +--------- + +Ginge actually consists of 4 independent executables and a few scripts: + ++ ginge_sloader - loader of static executables ++ ginge_dyn - dynamic executable handler ++ ginge_prep - .gpe parser that selects the right handler from above ++ gp2xmenu - the launcher/menu program ++ ginge_dyn.sh - environment setup script for ginge_dyn ++ ginge.sh/gpe - menu launcher script + +The menu is optional and can be replaced or bypassed completely. The only thing +it does is running ginge_prep on GP2X .gpe program, ginge_prep handles the rest. + + +License +------- + +gp2xmenu is based on GPH GPL source (http://www.gnu.org/licenses/gpl.html). +Source is available at http://notaz.gp2x.de/releases/ginge/gp2xmenu.tar.bz2 + +Ginge may come with some libraries. Those libraries are unmodified copies +of ones found in root filesystems in GP2X and Wiz and are included to more +accurately reproduce environment on GP2X. Their source code may or may not be +available, I do not have it nor did I use it. + +Remaining portion is released under custom closed source license. It is not +derived from gp2xmenu and is completely standalone, the menu is only included +for user's convenience. + +Redistribution and use of program's binaries and helper scripts, with or without +modification, is permitted provided that the following conditions are met: + * This readme is included in unmodified form. + * The program in any of it's forms is not sold or used as part of any + commercial package, including pre-installed or included in any kind of + portable device. + * It is not bundled or distributed with any GP2X program without respective + program's author's permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + -- 2.39.2