diff options
| -rwxr-xr-x | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | docs/README.md | 9 | ||||
| -rwxr-xr-x | docs/USAGE.md | 88 | ||||
| -rwxr-xr-x | src/box64context.c | 2 | ||||
| -rwxr-xr-x | src/include/debug.h | 6 | ||||
| -rwxr-xr-x | src/include/fileutils.h | 3 | ||||
| -rw-r--r-- | src/include/rcfile.h | 8 | ||||
| -rwxr-xr-x | src/librarian/library.c | 3 | ||||
| -rwxr-xr-x | src/main.c | 100 | ||||
| -rwxr-xr-x | src/tools/fileutils.c | 12 | ||||
| -rw-r--r-- | src/tools/rcfile.c | 454 | ||||
| -rw-r--r-- | src/wrapped/generated/functions_list.txt | 4 | ||||
| -rw-r--r-- | src/wrapped/generated/wrappedlibctypes.h | 2 | ||||
| -rw-r--r-- | src/wrapped/generated/wrapper.c | 5 | ||||
| -rw-r--r-- | src/wrapped/generated/wrapper.h | 2 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc.c | 11 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc_private.h | 2 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibgl.c | 4 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibx11.c | 7 | ||||
| -rwxr-xr-x | src/wrapped/wrappedsdl2.c | 5 | ||||
| -rw-r--r-- | system/box64.box64rc | 34 |
21 files changed, 654 insertions, 109 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index bca15509..aa9a620d 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,6 +281,7 @@ set(ELFLOADER_SRC "${BOX64_ROOT}/src/tools/gtkclass.c" "${BOX64_ROOT}/src/tools/pathcoll.c" "${BOX64_ROOT}/src/tools/fileutils.c" + "${BOX64_ROOT}/src/tools/rcfile.c" "${BOX64_ROOT}/src/tools/wine_tools.c" "${BOX64_ROOT}/src/wrapped/generated/wrapper.c" ) @@ -633,6 +634,7 @@ if(NOT _x86 AND NOT _x86_64) install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libstdc++.so.6 DESTINATION /usr/lib/x86_64-linux-gnu/) install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libgcc_s.so.1 DESTINATION /usr/lib/x86_64-linux-gnu/) install(FILES ${CMAKE_SOURCE_DIR}/x64lib/libpng12.so.0 DESTINATION /usr/lib/x86_64-linux-gnu/) + install(FILES ${CMAKE_SOURCE_DIR}/system/box64.box64rc DESTINATION /etc/) endif() if(NOT TARGET uninstall) diff --git a/docs/README.md b/docs/README.md index d3a77980..ea1c5b4e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -58,6 +58,15 @@ Note that many installer (mojo setup based) will fall back to "x86" when detecti ---- +Notes about Box64 configuration +---- + +Box64 now have configurations files. There are 2 files loaded. `/etc/box4.box64rc` and `~/.box64rc`. Both files have the same syntax, and is basicaly an ini files. Section in square brakets define the process name, and the rest is the env. var. to set. Looke at [Usage](USAGE.md) for detail on what parameters can be put. Box64 comes with a default file that should be installed for better stability. The file in in `system/box64.box64rc` and should be installed to `/etc/box64.box64rc` If, for some reasons, you don't want to install that file here, at least copy it to `~/.box64rc` or some game may not function correctly. +Note that the priority is: `~/.bashrc` > `/etc/box64.box64rc` > command line +So, your settings in `~/.bashrc` may override the setting from your command line... + +---- + Notes about Unity game emulation ---- diff --git a/docs/USAGE.md b/docs/USAGE.md index 606c6707..cb11e7aa 100755 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -3,15 +3,16 @@ Usage ---- There are many environment variables to control Box64 behaviour. +Env. var with * can also be put inside box64rc files -#### BOX64_LOG +#### BOX64_LOG * Controls the Verbosity level of the logs * 0: NONE : No message (except some fatal error). (Default.) * 1: INFO : Show some minimum log (Example: librairies not found) * 2: DEBUG : Details a lot of stuff (Example: relocations or functions called). * 3: DUMP : All DEBUG plus DUMP of all ELF Info. -#### BOX64_ROLLING_LOG +#### BOX64_ROLLING_LOG * Show last few wrapped function call when a Signal is caught * 0: No last function call printed (Default.) * 1: Last 16 wrapped functions calls printed when a signal is printed. Incompatible with BOX64_LOG>1 (may need BOX64_SHOWSEGV=1 also) @@ -22,146 +23,146 @@ Disables Box64 printing its version and build * 0 : Enable printing its banner. (Default.) * 1 : Disable printing its banner. -#### BOX64_LD_LIBRARY_PATH +#### BOX64_LD_LIBRARY_PATH * Path to look for x86_64 libraries. Default is current folder and `lib` in current folder. Also, `/usr/lib/x86_64-linux-gnu` and `/lib/x86_64-linux-gnu` are added if they exist. -#### BOX64_PATH +#### BOX64_PATH * Path to look for x86_64 executable. Default is current folder and `bin` in current folder. -#### BOX64_DLSYM_ERROR +#### BOX64_DLSYM_ERROR * Enables/Disables the logging of `dlsym` errors. * 0 : Don't log `dlsym` errors. (Default.) * 1 : Log dlsym errors. -#### BOX64_TRACE_FILE +#### BOX64_TRACE_FILE * Send all log and trace to a file instead of `stdout` Also, if name contains `%pid` then this is replaced by the actual PID of box64 instance End the filename with `+` to have thetrace appended instead of overwriten Use `stderr` to use this instead of default `stdout` -#### BOX64_TRACE +#### BOX64_TRACE * Only on build with trace enabled. Trace allow the logging of all instruction executed, along with register dump * 0 : No trace. (Default.) * 1 : Trace enabled. Trace start after the initialisation of all depending libraries is done. * symbolname : Trace only `symbolname` (trace is disable if the symbol is not found). * 0xXXXXXXX-0xYYYYYYY : Trace only between the 2 addresses. -#### BOX64_TRACE_INIT +#### BOX64_TRACE_INIT * Use BOX64_TRACE_INIT instead of BOX_TRACE to start trace before the initialisation of libraries and the running program * 0 : No trace. (Default.) * 1 : Trace enabled. The trace start with the initialisation of all depending libraries is done. -#### BOX64_TRACE_START +#### BOX64_TRACE_START * Only on builds with trace enabled. * NNNNNNN : Start trace only after NNNNNNNN opcode execute (number is an `uint64_t`). -#### BOX64_TRACE_XMM +#### BOX64_TRACE_XMM * Only on builds with trace enabled. * 0 : The XMM (i.e. SSE/SSE2) register will not be logged with the general and x86 registers. (Default.) * 1 : Dump the XMM registers. -#### BOX64_TRACE_EMM +#### BOX64_TRACE_EMM * Only on builds with trace enabled. - * 0 : The EMM (i.e. XMM/x87) register will not be logged with the general and x86 registers. (Default.) + * 0 : The EMM (i.e. MMX) register will not be logged with the general and x86 registers. (Default.) * 1 : Dump the EMM registers. -#### BOX64_TRACE_COLOR +#### BOX64_TRACE_COLOR * Only on builds with trace enabled. * 0 : The general registers will always be the default white color. (Default.) * 1 : The general registers will change color in the dumps when they changed value. -#### BOX64_LOAD_ADDR +#### BOX64_LOAD_ADDR * Try to load at 0xXXXXXX main binary (if binary is a PIE) * 0xXXXXXXXX : The load address . (Only active on PIE programs.) -#### BOX64_NOSIGSEGV +#### BOX64_NOSIGSEGV * Disable handling of SigSEGV. (Very useful for debugging.) * 0 : Let the x86 program set sighandler for SEGV (Default.) * 1 : Disable the handling of SigSEGV. -#### BOX64_NOSIGILL +#### BOX64_NOSIGILL * Disable handling of SigILL (to ease debugging mainly). * 0 : Let x86 program set sighandler for Illegal Instruction * 1 : Disables the handling of SigILL -#### BOX64_SHOWSEGV +#### BOX64_SHOWSEGV * Show Segfault signal even if a signal handler is present * 0 : Don"t force show the SIGSEGV analysis (Default.) * 1 : Show SIGSEGV detail, even if a signal handler is present -#### BOX64_SHOWBT +#### BOX64_SHOWBT * Show some Backtrace (Nativ e and Emulated) whgen a signal (SEGV, ILL or BUS) is caught * 0 : Don"t show backtraces (Default.) * 1 : Show Backtrace detail (for native, box64 is rename as the x86_64 binary run) -#### BOX64_X11THREADS +#### BOX64_X11THREADS * Call XInitThreads when loading X11. (This is mostly for old Loki games with the Loki_Compat library.) * 0 : Don't force call XInitThreads. (Default.) * 1 : Call XInitThreads as soon as libX11 is loaded. -#### BOX64_X11GLX +#### BOX64_X11GLX * Force libX11's GLX extension to be present. * 0 : Do not force libX11's GLX extension to be present. * 1 : GLX will always be present when using XQueryExtension. (Default.) -#### BOX64_DYNAREC_DUMP +#### BOX64_DYNAREC_DUMP * Enables/disables Box64's Dynarec's dump. * 0 : Disable Dynarec's blocks dump. (Default.) * 1 : Enable Dynarec's blocks dump. * 2 : Enable Dynarec's blocks dump with some colors. -#### BOX64_DYNAREC_LOG +#### BOX64_DYNAREC_LOG * Set the level of DynaRec's logs. * 0 : NONE : No Logs for DynaRec. (Default.) * 1 :INFO : Minimum Dynarec Logs (only unimplemented OpCode). * 2 : DEBUG : Debug Logs for Dynarec (with details on block created / executed). * 3 : VERBOSE : All of the above plus more. -#### BOX64_DYNAREC +#### BOX64_DYNAREC * Enables/Disables Box64's Dynarec. * 0 : Disables Dynarec. * 1 : Enable Dynarec. (Default.) -#### BOX64_DYNAREC_TRACE +#### BOX64_DYNAREC_TRACE * Enables/Disables trace for generated code. * 0 : Disable trace for generated code. (Default.) * 1 : Enable trace for generated code (like regular Trace, this will slow down the program a lot and generate huge logs). -#### BOX64_NODYNAREC +#### BOX64_NODYNAREC * Forbid dynablock creation in the interval specified (helpfull for debugging behaviour difference between Dynarec and Interpretor) * 0xXXXXXXXX-0xYYYYYYYY : define the interval where dynablock cannot start (inclusive-exclusive) -#### BOX64_DYNAREC_BIGBLOCK +#### BOX64_DYNAREC_BIGBLOCK * Enables/Disables Box64's Dynarec building BigBlock. * 0 : Don't try to build block as big as possible (can help program using lots of thread and a JIT, like C#/Unity) (Default when libmonobdwgc-2.0.so is loaded) * 1 : Build Dynarec block as big as possible (Default.) * 2 : Build Dynarec block bigger (don't stop when block overlaps, but only for blocks in elf memory) * 3 : Build Dynarec block bigger (don't stop when block overlaps, for all type of memory) -#### BOX64_DYNAREC_STRONGMEM +#### BOX64_DYNAREC_STRONGMEM * Enable/Disable simulation of Strong Memory model * 0 : Don't try anything special (Default.) * 1 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model while trying to limit performance impact (Default when libmonobdwgc-2.0.so is loaded) -* 2 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model (enabled with dota2 is detected) +* 2 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model -#### BOX64_DYNAREC_X87DOUBLE +#### BOX64_DYNAREC_X87DOUBLE * Force the use of Double for x87 emulation * 0 : Try to use float when possible for x87 emulation (default, faster) * 1 : Only use Double for x87 emulation (slower, may be needed for some specific games, like Crysis) -#### BOX64_DYNAREC_FASTNAN +#### BOX64_DYNAREC_FASTNAN * Enable/Disable generation of -NAN * 0 : Generate -NAN like on x86 * 1 : Don't do anything special with NAN, to go as fast as possible (default) -#### BOX64_DYNAREC_SAFEFLAGS +#### BOX64_DYNAREC_SAFEFLAGS * Handling of flags on CALL/RET opcodes * 0 : Treat CALL/RET as if it never needs any flags (faster but not advised) * 1 : most of RET will need flags, most of CALLS will not (Default) * 2 : All CALL/RET will need flags (slower, but might be needed. Automatically enabled for Vara.exe) -#### BOX64_LIBGL +#### BOX64_LIBGL * * libXXXX set the name for libGL (defaults to libGL.so.1). * /PATH/TO/libGLXXX : Sets the name and path for libGL You can also use SDL_VIDEO_GL_DRIVER @@ -170,47 +171,47 @@ Handling of flags on CALL/RET opcodes * XXXX[:YYYYY] force loading XXXX (and YYYY...) libraries with the binary PreLoaded libs can be emulated or native, and are treated the same way as if they were comming from the binary -#### BOX64_EMULATED_LIBS +#### BOX64_EMULATED_LIBS * * XXXX[:YYYYY] force lib XXXX (and YYYY...) to be emulated (and not wrapped) Some games uses an old version of some libraries, with an ABI incompatible with native version. Note that LittleInferno for example is auto detected, and libvorbis.so.0 is automatical added to emulated libs, and same for Don't Starve (and Together / Server variant) that use an old SDL2 too -#### BOX64_ALLOWMISSINGLIBS +#### BOX64_ALLOWMISSINGLIBS * Allow Box64 to continue even if a library is missing. * 0 : Box64 will stop if a library cannot be loaded. (Default.) * 1 : Continue even if a needed library cannot be loaded. Unadvised, this will, in most cases, crash later on. -#### BOX64_PREFER_WRAPPED +#### BOX64_PREFER_WRAPPED * Box64 will use wrapped libs even if the lib is specified with absolute path * 0 : Try to use emulated libs when they are defined with absolute path (Default.) * 1 : Use Wrapped native libs even if path is absolute -#### BOX64_PREFER_EMULATED +#### BOX64_PREFER_EMULATED * Box64 will prefer emulated libs first (execpt for glibc, alsa, pulse, GL, vulkan and X11 * 0 : Native libs are prefered (Default.) * 1 : Emulated libs are prefered (Default for program running inside pressure-vessel) -#### BOX64_CRASHHANDLER +#### BOX64_CRASHHANDLER * Box64 will use a dummy crashhandler.so library * 0 : Use Emulated crashhandler.so library if needed * 1 : Use an internal dummy (completly empty) crashhandler.so library (defaut for steam and dota2) -#### BOX64_NOPULSE +#### BOX64_NOPULSE * Disables the load of pulseaudio libraries. * 0 : Load pulseaudio libraries if found. (Default.) * 1 : Disables the load of pulse audio libraries (libpulse and libpulse-simple), both the native library and the x86 library -#### BOX64_NOGTK +#### BOX64_NOGTK * Disables the loading of wrapped GTK libraries. * 0 : Load wrapped GTK libraries if found. (Default.) * 1 : Disables loading wrapped GTK libraries. -#### BOX64_NOVULKAN +#### BOX64_NOVULKAN * Disables the load of vulkan libraries. * 0 : Load vulkan libraries if found. * 1 : Disables the load of vulkan libraries, both the native and the i386 version (can be useful on Pi4, where the vulkan driver is not quite there yet.) -#### BOX64_BASH +#### BOX64_BASH * Define x86_64 bash to launch script * yyyy Will use yyyy as x86_64 bash to launch script. yyyy needs to be a full path to a valid x86_64 version of bash @@ -223,7 +224,7 @@ Define x86_64 bash to launch script * XXX=yyyy will add XXX=yyyy env. var. and continue with BOX86_ENV2 ... until var doesn't exist -#### BOX64_JITGDB +#### BOX64_JITGDB * * 0 : Just print the Segfault message on segfault (default) * 1 : Launch `gdb` when a segfault, bus error or illegal instruction signal is trapped, attached to the offending process and go in an endless loop, waiting. When in gdb, you need to find the correct thread yourself (the one with `my_box64signalhandler` in is stack) @@ -233,3 +234,6 @@ Define x86_64 bash to launch script * 2 : Launch `gdbserver` when a segfault, bus error or illegal instruction signal is trapped, attached to the offending process, and go in an endless loop, waiting. Use `gdb /PATH/TO/box64` and then `target remote 127.0.0.1:1234` to connect to the gdbserver (or use actual IP if not on the machine). After that, the procedure is the same as with ` BOX64_JITGDB=1`. This mode can be usefullwhen programs redirect all console output to a file (like Unity3D Games) + +#### BOX64_NORCFILES +If the env var exist, no rc files (like /etc/box64.box64rc and ~/.box64rc) will be loaded diff --git a/src/box64context.c b/src/box64context.c index aa130f46..a70b40d0 100755 --- a/src/box64context.c +++ b/src/box64context.c @@ -19,6 +19,7 @@ #include "wrapper.h" #include "x64emu.h" #include "signals.h" +#include "rcfile.h" EXPORTDYN void initAllHelpers(box64context_t* context) @@ -39,6 +40,7 @@ void finiAllHelpers(box64context_t* context) static int finied = 0; if(finied) return; + DeleteParams(); fini_pthread_helper(context); fini_signal_helper(); fini_bridge_helper(); diff --git a/src/include/debug.h b/src/include/debug.h index b441416d..5a6aec91 100755 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -35,6 +35,9 @@ extern int trace_emm; // include EMM reg in trace? extern int trace_regsdiff; // colorize standard registers on changes extern uintptr_t trace_start, trace_end; extern char* trace_func; +extern char* trace_init; +extern char* box64_trace; +extern uint64_t start_cnt; #endif extern int box64_dummy_crashhandler; extern int allow_missing_libs; @@ -50,6 +53,9 @@ extern int box64_novulkan; // disabling the use of wrapped vulkan extern int box64_showsegv; // show sigv, even if a signal handler is present extern int box64_showbt; // show a backtrace if a signal is caught extern int box64_isglibc234; // is the program linked with glibc 2.34+ +extern int box64_x11threads; +extern int box64_x11glx; +extern char* box64_libGL; extern uintptr_t fmod_smc_start, fmod_smc_end; // to handle libfmod (from Unreal) SMC (self modifying code) extern uint32_t default_gs; extern int jit_gdb; // launch gdb when a segfault is trapped diff --git a/src/include/fileutils.h b/src/include/fileutils.h index ff69e6da..c666f0be 100755 --- a/src/include/fileutils.h +++ b/src/include/fileutils.h @@ -21,6 +21,9 @@ int FileIsShell(const char* filename); // return temp folder (will return /tmp if nothing is correct) const char* GetTmpDir(); +// will lower case the string and return a copy. Nothing fancy here, just A..Z transformed to a..z, rest is untouched +char* LowerCase(const char* s); + #if defined(RPI) || defined(RK3399) || defined(RK3326) void sanitize_mojosetup_gtk_background(); #endif diff --git a/src/include/rcfile.h b/src/include/rcfile.h new file mode 100644 index 00000000..c194e9ae --- /dev/null +++ b/src/include/rcfile.h @@ -0,0 +1,8 @@ +#ifndef __RCFILE_H__ +#define __RCFILE_H__ + +void LoadRCFile(const char* filename); +void DeleteParams(); +void ApplyParams(const char* name); + +#endif //__RCFILE_H__ \ No newline at end of file diff --git a/src/librarian/library.c b/src/librarian/library.c index 29c595a1..e58cd1d0 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -349,7 +349,6 @@ static int isEssentialLib(const char* name) { return 0; } -extern char* libGL; library_t *NewLibrary(const char* path, box64context_t* context) { printf_log(LOG_DEBUG, "Trying to load \"%s\"\n", path); @@ -357,7 +356,7 @@ library_t *NewLibrary(const char* path, box64context_t* context) lib->path = box_realpath(path, NULL); if(!lib->path) lib->path = box_strdup(path); - if(libGL && !strcmp(path, libGL)) + if(box64_libGL && !strcmp(path, box64_libGL)) lib->name = box_strdup("libGL.so.1"); else lib->name = Path2Name(path); diff --git a/src/main.c b/src/main.c index e1221454..121540a7 100755 --- a/src/main.c +++ b/src/main.c @@ -33,6 +33,7 @@ #include "librarian.h" #include "x64run.h" #include "symbols.h" +#include "rcfile.h" box64context_t *my_context = NULL; int box64_log = LOG_INFO; //LOG_NONE; @@ -71,12 +72,14 @@ int trace_regsdiff = 0; uint64_t start_cnt = 0; uintptr_t trace_start = 0, trace_end = 0; char* trace_func = NULL; +char* trace_init = NULL; +char* box64_trace = NULL; #ifdef DYNAREC int box64_dynarec_trace = 0; #endif #endif -int x11threads = 0; -int x11glx = 1; +int box64_x11threads = 0; +int box64_x11glx = 1; int allow_missing_libs = 0; int box64_prefer_emulated = 0; int box64_prefer_wrapped = 0; @@ -93,7 +96,7 @@ int box64_novulkan = 0; int box64_showsegv = 0; int box64_showbt = 0; int box64_isglibc234 = 0; -char* libGL = NULL; +char* box64_libGL = NULL; uintptr_t fmod_smc_start = 0; uintptr_t fmod_smc_end = 0; uint32_t default_gs = 0xa<<3; @@ -103,12 +106,12 @@ int box64_tcmalloc_minimal = 0; FILE* ftrace = NULL; int ftrace_has_pid = 0; -void openFTrace() +void openFTrace(const char* newtrace) { - char* t = getenv("BOX64_TRACE_FILE"); + const char* t = newtrace?newtrace:getenv("BOX64_TRACE_FILE"); char tmp[500]; char tmp2[500]; - char* p = t; + const char* p = t; int append=0; if(p && strlen(p) && p[strlen(p)-1]=='+') { strncat(tmp2, t, 499); @@ -159,7 +162,7 @@ void my_child_fork() if(ftrace_has_pid) { // open a new ftrace... fclose(ftrace); - openFTrace(); + openFTrace(NULL); } } @@ -332,7 +335,7 @@ void LoadLogEnv() } } // grab BOX64_TRACE_FILE envvar, and change %pid to actual pid is present in the name - openFTrace(); + openFTrace(NULL); box64_log = isatty(fileno(ftrace))?LOG_INFO:LOG_NONE; //default LOG value different if stdout is redirected or not p = getenv("BOX64_LOG"); if(p) { @@ -548,31 +551,31 @@ void LoadLogEnv() if(p) { if(strlen(p)==1) { if(p[0]>='0' && p[0]<='0'+1) - x11threads = p[0]-'0'; + box64_x11threads = p[0]-'0'; } - if(x11threads) + if(box64_x11threads) printf_log(LOG_INFO, "Try to Call XInitThreads if libX11 is loaded\n"); } p = getenv("BOX64_X11GLX"); if(p) { if(strlen(p)==1) { if(p[0]>='0' && p[0]<='0'+1) - x11glx = p[0]-'0'; + box64_x11glx = p[0]-'0'; } - if(x11glx) + if(box64_x11glx) printf_log(LOG_INFO, "Hack to force libX11 GLX extension present\n"); else printf_log(LOG_INFO, "Disabled Hack to force libX11 GLX extension present\n"); } p = getenv("BOX64_LIBGL"); if(p) - libGL = box_strdup(p); - if(!libGL) { + box64_libGL = box_strdup(p); + if(!box64_libGL) { p = getenv("SDL_VIDEO_GL_DRIVER"); if(p) - libGL = box_strdup(p); + box64_libGL = box_strdup(p); } - if(libGL) { + if(box64_libGL) { printf_log(LOG_INFO, "BOX64 using \"%s\" as libGL.so.1\n", p); } p = getenv("BOX64_ALLOWMISSINGLIBS"); @@ -892,13 +895,17 @@ void LoadEnvVars(box64context_t *context) #ifdef HAVE_TRACE char* p = getenv("BOX64_TRACE"); if(p) { - if (strcmp(p, "0")) + if (strcmp(p, "0")) { context->x64trace = 1; + box64_trace = p; + } } p = getenv("BOX64_TRACE_INIT"); if(p) { - if (strcmp(p, "0")) + if (strcmp(p, "0")) { context->x64trace = 1; + trace_init = p; + } } if(my_context->x64trace) { printf_log(LOG_INFO, "Initializing Zydis lib\n"); @@ -914,7 +921,7 @@ EXPORTDYN void setupTraceInit() { #ifdef HAVE_TRACE - char* p = getenv("BOX64_TRACE_INIT"); + char* p = trace_init; if(p) { setbuf(stdout, NULL); uintptr_t s_trace_start=0, s_trace_end=0; @@ -937,7 +944,7 @@ void setupTraceInit() } } } else { - p = getenv("BOX64_TRACE"); + p = box64_trace; if(p) if (strcmp(p, "0")) SetTraceEmu(0, 1); @@ -949,7 +956,7 @@ EXPORTDYN void setupTrace() { #ifdef HAVE_TRACE - char* p = getenv("BOX64_TRACE"); + char* p = box64_trace; if(p) { setbuf(stdout, NULL); uintptr_t s_trace_start=0, s_trace_end=0; @@ -978,6 +985,8 @@ void setupTrace() } else { printf_log(LOG_NONE, "Warning, symbol to trace (\"%s\") not found, trying to set trace later\n", p); SetTraceEmu(0, 1); // disabling trace, mostly + if(trace_func) + box_free(trace_func); trace_func = box_strdup(p); } } @@ -1044,9 +1053,9 @@ void endBox64() #endif // all done, free context FreeBox64Context(&my_context); - if(libGL) { - box_free(libGL); - libGL = NULL; + if(box64_libGL) { + box_free(box64_libGL); + box64_libGL = NULL; } } @@ -1057,6 +1066,20 @@ static void free_contextargv() box_free(my_context->argv[i]); } +static void load_rcfiles() +{ + if(FileExist("/etc/box64.box64rc", IS_FILE)) + LoadRCFile("/etc/box64.box64rc"); + char* p = getenv("HOME"); + if(p) { + char tmp[4096]; + strncpy(tmp, p, 4096); + strncat(tmp, "/.box64rc", 4095); + if(FileExist(tmp, IS_FILE)) + LoadRCFile(tmp); + } +} + void pressure_vessel(int argc, const char** argv, int nextarg); extern char** environ; int main(int argc, const char **argv, char **env) { @@ -1079,6 +1102,9 @@ int main(int argc, const char **argv, char **env) { // check BOX64_LOG debug level LoadLogEnv(); + if(!getenv("BOX64_NORCFILES")) { + load_rcfiles(); + } char* bashpath = NULL; { char* p = getenv("BOX64_BASH"); @@ -1251,24 +1277,10 @@ int main(int argc, const char **argv, char **env) { if(box64_wine) { AddPath("libdl.so.2", &ld_preload, 0); } - // special case for dontstarve that use an old SDL2 - if(strstr(prgname, "dontstarve")) { - printf_log(LOG_INFO, "Dontstarve* detected, forcing emulated SDL2\n"); - AddPath("libSDL2-2.0.so.0", &my_context->box64_emulated_libs, 0); - } // special case for steam that somehow seems to alter libudev opaque pointer (udev_monitor) if(!strcmp(prgname, "steam")) { printf_log(LOG_INFO, "steam detected...\n"); - AddPath("libudev.so.0", &my_context->box64_emulated_libs, 0); box64_steam = 1; - box64_dummy_crashhandler = 1; - } - if(!strcmp(prgname, "dota2")) { - printf_log(LOG_INFO, "dota2 detected, forcing dummy crashhandler\n"); - box64_dummy_crashhandler = 1; - #ifdef DYNAREC - box64_dynarec_strongmem = 1; - #endif } // special case for steam-runtime-check-requirements to fake 64bits suport if(strstr(prgname, "steam-runtime-check-requirements")==prgname) { @@ -1280,12 +1292,6 @@ int main(int argc, const char **argv, char **env) { printf_log(LOG_INFO, "steamwebhelper, ignoring for now!\n"); exit(0); // exiting } - // special case for streaming_client to use emulated libSDL2 - if(strstr(prgname, "streaming_client")==prgname) { - printf_log(LOG_INFO, "streaming_client detected, using emulated libSDL2!\n"); - AddPath("libSDL2-2.0.so.0", &my_context->box64_emulated_libs, 0); - AddPath("libSDL2_ttf-2.0.so.0", &my_context->box64_emulated_libs, 0); - } // special case for zoom if(strstr(prgname, "zoom")==prgname) { printf_log(LOG_INFO, "Zoom detected, trying to use system libturbojpeg if possible\n"); @@ -1306,10 +1312,6 @@ int main(int argc, const char **argv, char **env) { if(bashpath) my_context->bashpath = box_strdup(bashpath); - if(strstr(prgname, "pressure-vessel-wrap")==prgname) { - printf_log(LOG_INFO, "pressure-vessel-wrap detected, disabling GTK\n"); - box64_nogtk = 1; - } /*if(strstr(prgname, "awesomium_process")==prgname) { printf_log(LOG_INFO, "awesomium_process detected, forcing emulated libpng12\n"); AddPath("libpng12.so.0", &my_context->box64_emulated_libs, 0); @@ -1317,6 +1319,8 @@ int main(int argc, const char **argv, char **env) { /*if(!strcmp(prgname, "gdb")) { exit(-1); }*/ + ApplyParams("*"); // [*] is a special setting for all process + ApplyParams(prgname); for(int i=1; i<my_context->argc; ++i) { my_context->argv[i] = box_strdup(argv[i+nextarg]); diff --git a/src/tools/fileutils.c b/src/tools/fileutils.c index 04905c04..d6d15568 100755 --- a/src/tools/fileutils.c +++ b/src/tools/fileutils.c @@ -134,6 +134,18 @@ const char* GetTmpDir() { return "/tmp"; // meh... } +char* LowerCase(const char* s) { + if(!s) + return NULL; + char* ret = box_calloc(1, strlen(s)+1); + size_t i=0; + while(*s) { + ret[i++] = (*s>='A' && *s<='Z')?(*s-'A'+'a'):(*s); + ++s; + } + + return ret; +} #if defined(RPI) || defined(RK3399) || defined(RK3326) void sanitize_mojosetup_gtk_background() diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c new file mode 100644 index 00000000..fe2f8ca4 --- /dev/null +++ b/src/tools/rcfile.c @@ -0,0 +1,454 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> + +#include "debug.h" +#include "rcfile.h" +#include "box64context.h" +#include "fileutils.h" +#include "pathcoll.h" +#ifdef HAVE_TRACE +#include "x64trace.h" +#endif +#include "custommem.h" +#include "khash.h" + +// This file handle the box64rc files +// file are basicaly ini file, with section [XXXX] defining the name of the process +// and BOX64_XXXX=YYYY entry like the env. var. variables + +// list of all entries +#define SUPER1() \ +ENTRYINTPOS(BOX64_ROLLING_LOG, cycle_log) \ +ENTRYSTRING_(BOX64_LD_LIBRARY_PATH, ld_library_path) \ +ENTRYSTRING_(BOX64_PATH, box64_path) \ +ENTRYSTRING_(BOX64_TRACE_FILE, trace_file) \ +ENTRYADDR(BOX64_LOAD_ADDR, box64_load_addr) \ +ENTRYINT(BOX64_LOG, box64_log, 0, 3, 2) \ +ENTRYBOOL(BOX64_DUMP, box64_dump) \ +ENTRYBOOL(BOX64_DLSYM_ERROR, dlsym_error) \ +CENTRYBOOL(BOX64_NOSIGSEGV, no_sigsegv) \ +CENTRYBOOL(BOX64_NOSIGILL, no_sigill) \ +ENTRYBOOL(BOX64_SHOWSEGV, box64_showsegv) \ +ENTRYBOOL(BOX64_SHOWBT, box64_showbt) \ +ENTRYBOOL(BOX64_X11THREADS, box64_x11threads) \ +ENTRYBOOL(BOX64_X11GLX, box64_x11glx) \ +ENTRYDSTRING(BOX64_LIBGL, box64_libGL) \ +ENTRYSTRING_(BOX64_EMULATED_LIBS, emulated_libs) \ +ENTRYBOOL(BOX64_ALLOWMISSINGLIBS, allow_missing_libs) \ +ENTRYBOOL(BOX64_PREFER_WRAPPED, box64_prefer_wrapped) \ +ENTRYBOOL(BOX64_PREFER_EMULATED, box64_prefer_emulated) \ +ENTRYBOOL(BOX64_CRASHHANDLER, box64_dummy_crashhandler) \ +ENTRYBOOL(BOX64_NOPULSE, box64_nopulse) \ +ENTRYBOOL(BOX64_NOGTK, box64_nogtk) \ +ENTRYBOOL(BOX64_NOVULKAN, box64_novulkan) \ +ENTRYSTRING_(BOX64_BASH, bash) \ +ENTRYINT(BOX64_JITGDB, jit_gdb, 0, 2, 2) \ + +#ifdef HAVE_TRACE +#define SUPER2() \ +ENTRYSTRING_(BOX64_TRACE, trace) \ +ENTRYULONG(BOX64_TRACE_START, start_cnt) \ +ENTRYSTRING_(BOX64_TRACE_INIT, trace_init) \ +ENTRYBOOL(BOX64_TRACE_XMM, trace_xmm) \ +ENTRYBOOL(BOX64_TRACE_EMM, trace_emm) \ +ENTRYBOOL(BOX64_TRACE_COLOR, trace_regsdiff) \ + +#else +#define SUPER2() \ +IGNORE(BOX64_TRACE) \ +IGNORE(BOX64_TRACE_START) \ +IGNORE(BOX64_TRACE_INIT) \ +IGNORE(BOX64_TRACE_XMM) \ +IGNORE(BOX64_TRACE_EMM) \ +IGNORE(BOX64_TRACE_COLOR) \ + +#endif + +#ifdef DYNAREC +#define SUPER3() \ +ENTRYBOOL(BOX64_DYNAREC, box64_dynarec) \ +ENTRYINT(BOX64_DYNAREC_DUMP, box64_dynarec_dump, 0, 2, 2) \ +ENTRYINT(BOX64_DYNAREC_LOG, box64_dynarec_log, 0, 3, 2) \ +ENTRYBOOL(BOX64_DYNAREC_TRACE, box64_dynarec_trace) \ +ENTRYINT(BOX64_DYNAREC_BIGBLOCK, box64_dynarec_bigblock, 0, 3, 2) \ +ENTRYINT(BOX64_DYNAREC_STRONGMEM, box64_dynarec_strongmem, 0, 2, 2) \ +ENTRYBOOL(BOX64_DYNAREC_X87DOUBLE, box64_dynarec_x87double) \ +ENTRYBOOL(BOX64_DYNAREC_FASTNAN, box64_dynarec_fastnan) \ +ENTRYINT(BOX64_DYNAREC_SAFEFLAGS, box64_dynarec_safeflags, 0, 2, 2) \ +ENTRYSTRING_(BOX64_NODYNAREC, box64_nodynarec) \ + +#else +#define SUPER3() \ +IGNORE(BOX64_DYNAREC) \ +IGNORE(BOX64_DYNAREC_DUMP) \ +IGNORE(BOX64_DYNAREC_LOG) \ +IGNORE(BOX64_DYNAREC_TRACE) \ +IGNORE(BOX64_DYNAREC_BIGBLOCK) \ +IGNORE(BOX64_DYNAREC_STRONGMEM) \ +IGNORE(BOX64_DYNAREC_X87DOUBLE) \ +IGNORE(BOX64_DYNAREC_FASTNAN) \ +IGNORE(BOX64_DYNAREC_SAFEFLAGS) \ +IGNORE(BOX64_NODYNAREC) \ + +#endif + +#define SUPER() \ +SUPER1() \ +SUPER2() \ +SUPER3() + +typedef struct my_params_s { +// is present part +#define ENTRYBOOL(NAME, name) uint8_t is_##name##_present:1; +#define CENTRYBOOL(NAME, name) uint8_t is_##name##_present:1; +#define ENTRYINT(NAME, name, minval, maxval, bits) uint8_t is_##name##_present:1; +#define ENTRYINTPOS(NAME, name) uint8_t is_##name##_present:1; +#define ENTRYSTRING(NAME, name) uint8_t is_##name##_present:1; +#define ENTRYSTRING_(NAME, name) uint8_t is_##name##_present:1; +#define ENTRYDSTRING(NAME, name) uint8_t is_##name##_present:1; +#define ENTRYADDR(NAME, name) uint8_t is_##name##_present:1; +#define ENTRYULONG(NAME, name) uint8_t is_##name##_present:1; +#define IGNORE(NAME) +SUPER() +// done +#undef ENTRYBOOL +#undef CENTRYBOOL +#undef ENTRYINT +#undef ENTRYINTPOS +#undef ENTRYSTRING +#undef ENTRYSTRING_ +#undef ENTRYDSTRING +#undef ENTRYADDR +#undef ENTRYULONG +// the actual fields +#define ENTRYBOOL(NAME, name) uint8_t name:1; +#define CENTRYBOOL(NAME, name) uint8_t name:1; +#define ENTRYINT(NAME, name, minval, maxval, bits) uint8_t name:bits; +#define ENTRYINTPOS(NAME, name) uint32_t name; +#define ENTRYSTRING(NAME, name) char* name; +#define ENTRYSTRING_(NAME, name) char* name; +#define ENTRYDSTRING(NAME, name) char* name; +#define ENTRYADDR(NAME, name) uintptr_t name; +#define ENTRYULONG(NAME, name) uint64_t name; +SUPER() +// done +#undef ENTRYBOOL +#undef CENTRYBOOL +#undef ENTRYINT +#undef ENTRYINTPOS +#undef ENTRYSTRING +#undef ENTRYSTRING_ +#undef ENTRYDSTRING +#undef ENTRYADDR +#undef ENTRYULONG +} my_params_t; + +KHASH_MAP_INIT_STR(params, my_params_t) + +static kh_params_t *params = NULL; + +static void clearParam(my_params_t* param) +{ + #define ENTRYBOOL(NAME, name) + #define CENTRYBOOL(NAME, name) + #define ENTRYINT(NAME, name, minval, maxval, bits) + #define ENTRYINTPOS(NAME, name) + #define ENTRYSTRING(NAME, name) free(param->name); + #define ENTRYSTRING_(NAME, name) free(param->name); + #define ENTRYDSTRING(NAME, name) free(param->name); + #define ENTRYADDR(NAME, name) + #define ENTRYULONG(NAME, name) + SUPER() + #undef ENTRYBOOL + #undef CENTRYBOOL + #undef ENTRYINT + #undef ENTRYINTPOS + #undef ENTRYSTRING + #undef ENTRYSTRING_ + #undef ENTRYDSTRING + #undef ENTRYADDR + #undef ENTRYULONG +} + +static void addParam(const char* name, my_params_t* param) +{ + khint_t k; + int ret; + k = kh_get(params, params, name); + const char* oldkey = (k!=kh_end(params))?kh_key(params, k):NULL; + k = kh_put(params, params, strdup(name), &ret); + my_params_t *p = &kh_value(params, k); + if(!ret) + clearParam(p); + if(oldkey) + free((void*)oldkey); + memcpy(p, param, sizeof(my_params_t)); +} + +static void trimString(char* s) +{ + if(!s) + return; + // trim right space/tab + size_t len = strlen(s); + while(len && (s[len-1]==' ' || s[len-1]=='\t')) + s[--len] = '\0'; + // trim left space/tab + while(s[0]==' ' || s[0]=='\t') + memmove(s, s+1, strlen(s)); +} + +void LoadRCFile(const char* filename) +{ + FILE *f = fopen(filename, "r"); + if(!f) { + printf_log(LOG_INFO, "Cannot open RC file %s\n", filename); + return; + } + // init the hash table if needed + if(!params) + params = kh_init(params); + // prepare to parse the file + char* line = NULL; + size_t lsize = 0; + my_params_t current_param = {0}; + char* current_name = NULL; + int dummy; + size_t len; + char* p; + // parsing + while ((dummy = getline(&line, &lsize, f)) != -1) { + // remove comments + if((p=strchr(line, '#'))) + *p = '\0'; + trimString(line); + len = strlen(line); + // check the line content + if(line[0]=='[' && strchr(line, ']')) { + // new entry, will need to add current one + if(current_name) + addParam(current_name, ¤t_param); + // prepare a new entry + memset(¤t_param, 0, sizeof(current_param)); + free(current_name); + current_name = LowerCase(line+1); + *strchr(current_name, ']') = '\0'; + trimString(current_name); + } else if(strchr(line, '=')) { + // actual parameters + //get the key and val + char* key = line; + char* val = strchr(key, '=')+1; + *strchr(key, '=') = '\0'; + trimString(key); + trimString(val); + // extract, check and set arg + #define ENTRYINT(NAME, name, minval, maxval, bits) \ + else if(!strcmp(key, #NAME)) { \ + int v = strtol(val, &p, 0); \ + if(p!=val && v>=minval && v<=maxval) { \ + current_param.is_##name##_present = 1; \ + current_param.name = v; \ + } \ + } + #define ENTRYBOOL(NAME, name) ENTRYINT(NAME, name, 0, 1, 1) + #define CENTRYBOOL(NAME, name) ENTRYBOOL(NAME, name) + #define ENTRYINTPOS(NAME, name) \ + else if(!strcmp(key, #NAME)) { \ + int v = strtol(val, &p, 0); \ + if(p!=val) { \ + current_param.is_##name##_present = 1; \ + current_param.name = v; \ + } \ + } + #define ENTRYSTRING(NAME, name) \ + else if(!strcmp(key, #NAME)) { \ + current_param.is_##name##_present = 1; \ + if(current_param.name) free(current_param.name); \ + current_param.name = strdup(val); \ + } + #define ENTRYSTRING_(NAME, name) ENTRYSTRING(NAME, name) + #define ENTRYDSTRING(NAME, name) ENTRYSTRING(NAME, name) + #define ENTRYADDR(NAME, name) \ + else if(!strcmp(key, #NAME)) { \ + uintptr_t v = strtoul(val, &p, 0); \ + if(p!=val) { \ + current_param.is_##name##_present = 1; \ + current_param.name = v; \ + } \ + } + #define ENTRYULONG(NAME, name) \ + else if(!strcmp(key, #NAME)) { \ + uint64_t v = strtoull(val, &p, 0); \ + if(p!=val) { \ + current_param.is_##name##_present = 1; \ + current_param.name = v; \ + } \ + } + #undef IGNORE + #define IGNORE(NAME) else if(!strcmp(key, #NAME)) ; + if(0) ; + SUPER() + else if(len && current_name) { + printf_log(LOG_INFO, "Warning, unsupported %s=%s for [%s] in %s", key, val, current_name, filename); + } + #undef ENTRYBOOL + #undef CENTRYBOOL + #undef ENTRYINT + #undef ENTRYINTPOS + #undef ENTRYSTRING + #undef ENTRYSTRING_ + #undef ENTRYDSTRING + #undef ENTRYADDR + #undef ENTRYULONG + #undef IGNORE + #define IGNORE(NAME) + } + } + // last entry to be pushed too + if(current_name) + addParam(current_name, ¤t_param); + free(line); + printf_log(LOG_INFO, "Params database has %d entries\n", kh_size(params)); +} + +void DeleteParams() +{ + if(!params) + return; + + // free strings + my_params_t* p; + // need to free duplicated strings + kh_foreach_value_ref(params, p, clearParam(p)); + const char* key; + kh_foreach_key(params, key, free((void*)key)); + // free the hash itself + kh_destroy(params, params); + params = NULL; +} + +extern int ftrace_has_pid; +void openFTrace(const char* newtrace); +#ifdef DYNAREC +void GatherDynarecExtensions(); +#endif +#ifdef HAVE_TRACE +void setupTraceInit(); +void setupTrace(); +#endif +void ApplyParams(const char* name) +{ + if(!name || !params) + return; + static const char* old_name = NULL; + if(old_name && !strcmp(name, old_name)) { + return; + } + old_name = name; + khint_t k; + { + char* lname = LowerCase(name); + k = kh_get(params, params, lname); + free(lname); + } + if(k == kh_end(params)) + return; + my_params_t* param = &kh_value(params, k); + #ifdef DYNAREC + int olddynarec = box64_dynarec; + #endif + printf_log(LOG_INFO, "Apply RC params for %s\n", name); + #define ENTRYINT(NAME, name, minval, maxval, bits) if(param->is_##name##_present) {name = param->name; printf_log(LOG_INFO, "Applying %s=%d\n", #NAME, param->name);} + #define ENTRYBOOL(NAME, name) ENTRYINT(NAME, name, 0, 1, 1) + #define CENTRYBOOL(NAME, name) if(param->is_##name##_present) {my_context->name = param->name; printf_log(LOG_INFO, "Applying %s=%d\n", #NAME, param->name);} + #define ENTRYINTPOS(NAME, name) if(param->is_##name##_present) {name = param->name; printf_log(LOG_INFO, "Applying %s=%d\n", #NAME, param->name);} + #define ENTRYSTRING(NAME, name) if(param->is_##name##_present) {name = param->name; printf_log(LOG_INFO, "Applying %s=%s\n", #NAME, param->name);} + #define ENTRYSTRING_(NAME, name) + #define ENTRYDSTRING(NAME, name) if(param->is_##name##_present) {if(name) free(name); name = strdup(param->name); printf_log(LOG_INFO, "Applying %s=%s\n", #NAME, param->name);} + #define ENTRYADDR(NAME, name) if(param->is_##name##_present) {name = param->name; printf_log(LOG_INFO, "Applying %s=%zd\n", #NAME, param->name);} + #define ENTRYULONG(NAME, name) if(param->is_##name##_present) {name = param->name; printf_log(LOG_INFO, "Applying %s=%lld\n", #NAME, param->name);} + SUPER() + #undef ENTRYBOOL + #undef CENTRYBOOL + #undef ENTRYINT + #undef ENTRYINTPOS + #undef ENTRYSTRING + #undef ENTRYSTRING_ + #undef ENTRYDSTRING + #undef ENTRYADDR + #undef ENTRYULONG + // now handle the manuel entry (the one with ending underscore) + if(param->is_ld_library_path_present) AppendList(&my_context->box64_ld_lib, param->ld_library_path, 1); + if(param->is_box64_path_present) AppendList(&my_context->box64_path, param->box64_path, 1); + if(param->is_trace_file_present) { + if(ftrace_has_pid) { + // open a new ftrace... + fclose(ftrace); + openFTrace(param->trace_file); + } + } + if(param->is_emulated_libs_present) { + AppendList(&my_context->box64_emulated_libs, param->emulated_libs, 0); + printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_EMULATED_LIBS", param->emulated_libs); + } + if(param->is_bash_present && FileIsX64ELF(param->bash)) { + if(my_context->bashpath) + free(my_context->bashpath); + my_context->bashpath = strdup(param->bash); + printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_BASH", param->bash); + } + #ifdef HAVE_TRACE + int old_x64trace = my_context->x64trace; + if(param->is_trace_present) { + char*p = param->trace; + if (strcmp(p, "0")) { + my_context->x64trace = 1; + box64_trace = p; + } + printf_log(LOG_INFO, "Applying %s=%d", "BOX64_TRACE", param->trace); + } + if(param->is_trace_init_present) { + char* p = param->trace_init; + if (strcmp(p, "0")) { + my_context->x64trace = 1; + trace_init = p; + } + printf_log(LOG_INFO, "Applying %s=%d", "BOX64_TRACE_INIT", param->trace_init); + } + if(my_context->x64trace && !old_x64trace) { + printf_log(LOG_INFO, "Initializing Zydis lib\n"); + if(InitX64Trace(my_context)) { + printf_log(LOG_INFO, "Zydis init failed, no x86 trace activated\n"); + my_context->x64trace = 0; + } + } + if(param->is_trace_init_present) + setupTraceInit(); + if(param->is_trace_present) + setupTrace(); + #endif + #ifdef DYNAREC + if(param->is_box64_nodynarec_present) { + uintptr_t no_start = 0, no_end = 0; + char* p; + no_start = strtoul(param->box64_nodynarec, &p, 0); + if(p!=param->box64_nodynarec) { + char* p2; + no_end = strtoul(p, &p2, 0); + if(p2!=p && no_end>no_start) { + box64_nodynarec_start = no_start; + box64_nodynarec_end = no_end; + printf_log(LOG_INFO, "Appling BOX64_NODYNAREC=%p-%p\n", (void*)box64_nodynarec_start, (void*)box64_nodynarec_end); + } + } + } + if(!olddynarec && box64_dynarec) + GatherDynarecExtensions(); + #endif + if(box64_log==3) { + box64_log = 2; + box64_dump = 1; + } +} \ No newline at end of file diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt index 4ca5da07..d3449255 100644 --- a/src/wrapped/generated/functions_list.txt +++ b/src/wrapped/generated/functions_list.txt @@ -1167,7 +1167,6 @@ #() iFiiupp #() iFiipup #() iFiuLip -#() iFiLLLL #() iFipiii #() iFipiup #() iFipipi @@ -1475,6 +1474,7 @@ #() cFppLppi #() iFEiippi #() iFEiippp +#() iFEiLLLL #() iFEippLp #() iFElpppp #() iFEpiipp @@ -3129,6 +3129,8 @@ wrappedlibc: - iFiippi: - __fxstatat - __fxstatat64 +- iFiLLLL: + - prctl - iFipiip: - epoll_pwait - iFipppp: diff --git a/src/wrapped/generated/wrappedlibctypes.h b/src/wrapped/generated/wrappedlibctypes.h index 9352b479..d27b57b8 100644 --- a/src/wrapped/generated/wrappedlibctypes.h +++ b/src/wrapped/generated/wrappedlibctypes.h @@ -72,6 +72,7 @@ typedef int64_t (*iFppiV_t)(void*, void*, int64_t, ...); typedef int64_t (*iFpppp_t)(void*, void*, void*, void*); typedef void (*vFpLLpp_t)(void*, uintptr_t, uintptr_t, void*, void*); typedef int64_t (*iFiippi_t)(int64_t, int64_t, void*, void*, int64_t); +typedef int64_t (*iFiLLLL_t)(int64_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); typedef int64_t (*iFipiip_t)(int64_t, void*, int64_t, int64_t, void*); typedef int64_t (*iFipppp_t)(int64_t, void*, void*, void*, void*); typedef int64_t (*iFpilpV_t)(void*, int64_t, intptr_t, void*, ...); @@ -237,6 +238,7 @@ typedef int64_t (*iFppipppp_t)(void*, void*, int64_t, void*, void*, void*, void* GO(qsort_r, vFpLLpp_t) \ GO(__fxstatat, iFiippi_t) \ GO(__fxstatat64, iFiippi_t) \ + GO(prctl, iFiLLLL_t) \ GO(epoll_pwait, iFipiip_t) \ GO(getopt_long, iFipppp_t) \ GO(getopt_long_only, iFipppp_t) \ diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c index e5575136..34225b54 100644 --- a/src/wrapped/generated/wrapper.c +++ b/src/wrapped/generated/wrapper.c @@ -1201,7 +1201,6 @@ typedef int64_t (*iFiiipp_t)(int64_t, int64_t, int64_t, void*, void*); typedef int64_t (*iFiiupp_t)(int64_t, int64_t, uint64_t, void*, void*); typedef int64_t (*iFiipup_t)(int64_t, int64_t, void*, uint64_t, void*); typedef int64_t (*iFiuLip_t)(int64_t, uint64_t, uintptr_t, int64_t, void*); -typedef int64_t (*iFiLLLL_t)(int64_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); typedef int64_t (*iFipiii_t)(int64_t, void*, int64_t, int64_t, int64_t); typedef int64_t (*iFipiup_t)(int64_t, void*, int64_t, uint64_t, void*); typedef int64_t (*iFipipi_t)(int64_t, void*, int64_t, void*, int64_t); @@ -1509,6 +1508,7 @@ typedef void (*vFpppppp_t)(void*, void*, void*, void*, void*, void*); typedef int8_t (*cFppLppi_t)(void*, void*, uintptr_t, void*, void*, int64_t); typedef int64_t (*iFEiippi_t)(x64emu_t*, int64_t, int64_t, void*, void*, int64_t); typedef int64_t (*iFEiippp_t)(x64emu_t*, int64_t, int64_t, void*, void*, void*); +typedef int64_t (*iFEiLLLL_t)(x64emu_t*, int64_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); typedef int64_t (*iFEippLp_t)(x64emu_t*, int64_t, void*, void*, uintptr_t, void*); typedef int64_t (*iFElpppp_t)(x64emu_t*, intptr_t, void*, void*, void*, void*); typedef int64_t (*iFEpiipp_t)(x64emu_t*, void*, int64_t, int64_t, void*, void*); @@ -3450,7 +3450,6 @@ void iFiiipp(x64emu_t *emu, uintptr_t fcn) { iFiiipp_t fn = (iFiiipp_t)fcn; R_RA void iFiiupp(x64emu_t *emu, uintptr_t fcn) { iFiiupp_t fn = (iFiiupp_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (int64_t)R_RSI, (uint64_t)R_RDX, (void*)R_RCX, (void*)R_R8); } void iFiipup(x64emu_t *emu, uintptr_t fcn) { iFiipup_t fn = (iFiipup_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (uint64_t)R_RCX, (void*)R_R8); } void iFiuLip(x64emu_t *emu, uintptr_t fcn) { iFiuLip_t fn = (iFiuLip_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (uint64_t)R_RSI, (uintptr_t)R_RDX, (int64_t)R_RCX, (void*)R_R8); } -void iFiLLLL(x64emu_t *emu, uintptr_t fcn) { iFiLLLL_t fn = (iFiLLLL_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8); } void iFipiii(x64emu_t *emu, uintptr_t fcn) { iFipiii_t fn = (iFipiii_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8); } void iFipiup(x64emu_t *emu, uintptr_t fcn) { iFipiup_t fn = (iFipiup_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (uint64_t)R_RCX, (void*)R_R8); } void iFipipi(x64emu_t *emu, uintptr_t fcn) { iFipipi_t fn = (iFipipi_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (void*)R_RCX, (int64_t)R_R8); } @@ -3758,6 +3757,7 @@ void vFpppppp(x64emu_t *emu, uintptr_t fcn) { vFpppppp_t fn = (vFpppppp_t)fcn; f void cFppLppi(x64emu_t *emu, uintptr_t fcn) { cFppLppi_t fn = (cFppLppi_t)fcn; R_RAX=fn((void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (void*)R_RCX, (void*)R_R8, (int64_t)R_R9); } void iFEiippi(x64emu_t *emu, uintptr_t fcn) { iFEiippi_t fn = (iFEiippi_t)fcn; R_RAX=(int64_t)fn(emu, (int64_t)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (int64_t)R_R8); } void iFEiippp(x64emu_t *emu, uintptr_t fcn) { iFEiippp_t fn = (iFEiippp_t)fcn; R_RAX=(int64_t)fn(emu, (int64_t)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8); } +void iFEiLLLL(x64emu_t *emu, uintptr_t fcn) { iFEiLLLL_t fn = (iFEiLLLL_t)fcn; R_RAX=(int64_t)fn(emu, (int64_t)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8); } void iFEippLp(x64emu_t *emu, uintptr_t fcn) { iFEippLp_t fn = (iFEippLp_t)fcn; R_RAX=(int64_t)fn(emu, (int64_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX, (void*)R_R8); } void iFElpppp(x64emu_t *emu, uintptr_t fcn) { iFElpppp_t fn = (iFElpppp_t)fcn; R_RAX=(int64_t)fn(emu, (intptr_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8); } void iFEpiipp(x64emu_t *emu, uintptr_t fcn) { iFEpiipp_t fn = (iFEpiipp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (void*)R_RCX, (void*)R_R8); } @@ -5526,7 +5526,6 @@ int isSimpleWrapper(wrapper_t fun) { if (fun == &iFiiupp) return 1; if (fun == &iFiipup) return 1; if (fun == &iFiuLip) return 1; - if (fun == &iFiLLLL) return 1; if (fun == &iFipiii) return 1; if (fun == &iFipiup) return 1; if (fun == &iFipipi) return 1; diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h index df3f84a0..31d952b6 100644 --- a/src/wrapped/generated/wrapper.h +++ b/src/wrapped/generated/wrapper.h @@ -1200,7 +1200,6 @@ void iFiiipp(x64emu_t *emu, uintptr_t fnc); void iFiiupp(x64emu_t *emu, uintptr_t fnc); void iFiipup(x64emu_t *emu, uintptr_t fnc); void iFiuLip(x64emu_t *emu, uintptr_t fnc); -void iFiLLLL(x64emu_t *emu, uintptr_t fnc); void iFipiii(x64emu_t *emu, uintptr_t fnc); void iFipiup(x64emu_t *emu, uintptr_t fnc); void iFipipi(x64emu_t *emu, uintptr_t fnc); @@ -1508,6 +1507,7 @@ void vFpppppp(x64emu_t *emu, uintptr_t fnc); void cFppLppi(x64emu_t *emu, uintptr_t fnc); void iFEiippi(x64emu_t *emu, uintptr_t fnc); void iFEiippp(x64emu_t *emu, uintptr_t fnc); +void iFEiLLLL(x64emu_t *emu, uintptr_t fnc); void iFEippLp(x64emu_t *emu, uintptr_t fnc); void iFElpppp(x64emu_t *emu, uintptr_t fnc); void iFEpiipp(x64emu_t *emu, uintptr_t fnc); diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index d1d686b1..6d7169bb 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -38,6 +38,7 @@ #include <syslog.h> #include <malloc.h> #include <getopt.h> +#include <sys/prctl.h> #undef LOG_INFO #undef LOG_DEBUG @@ -60,6 +61,7 @@ #include "elfloader.h" #include "bridge.h" #include "globalsymbols.h" +#include "rcfile.h" #define LIBNAME libc const char* libcName = "libc.so.6"; @@ -2969,6 +2971,15 @@ EXPORT void my_exit(x64emu_t* emu, int code) EXPORT void my__exit(x64emu_t* emu, int code) __attribute__((alias("my_exit"))); +EXPORT int my_prctl(x64emu_t* emu, int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) +{ + if(option==PR_SET_NAME) { + printf_log(LOG_DEBUG, "BOX64: set process name to \"%s\"\n", (char*)arg2); + ApplyParams((char*)arg2); + } + return prctl(option, arg2, arg3, arg4, arg5); +} + EXPORT char* my___progname = NULL; EXPORT char* my___progname_full = NULL; diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h index 066596b4..6c5dcdd3 100755 --- a/src/wrapped/wrappedlibc_private.h +++ b/src/wrapped/wrappedlibc_private.h @@ -1358,7 +1358,7 @@ GOW(posix_spawn_file_actions_init, iFp) GOM(posix_spawnp, iFEpppppp) GO(ppoll, iFpLpp) //GO(__ppoll_chk, -GOW(prctl, iFiLLLL) +GOWM(prctl, iFEiLLLL) GOW(pread, lFipLl) GOW(__pread64, lFipLI) GOW(pread64, lFipLl) diff --git a/src/wrapped/wrappedlibgl.c b/src/wrapped/wrappedlibgl.c index 63d30938..9875847c 100755 --- a/src/wrapped/wrappedlibgl.c +++ b/src/wrapped/wrappedlibgl.c @@ -16,8 +16,6 @@ #include "librarian.h" #include "callback.h" -extern char* libGL; - const char* libglName = "libGL.so.1"; #define LIBNAME libgl @@ -198,7 +196,7 @@ EXPORT void* my_glGetVkProcAddrNV(x64emu_t* emu, void* name) return my_GetVkProcAddr(emu, name, GetVkProcAddrNV); } -#define PRE_INIT if(libGL) {lib->w.lib = dlopen(libGL, RTLD_LAZY | RTLD_GLOBAL); lib->path = strdup(libGL);} else +#define PRE_INIT if(box64_libGL) {lib->w.lib = dlopen(box64_libGL, RTLD_LAZY | RTLD_GLOBAL); lib->path = strdup(box64_libGL);} else #define CUSTOM_INIT \ lib->w.priv = dlsym(lib->w.lib, "glXGetProcAddress"); \ if (!box64->glxprocaddress) \ diff --git a/src/wrapped/wrappedlibx11.c b/src/wrapped/wrappedlibx11.c index 2545cbd2..bf74a1c6 100755 --- a/src/wrapped/wrappedlibx11.c +++ b/src/wrapped/wrappedlibx11.c @@ -20,9 +20,6 @@ const char* libx11Name = "libX11.so.6"; #define LIBNAME libx11 -extern int x11threads; -extern int x11glx; - typedef int (*XErrorHandler)(void *, void *); void* my_XSetErrorHandler(x64emu_t* t, XErrorHandler handler); typedef int (*XIOErrorHandler)(void *); @@ -915,7 +912,7 @@ EXPORT int my_XUnregisterIMInstantiateCallback(x64emu_t* emu, void* d, void* db, EXPORT int my_XQueryExtension(x64emu_t* emu, void* display, char* name, int* major, int* first_event, int* first_error) { int ret = my->XQueryExtension(display, name, major, first_event, first_error); - if(!ret && name && !strcmp(name, "GLX") && x11glx) { + if(!ret && name && !strcmp(name, "GLX") && box64_x11glx) { // hack to force GLX to be accepted, even if not present // left major and first_XXX to default... ret = 1; @@ -1154,7 +1151,7 @@ EXPORT void* my_XOpenDisplay(x64emu_t* emu, void* d) #define CUSTOM_INIT \ getMy(lib); \ - if(x11threads) my->XInitThreads(); + if(box64_x11threads) my->XInitThreads(); #define CUSTOM_FINI \ freeMy(); diff --git a/src/wrapped/wrappedsdl2.c b/src/wrapped/wrappedsdl2.c index 6de8b907..d68ca1a9 100755 --- a/src/wrapped/wrappedsdl2.c +++ b/src/wrapped/wrappedsdl2.c @@ -646,7 +646,6 @@ EXPORT void my2_SDL_Log(x64emu_t* emu, void* fmt, void *b) { } void fillGLProcWrapper(box64context_t*); -extern char* libGL; EXPORT void* my2_SDL_GL_GetProcAddress(x64emu_t* emu, void* name) { khint_t k; @@ -658,9 +657,9 @@ EXPORT void* my2_SDL_GL_GetProcAddress(x64emu_t* emu, void* name) if(!emu->context->glwrappers) { fillGLProcWrapper(emu->context); // check if libGL is loaded, load it if not (helps DeadCells) - if(!my_glhandle && !GetLibInternal(libGL?libGL:"libGL.so.1")) { + if(!my_glhandle && !GetLibInternal(box64_libGL?box64_libGL:"libGL.so.1")) { // use a my_dlopen to actually open that lib, like SDL2 is doing... - my_glhandle = my_dlopen(emu, libGL?libGL:"libGL.so.1", RTLD_LAZY|RTLD_GLOBAL); + my_glhandle = my_dlopen(emu, box64_libGL?box64_libGL:"libGL.so.1", RTLD_LAZY|RTLD_GLOBAL); } } // get proc adress using actual glXGetProcAddress diff --git a/system/box64.box64rc b/system/box64.box64rc new file mode 100644 index 00000000..cbf7fa5f --- /dev/null +++ b/system/box64.box64rc @@ -0,0 +1,34 @@ +# System-wide .box64rc + +# Note that process name are case insensitive! + +# +# Linux process +# + +[7z] +# Those are safe to use on 7z and give a bit of a boost +BOX64_DYNAREC_SAFEFLAGS=0 +BOX64_DYNAREC_BIGBLOCK=2 + +[dontstarve] +# use emulated sdl2 +BOX64_EMULATED_LIBS=libSDL2-2.0.so.0 + +[dota2] +BOX64_CRASHHANDLER=1 +BOX64_DYNAREC_STRONGMEM=1 + +[pressure-vessel-wrap] +BOX64_NOGTK=1 + +[steam] +BOX64_CRASHHANDLER=1 +BOX64_EMULATED_LIBS=libudev.so.0 + +[streaming_client] +BOX64_EMULATED_LIBS=libSDL2-2.0.so.0:libSDL2_ttf-2.0.so.0 + +# +# Wine process +# |