#include #include #include #include #include #include #include "debug.h" #include "rcfile.h" #include "box64context.h" #include "fileutils.h" #include "pathcoll.h" #include "x64emu.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 // default rcfile static const char default_rcfile[] = "[bash]\n" "BOX64_LOG=0\n" "\n" "[deadcells]\n" "BOX64_PREFER_EMULATED=1\n" "\n" "[dontstarve]\n" "BOX64_EMULATED_LIBS=libSDL2-2.0.so.0\n" "\n" "[dota2]\n" "BOX64_CRASHHANDLER=1\n" "BOX64_DYNAREC_STRONGMEM=1\n" "\n" "[factorio]\n" "BOX64_DYNAREC_FASTROUND=0\n" "\n" "[heroic]\n" "BOX64_NOSANDBOX=1\n" "BOX64_MALLOC_HACK=2\n" "\n" "[LotCG.x86_64]\n" "BOX64_DYNAREC_FASTROUND=0\n" "\n" "[Mini Metro]\n" "BOX64_ADDLIBS=stdc++.so.6\n" "\n" "[pressure-vessel-wrap]\n" "BOX64_NOGTK=1\n" "\n" "[ShovelKnight]\n" "BOX64_SDL2_JGUID=1\n" "\n" "[Soma.bin.x86_64]\n" "BOX64_DYNAREC_FASTROUND=0\n" "\n" "[streaming_client]\n" "BOX64_EMULATED_LIBS=libSDL2-2.0.so.0:libSDL2_ttf-2.0.so.0\n" "\n" "[steam-runtime-check-requirements]\n" "BOX64_EXIT=1\n" "\n" "[steam-runtime-launcher-service]\n" "BOX64_EXIT=1\n" ; // list of all entries #define SUPER1() \ ENTRYINTPOS(BOX64_ROLLING_LOG, new_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_MMAP32, box64_mmap32) \ ENTRYBOOL(BOX64_IGNOREINT3, box64_ignoreint3) \ IGNORE(BOX64_RDTSC) \ ENTRYBOOL(BOX64_X11THREADS, box64_x11threads) \ ENTRYBOOL(BOX64_X11GLX, box64_x11glx) \ ENTRYDSTRING(BOX64_LIBGL, box64_libGL) \ ENTRYBOOL(BOX64_SSE_FLUSHTO0, box64_sse_flushto0) \ ENTRYBOOL(BOX64_X87_NO80BITS, box64_x87_no80bits) \ ENTRYBOOL(BOX64_SYNC_ROUNDING, box64_sync_rounding) \ 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) \ ENTRYBOOL(BOX64_RDTSC_1GHZ, box64_rdtsc_1ghz) \ ENTRYBOOL(BOX64_SHAEXT, box64_shaext) \ ENTRYBOOL(BOX64_SSE42, box64_sse42) \ ENTRYINT(BOX64_AVX, new_avx, 0, 2, 2) \ ENTRYBOOL(BOX64_FUTEX_WAITV, box64_futex_waitv) \ ENTRYSTRING_(BOX64_BASH, bash) \ ENTRYINT(BOX64_JITGDB, jit_gdb, 0, 3, 2) \ ENTRYBOOL(BOX64_NOSANDBOX, box64_nosandbox) \ ENTRYBOOL(BOX64_INPROCESSGPU, box64_inprocessgpu) \ ENTRYBOOL(BOX64_CEFDISABLEGPU, box64_cefdisablegpu) \ ENTRYBOOL(BOX64_CEFDISABLEGPUCOMPOSITOR, box64_cefdisablegpucompositor)\ ENTRYBOOL(BOX64_EXIT, want_exit) \ ENTRYBOOL(BOX64_LIBCEF, box64_libcef) \ ENTRYBOOL(BOX64_JVM, box64_jvm) \ ENTRYBOOL(BOX64_UNITYPLAYER, box64_unityplayer) \ ENTRYBOOL(BOX64_SDL2_JGUID, box64_sdl2_jguid) \ ENTRYINT(BOX64_MALLOC_HACK, box64_malloc_hack, 0, 2, 2) \ ENTRYINTPOS(BOX64_MAXCPU, new_maxcpu) \ ENTRYSTRING_(BOX64_ADDLIBS, new_addlibs) \ ENTRYSTRING_(BOX64_ENV, new_env) \ ENTRYSTRING_(BOX64_ENV1, new_env1) \ ENTRYSTRING_(BOX64_ENV2, new_env2) \ ENTRYSTRING_(BOX64_ENV3, new_env3) \ ENTRYSTRING_(BOX64_ENV4, new_env4) \ ENTRYBOOL(BOX64_RESERVE_HIGH, new_reserve_high) \ #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) \ ENTRYINT(BOX64_DYNAREC_BIGBLOCK, box64_dynarec_bigblock, 0, 3, 2) \ ENTRYSTRING_(BOX64_DYNAREC_FORWARD, box64_dynarec_forward) \ ENTRYINT(BOX64_DYNAREC_STRONGMEM, box64_dynarec_strongmem, 0, 4, 3) \ ENTRYBOOL(BOX64_DYNAREC_X87DOUBLE, box64_dynarec_x87double) \ ENTRYBOOL(BOX64_DYNAREC_DIV0, box64_dynarec_div0) \ ENTRYBOOL(BOX64_DYNAREC_FASTNAN, box64_dynarec_fastnan) \ ENTRYBOOL(BOX64_DYNAREC_FASTROUND, box64_dynarec_fastround) \ ENTRYINT(BOX64_DYNAREC_SAFEFLAGS, box64_dynarec_safeflags, 0, 2, 2) \ ENTRYBOOL(BOX64_DYNAREC_CALLRET, box64_dynarec_callret) \ ENTRYBOOL(BOX64_DYNAREC_BLEEDING_EDGE, box64_dynarec_bleeding_edge) \ ENTRYBOOL(BOX64_DYNAREC_JVM, box64_dynarec_jvm) \ ENTRYBOOL(BOX64_DYNAREC_TBB, box64_dynarec_tbb) \ IGNORE(BOX64_DYNAREC_HOTPAGE) \ IGNORE(BOX64_DYNAREC_FASTPAGE) \ ENTRYBOOL(BOX64_DYNAREC_ALIGNED_ATOMICS, box64_dynarec_aligned_atomics) \ ENTRYBOOL(BOX64_DYNAREC_WAIT, box64_dynarec_wait) \ ENTRYSTRING_(BOX64_NODYNAREC, box64_nodynarec) \ ENTRYSTRING_(BOX64_DYNAREC_TEST, box64_dynarec_test) \ ENTRYBOOL(BOX64_DYNAREC_MISSING, box64_dynarec_missing) \ #else #define SUPER3() \ IGNORE(BOX64_DYNAREC) \ IGNORE(BOX64_DYNAREC_DUMP) \ IGNORE(BOX64_DYNAREC_LOG) \ IGNORE(BOX64_DYNAREC_BIGBLOCK) \ IGNORE(BOX64_DYNAREC_FORWARD) \ IGNORE(BOX64_DYNAREC_STRONGMEM) \ IGNORE(BOX64_DYNAREC_X87DOUBLE) \ IGNORE(BOX64_DYNAREC_DIV0) \ IGNORE(BOX64_DYNAREC_FASTNAN) \ IGNORE(BOX64_DYNAREC_FASTROUND) \ IGNORE(BOX64_DYNAREC_SAFEFLAGS) \ IGNORE(BOX64_DYNAREC_CALLRET) \ IGNORE(BOX64_DYNAREC_BLEEDING_EDGE) \ IGNORE(BOX64_DYNAREC_JVM) \ IGNORE(BOX64_DYNAREC_TBB) \ IGNORE(BOX64_DYNAREC_HOTPAGE) \ IGNORE(BOX64_DYNAREC_FASTPAGE) \ IGNORE(BOX64_DYNAREC_ALIGNED_ATOMICS) \ IGNORE(BOX64_DYNAREC_WAIT) \ IGNORE(BOX64_NODYNAREC) \ IGNORE(BOX64_DYNAREC_TEST) \ IGNORE(BOX64_DYNAREC_MISSING) \ #endif #if defined(HAVE_TRACE) && defined(DYNAREC) #define SUPER4() \ ENTRYBOOL(BOX64_DYNAREC_TRACE, box64_dynarec_trace) \ #else #define SUPER4() \ IGNORE(BOX64_DYNAREC_TRACE) \ #endif #define SUPER() \ SUPER1() \ SUPER2() \ SUPER3() \ SUPER4() 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, in two steps to regroup bit fields together #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) #define ENTRYSTRING(NAME, name) #define ENTRYSTRING_(NAME, name) #define ENTRYDSTRING(NAME, name) #define ENTRYADDR(NAME, name) #define ENTRYULONG(NAME, name) SUPER() // done #undef ENTRYBOOL #undef CENTRYBOOL #undef ENTRYINT #undef ENTRYINTPOS #undef ENTRYSTRING #undef ENTRYSTRING_ #undef ENTRYDSTRING #undef ENTRYADDR #undef ENTRYULONG #define ENTRYBOOL(NAME, name) #define CENTRYBOOL(NAME, name) #define ENTRYINT(NAME, name, minval, maxval, 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; k = kh_get(params, params, name); if(k==kh_end(params)) { int ret; k = kh_put(params, params, box_strdup(name), &ret); } else { clearParam(&kh_value(params, k)); } my_params_t *p = &kh_value(params, k); 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-1]=='\n')) s[--len] = '\0'; // trim left space/tab while(s[0]==' ' || s[0]=='\t') memmove(s, s+1, strlen(s)); } #ifdef ANDROID static int shm_open(const char *name, int oflag, mode_t mode) { return -1; } static int shm_unlink(const char *name) { return -1; } #endif void LoadRCFile(const char* filename) { FILE *f = NULL; if(filename) f = fopen(filename, "r"); else { #define TMP_MEMRCFILE "/box64_rcfile" int tmp = shm_open(TMP_MEMRCFILE, O_RDWR | O_CREAT, S_IRWXU); if(tmp<0) return; // error, bye bye shm_unlink(TMP_MEMRCFILE); // remove the shm file, but it will still exist because it's currently in use int dummy = write(tmp, default_rcfile, sizeof(default_rcfile)); (void)dummy; lseek(tmp, 0, SEEK_SET); f = fdopen(tmp, "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 = box_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\n", 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(current_name); } free(line); fclose(f); 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; extern FILE* ftrace; extern char* ftrace_name; void openFTrace(const char* newtrace); void addNewEnvVar(const char* s); void AddNewLibs(const char* libs); void computeRDTSC(); void my_reserveHighMem(); #ifdef DYNAREC void GatherDynarecExtensions(); #endif #ifdef HAVE_TRACE void setupTraceInit(); void setupTrace(); #endif static char old_name[256] = ""; const char* GetLastApplyName() { return old_name; } void ApplyParams(const char* name) { if(!name || !params) return; int new_cycle_log = cycle_log; int new_maxcpu = box64_maxcpu; int new_avx = box64_avx2?2:box64_avx; int box64_dynarec_jvm = box64_jvm; int new_reserve_high = 0; if(!strcmp(name, old_name)) { return; } strncpy(old_name, name, 255); 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); int want_exit = 0; #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 = box_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(want_exit) exit(0); if(new_cycle_log==1) new_cycle_log = 16; if(new_cycle_log!=cycle_log) { freeCycleLog(my_context); cycle_log = new_cycle_log; initCycleLog(my_context); } if(new_reserve_high) my_reserveHighMem(); if(param->is_new_avx_present) { if(!new_avx) { printf_log(LOG_INFO, "Hiding AVX extension\n"); box64_avx = 0; box64_avx2 = 0; } else if(new_avx==1) { printf_log(LOG_INFO, "Exposing AVX extension\n"); box64_avx = 1; box64_avx2 = 0; } else if(new_avx==2) { printf_log(LOG_INFO, "Exposing AVX/AVX2 extensions\n"); box64_avx = 1; box64_avx2 = 1; } } if(param->is_box64_rdtsc_1ghz_present) computeRDTSC(); #ifdef DYNAREC if(param->is_box64_dynarec_jvm_present && !param->is_box64_jvm_present) box64_jvm = box64_dynarec_jvm; #endif if(!box64_maxcpu_immutable) { if(new_maxcpu!=box64_maxcpu && box64_maxcpu && box64_maxcpuis_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) { // open a new ftrace... printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_TRACE_FILE", param->trace_file); if(ftrace_name) { 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_new_addlibs_present) { AddNewLibs(param->new_addlibs); } if(param->is_new_env_present) { addNewEnvVar(param->new_env); printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV", param->new_env); } if(param->is_new_env1_present) { addNewEnvVar(param->new_env1); printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV1", param->new_env1); } if(param->is_new_env2_present) { addNewEnvVar(param->new_env2); printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV2", param->new_env2); } if(param->is_new_env3_present) { addNewEnvVar(param->new_env3); printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV3", param->new_env3); } if(param->is_new_env4_present) { addNewEnvVar(param->new_env4); printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV4", param->new_env4); } if(param->is_bash_present && FileIsX64ELF(param->bash)) { if(my_context->bashpath) free(my_context->bashpath); my_context->bashpath = box_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=%s\n", "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=%s\n", "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; int ok = 0; if(sscanf(param->box64_nodynarec, "0x%lX-0x%lX", &no_start, &no_end)==2) ok = 1; if(!ok && sscanf(param->box64_nodynarec, "%lx-%lx", &no_start, &no_end)==2) ok = 1; if(!ok && sscanf(param->box64_nodynarec, "%ld-%ld", &no_start, &no_end)==2) ok = 1; if(ok && 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); } else { printf_log(LOG_INFO, "Ignoring BOX64_NODYNAREC=%s (%p-%p)\n", param->box64_nodynarec, (void*)box64_nodynarec_start, (void*)box64_nodynarec_end); } } if(param->is_box64_dynarec_test_present) { uintptr_t no_start = 0, no_end = 0; if(strlen(param->box64_dynarec_test)==1) { box64_dynarec_test = param->box64_dynarec_test[0]-'0'; box64_dynarec_test_start = 0x0; box64_dynarec_test_end = 0x0; if(box64_dynarec_test>2) box64_dynarec_test = 0; } else { int ok = 0; if(sscanf(param->box64_dynarec_test, "0x%lX-0x%lX", &no_start, &no_end)==2) ok = 1; if(!ok && sscanf(param->box64_dynarec_test, "%lx-%lx", &no_start, &no_end)==2) ok = 1; if(!ok && sscanf(param->box64_dynarec_test, "%ld-%ld", &no_start, &no_end)==2) ok = 1; if(ok && no_end>no_start) { box64_dynarec_test = 1; box64_dynarec_test_start = no_start; box64_dynarec_test_end = no_end; printf_log(LOG_INFO, "Appling BOX64_DYNAREC_TEST=%p-%p\n", (void*)box64_dynarec_test_start, (void*)box64_dynarec_test_end); } else { box64_dynarec_test = 0; printf_log(LOG_INFO, "Ignoring BOX64_DYNAREC_TEST=%s (%p-%p)\n", param->box64_dynarec_test, (void*)box64_dynarec_test_start, (void*)box64_dynarec_test_end); } } } if(param->is_box64_dynarec_forward_present) { int forward = 0; if(sscanf(param->box64_dynarec_forward, "%d", &forward)==1) { box64_dynarec_forward = forward; printf_log(LOG_INFO, "Appling BOX64_DYNAREC_FORWARD=%d\n", box64_dynarec_forward); } } if(!olddynarec && box64_dynarec) GatherDynarecExtensions(); if(param->is_box64_dynarec_test_present && box64_dynarec_test) { box64_dynarec_fastnan = 0; box64_dynarec_fastround = 0; box64_dynarec_x87double = 1; box64_dynarec_div0 = 1; box64_dynarec_callret = 0; } #endif if(box64_log==3) { box64_log = 2; box64_dump = 1; } }