#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#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"
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"
;
#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_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 {
#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()
#undef ENTRYBOOL
#undef CENTRYBOOL
#undef ENTRYINT
#undef ENTRYINTPOS
#undef ENTRYSTRING
#undef ENTRYSTRING_
#undef ENTRYDSTRING
#undef ENTRYADDR
#undef ENTRYULONG
#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()
#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()
#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;
size_t len = strlen(s);
while(len && (s[len-1]==' ' || s[len-1]=='\t' || s[len-1]=='\n'))
s[--len] = '\0';
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;
shm_unlink(TMP_MEMRCFILE);
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;
}
if(!params)
params = kh_init(params);
char* line = NULL;
size_t lsize = 0;
my_params_t current_param = {0};
char* current_name = NULL;
int dummy;
size_t len;
char* p;
while ((dummy = getline(&line, &lsize, f)) != -1) {
if((p=strchr(line, '#')))
*p = '\0';
trimString(line);
len = strlen(line);
if(line[0]=='[' && strchr(line, ']')) {
if(current_name)
addParam(current_name, ¤t_param);
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, '=')) {
char* key = line;
char* val = strchr(key, '=')+1;
*strchr(key, '=') = '\0';
trimString(key);
trimString(val);
#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)
}
}
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;
my_params_t* p;
kh_foreach_value_ref(params, p, clearParam(p));
const char* key;
kh_foreach_key(params, key, free((void*)key));
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
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, "Hidding 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_maxcpu<new_maxcpu) {
printf_log(LOG_INFO, "Not applying BOX64_MAXCPU=%d because a lesser value is already active: %d\n", new_maxcpu, box64_maxcpu);
} else
box64_maxcpu = new_maxcpu;
} else if(new_maxcpu!=box64_maxcpu)
printf_log(LOG_INFO, "Not applying BOX64_MAXCPU=%d because it's too late\n", new_maxcpu);
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) {
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;
}
}