diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-01-21 23:13:51 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-21 16:13:51 +0100 |
| commit | 044dec0bfa0f3f8f62f7703d6b0a8600c1354dc5 (patch) | |
| tree | dc41c611965cec299dcb62185c5fba4935b6251f /src/core.c | |
| parent | ed8b6fe9db863a8d9e473a645e84700c7291bb06 (diff) | |
| download | box64-044dec0bfa0f3f8f62f7703d6b0a8600c1354dc5.tar.gz box64-044dec0bfa0f3f8f62f7703d6b0a8600c1354dc5.zip | |
[ENV] Initial refactor of env variables infrastructure (#2274)
* [ENV] Initial refactor of env variables infrastructure * Ported BOX64_DYNAREC_LOG * Ported more options * Ported BOX64_MALLOC_HACK * Ported BOX64_DYNAREC_TEST * Ported more options * Ported more options * Ported more options * Ported all options * Removed old rcfile parser * Fix * review * fix * fix * more fixes
Diffstat (limited to 'src/core.c')
| -rw-r--r-- | src/core.c | 1271 |
1 files changed, 97 insertions, 1174 deletions
diff --git a/src/core.c b/src/core.c index 85c60500..83f09419 100644 --- a/src/core.c +++ b/src/core.c @@ -37,75 +37,38 @@ #include "librarian.h" #include "x64run.h" #include "symbols.h" -#include "rcfile.h" #include "emu/x64run_private.h" #include "elfs/elfloader_private.h" #include "library.h" #include "core.h" +#include "env.h" box64context_t *my_context = NULL; +extern box64env_t box64env; + int box64_quit = 0; int box64_exit_code = 0; -int box64_log = LOG_INFO; //LOG_NONE; -int box64_dump = 0; -int box64_nobanner = 0; int box64_stdout_no_w = 0; -int box64_dynarec_log = LOG_NONE; uintptr_t box64_pagesize; -uintptr_t box64_load_addr = 0; -int box64_nosandbox = 0; -int box64_inprocessgpu = 0; -int box64_cefdisablegpu = 0; -int box64_cefdisablegpucompositor = 0; -int box64_malloc_hack = 0; -int box64_dynarec_test = 0; -int box64_x11sync = 0; path_collection_t box64_addlibs = {0}; -int box64_maxcpu = 0; -int box64_maxcpu_immutable = 0; int box64_is32bits = 0; -int box64_cputype = 0; -#if defined(SD845) || defined(SD888) || defined(SD8G2) || defined(TEGRAX1) -int box64_mmap32 = 1; -#else -int box64_mmap32 = 0; -#endif -int box64_ignoreint3 = 0; int box64_rdtsc = 0; -int box64_rdtsc_1ghz = 0; uint8_t box64_rdtsc_shift = 0; -char* box64_insert_args = NULL; -char* box64_new_args = NULL; +int box64_mapclean = 0; +int box64_zoom = 0; +int box64_steam = 0; +int box64_steamcmd = 0; +int box64_wine = 0; +int box64_musl = 0; +char* box64_custom_gstreamer = NULL; +int box64_tcmalloc_minimal = 0; +uintptr_t fmod_smc_start = 0; +uintptr_t fmod_smc_end = 0; +uint32_t default_gs = 0x53; +uint32_t default_fs = 0; +int box64_isglibc234 = 0; + #ifdef DYNAREC -int box64_dynarec = 1; -int box64_dynarec_dump = 0; -int box64_dynarec_forced = 0; -int box64_dynarec_bigblock = 1; -int box64_dynarec_forward = 128; -int box64_dynarec_strongmem = 0; -int box64_dynarec_weakbarrier = 1; -int box64_dynarec_pause = 0; -int box64_dynarec_x87double = 0; -int box64_dynarec_div0 = 0; -int box64_dynarec_fastnan = 1; -int box64_dynarec_fastround = 1; -int box64_dynarec_safeflags = 1; -int box64_dynarec_callret = 0; -int box64_dynarec_bleeding_edge = 1; -int box64_dynarec_tbb = 1; -int box64_dynarec_wait = 1; -int box64_dynarec_missing = 0; -int box64_dynarec_aligned_atomics = 0; -int box64_dynarec_nativeflags = 1; -uintptr_t box64_nodynarec_start = 0; -uintptr_t box64_nodynarec_end = 0; -uintptr_t box64_dynarec_test_start = 0; -uintptr_t box64_dynarec_test_end = 0; -int box64_dynarec_gdbjit = 0; -int box64_dynarec_df = 1; -int box64_dynarec_perf_map = 0; -int box64_dynarec_perf_map_fd = -1; -int box64_dynarec_dirty = 0; #ifdef ARM64 int arm64_asimd = 0; int arm64_aes = 0; @@ -143,73 +106,12 @@ int la64_lam_bh = 0; int la64_lamcas = 0; int la64_scq = 0; #endif -#else //DYNAREC -int box64_dynarec = 0; #endif -int box64_libcef = 1; -int box64_jvm = 1; -int box64_unityplayer = 1; -int box64_sdl2_jguid = 0; -int dlsym_error = 0; -int cycle_log = 0; + #ifdef HAVE_TRACE -int trace_xmm = 0; -int trace_emm = 0; -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 box64_x11threads = 0; -int box64_x11glx = 1; -int allow_missing_libs = 0; -int box64_prefer_emulated = 0; -int box64_prefer_wrapped = 0; -int box64_wrap_egl = 0; -int box64_sse_flushto0 = 0; -int box64_x87_no80bits = 0; -int box64_sync_rounding = 0; -int box64_shaext = 1; -int box64_sse42 = 1; -#if defined(DYNAREC) && defined(ARM64) -int box64_avx = 1; -int box64_avx2 = 1; -#else -int box64_avx = 0; -int box64_avx2 = 0; -#endif -int fix_64bit_inodes = 0; -int box64_dummy_crashhandler = 1; -int box64_mapclean = 0; -int box64_zoom = 0; -int box64_steam = 0; -int box64_steamcmd = 0; -int box64_wine = 0; -int box64_musl = 0; -int box64_nopulse = 0; -int box64_nogtk = 0; -int box64_novulkan = 0; -int box64_showsegv = 0; -int box64_showbt = 0; -int box64_isglibc234 = 0; -#ifdef BAD_SIGNAL -int box64_futex_waitv = 0; -#else -int box64_futex_waitv = 1; -#endif -char* box64_libGL = NULL; -char* box64_custom_gstreamer = NULL; -uintptr_t fmod_smc_start = 0; -uintptr_t fmod_smc_end = 0; -uint32_t default_gs = 0x53; -uint32_t default_fs = 0; -int jit_gdb = 0; -int box64_tcmalloc_minimal = 0; FILE* ftrace = NULL; char* ftrace_name = NULL; @@ -217,7 +119,7 @@ int ftrace_has_pid = 0; void openFTrace(const char* newtrace, int reopen) { - const char* p = newtrace?newtrace:getenv("BOX64_TRACE_FILE"); + const char* p = newtrace?newtrace:BOX64ENV(trace_file); #ifndef MAX_PATH #define MAX_PATH 4096 #endif @@ -272,7 +174,7 @@ void openFTrace(const char* newtrace, int reopen) if (!reopen) ftrace_name = box_strdup(p); /*fclose(ftrace); ftrace = NULL;*/ - if(!box64_nobanner) { + if (!BOX64ENV(nobanner)) { printf("BOX64 Trace %s to \"%s\"\n", append?"appended":"redirected", p); box64_stdout_no_w = 1; } @@ -304,7 +206,7 @@ void printf_ftrace(const char* fmt, ...) void my_prepare_fork() { if (ftrace_has_pid && ftrace && (ftrace != stdout) && (ftrace != stderr)) { - printf_log(LOG_INFO, "%04d|Closed trace file of %s at prepare\n", GetTID(), GetLastApplyName()); + printf_log(LOG_INFO, "%04d|Closed trace file of %s at prepare\n", GetTID(), GetLastApplyEntryName()); fclose(ftrace); } } @@ -313,7 +215,7 @@ void my_parent_fork() { if (ftrace_has_pid) { openFTrace(NULL, 1); - printf_log(LOG_INFO, "%04d|Reopened trace file of %s at parent\n", GetTID(), GetLastApplyName()); + printf_log(LOG_INFO, "%04d|Reopened trace file of %s at parent\n", GetTID(), GetLastApplyEntryName()); } } @@ -321,135 +223,24 @@ void my_child_fork() { if (ftrace_has_pid) { openFTrace(NULL, 0); - printf_log(LOG_INFO, "%04d|Created trace file of %s at child\n", GetTID(), GetLastApplyName()); + printf_log(LOG_INFO, "%04d|Created trace file of %s at child\n", GetTID(), GetLastApplyEntryName()); } } const char* getCpuName(); int getNCpu(); + #ifdef DYNAREC void GatherDynarecExtensions() { #ifdef ARM64 -/* -HWCAP_FP - Functionality implied by ID_AA64PFR0_EL1.FP == 0b0000. -HWCAP_ASIMD - Functionality implied by ID_AA64PFR0_EL1.AdvSIMD == 0b0000. -HWCAP_EVTSTRM - The generic timer is configured to generate events at a frequency of - approximately 10KHz. -HWCAP_AES - Functionality implied by ID_AA64ISAR0_EL1.AES == 0b0001. => AESE, AESD, AESMC, and AESIMC instructions are implemented -HWCAP_PMULL - Functionality implied by ID_AA64ISAR0_EL1.AES == 0b0010. => AESE, AESD, AESMC, and AESIMC instructions are implemented plus PMULL/PMULL2 instructions operating on 64-bit data quantities. -HWCAP_SHA1 - Functionality implied by ID_AA64ISAR0_EL1.SHA1 == 0b0001. => SHA1C, SHA1P, SHA1M, SHA1H, SHA1SU0, and SHA1SU1 instructions implemented. -HWCAP_SHA2 - Functionality implied by ID_AA64ISAR0_EL1.SHA2 == 0b0001. => SHA256H, SHA256H2, SHA256SU0 and SHA256SU1 instructions implemented. -HWCAP_CRC32 - Functionality implied by ID_AA64ISAR0_EL1.CRC32 == 0b0001. => CRC32B, CRC32H, CRC32W, CRC32X, CRC32CB, CRC32CH, CRC32CW, and CRC32CX instructions implemented. -HWCAP_ATOMICS - Functionality implied by ID_AA64ISAR0_EL1.Atomic == 0b0010. => LDADD, LDCLR, LDEOR, LDSET, LDSMAX, LDSMIN, LDUMAX, LDUMIN, CAS, CASP, and SWP instructions implemented. -HWCAP_FPHP - Functionality implied by ID_AA64PFR0_EL1.FP == 0b0001. -HWCAP_ASIMDHP - Functionality implied by ID_AA64PFR0_EL1.AdvSIMD == 0b0001. -HWCAP_CPUID - EL0 access to certain ID registers is available. - These ID registers may imply the availability of features. -HWCAP_ASIMDRDM - Functionality implied by ID_AA64ISAR0_EL1.RDM == 0b0001. => SQRDMLAH and SQRDMLSH instructions implemented. -HWCAP_JSCVT - Functionality implied by ID_AA64ISAR1_EL1.JSCVT == 0b0001. => The FJCVTZS instruction is implemented. -HWCAP_FCMA - Functionality implied by ID_AA64ISAR1_EL1.FCMA == 0b0001. => The FCMLA and FCADD instructions are implemented. -HWCAP_LRCPC - Functionality implied by ID_AA64ISAR1_EL1.LRCPC == 0b0001. => LDAPR and variants -HWCAP_DCPOP - Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0001. -HWCAP_SHA3 - Functionality implied by ID_AA64ISAR0_EL1.SHA3 == 0b0001. => EOR3, RAX1, XAR, and BCAX instructions implemented. -HWCAP_SM3 - Functionality implied by ID_AA64ISAR0_EL1.SM3 == 0b0001. => SM3SS1, SM3TT1A, SM3TT1B, SM3TT2A, SM3TT2B, SM3PARTW1, and SM3PARTW2 instructions implemented. -HWCAP_SM4 - Functionality implied by ID_AA64ISAR0_EL1.SM4 == 0b0001. => SM4E and SM4EKEY instructions implemented. -HWCAP_ASIMDDP - Functionality implied by ID_AA64ISAR0_EL1.DP == 0b0001. => UDOT and SDOT instructions implemented. -HWCAP_SHA512 - Functionality implied by ID_AA64ISAR0_EL1.SHA2 == 0b0010. => SHA512H, SHA512H2, SHA512SU0, and SHA512SU1 instructions implemented. -HWCAP_SVE - Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001. -HWCAP_ASIMDFHM - Functionality implied by ID_AA64ISAR0_EL1.FHM == 0b0001. => FMLAL and FMLSL instructions are implemented. -HWCAP_DIT - Functionality implied by ID_AA64PFR0_EL1.DIT == 0b0001. -HWCAP_USCAT - Functionality implied by ID_AA64MMFR2_EL1.AT == 0b0001. -HWCAP_ILRCPC - Functionality implied by ID_AA64ISAR1_EL1.LRCPC == 0b0010. => The LDAPUR*, STLUR*, and LDAPR* instructions are implemented. -HWCAP_FLAGM - Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0001. -HWCAP_SSBS - Functionality implied by ID_AA64PFR1_EL1.SSBS == 0b0010. => AArch64 provides the PSTATE.SSBS mechanism to mark regions that are Speculative Store Bypassing Safe, and the MSR and MRS instructions to directly read and write the PSTATE.SSBS field. -HWCAP_SB - Functionality implied by ID_AA64ISAR1_EL1.SB == 0b0001. => SB instruction is implemented. -HWCAP_PACA - Functionality implied by ID_AA64ISAR1_EL1.APA == 0b0001 or - ID_AA64ISAR1_EL1.API == 0b0001. -HWCAP_PACG - Functionality implied by ID_AA64ISAR1_EL1.GPA == 0b0001 or => Generic Authentication using the QARMA algorithm is implemented. This includes the PACGA instruction. - ID_AA64ISAR1_EL1.GPI == 0b0001. -HWCAP2_DCPODP - Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010. => DC CVAP and DC CVADP supported -HWCAP2_SVE2 - Functionality implied by ID_AA64ZFR0_EL1.SVEVer == 0b0001. -HWCAP2_SVEAES - Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0001. -HWCAP2_SVEPMULL - Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0010. -HWCAP2_SVEBITPERM - Functionality implied by ID_AA64ZFR0_EL1.BitPerm == 0b0001. -HWCAP2_SVESHA3 - Functionality implied by ID_AA64ZFR0_EL1.SHA3 == 0b0001. -HWCAP2_SVESM4 - Functionality implied by ID_AA64ZFR0_EL1.SM4 == 0b0001. -HWCAP2_FLAGM2 - Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0010. => CFINV, RMIF, SETF16, SETF8, AXFLAG, and XAFLAG instructions are implemented. -HWCAP2_FRINT - Functionality implied by ID_AA64ISAR1_EL1.FRINTTS == 0b0001. => FRINT32Z, FRINT32X, FRINT64Z, and FRINT64X instructions are implemented. -HWCAP2_SVEI8MM - Functionality implied by ID_AA64ZFR0_EL1.I8MM == 0b0001. -HWCAP2_SVEF32MM - Functionality implied by ID_AA64ZFR0_EL1.F32MM == 0b0001. -HWCAP2_SVEF64MM - Functionality implied by ID_AA64ZFR0_EL1.F64MM == 0b0001. -HWCAP2_SVEBF16 - Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0001 -HWCAP2_I8MM - Functionality implied by ID_AA64ISAR1_EL1.I8MM == 0b0001. => SMMLA, SUDOT, UMMLA, USMMLA, and USDOT instructions are implemented -HWCAP2_BF16 - Functionality implied by ID_AA64ISAR1_EL1.BF16 == 0b0001. => BFDOT, BFMLAL, BFMLAL2, BFMMLA, BFCVT, and BFCVT2 instructions are implemented. -HWCAP2_DGH - Functionality implied by ID_AA64ISAR1_EL1.DGH == 0b0001. => Data Gathering Hint is implemented. -HWCAP2_RNG - Functionality implied by ID_AA64ISAR0_EL1.RNDR == 0b0001. -HWCAP2_BTI - Functionality implied by ID_AA64PFR0_EL1.BT == 0b0001. -HWCAP2_MTE - Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0010. => Full Memory Tagging Extension is implemented. -HWCAP2_ECV - Functionality implied by ID_AA64MMFR0_EL1.ECV == 0b0001. -HWCAP2_AFP - AFP = 0b0001 => The AArch64-FPCR.{AH, FIZ, NEP} fields are supported. (Alternate floating-point behavior) -*/ unsigned long hwcap = real_getauxval(AT_HWCAP); - if(!hwcap) // no HWCap: provide a default... + if(!hwcap) hwcap = HWCAP_ASIMD; // first, check all needed extensions, lif half, edsp and fastmult if((hwcap&HWCAP_ASIMD) == 0) { printf_log(LOG_INFO, "Missing ASMID cpu support, disabling Dynarec\n"); - box64_dynarec=0; + SET_BOX64ENV(dynarec, 0); return; } if(hwcap&HWCAP_CRC32) @@ -529,7 +320,7 @@ HWCAP2_AFP printf_log(LOG_INFO, "with extension LSX LASX"); } else { printf_log(LOG_INFO, "\nMissing LSX and/or LASX extension support, disabling Dynarec\n"); - box64_dynarec = 0; + SET_BOX64ENV(dynarec, 0); return; } @@ -611,7 +402,7 @@ void computeRDTSC() printf_log(LOG_INFO, "Will use time-based emulation for RDTSC, even if hardware counters are available\n"); #endif uint64_t freq = ReadTSCFrequency(NULL); - if(freq<((box64_rdtsc_1ghz)?1000000000LL:1000000)) { + if(freq<((BOX64ENV(rdtsc_1ghz))?1000000000LL:1000000)) { box64_rdtsc = 1; if(hardware) printf_log(LOG_INFO, "Hardware counter is too slow (%d kHz), not using it\n", freq/1000); hardware = 0; @@ -642,710 +433,23 @@ void computeRDTSC() EXPORTDYN void LoadLogEnv() { - ftrace = stdout; - box64_nobanner = isatty(fileno(stdout))?0:1; - const char *p = getenv("BOX64_NOBANNER"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_nobanner = p[0]-'0'; - } - } - // grab BOX64_TRACE_FILE envvar, and change %pid to actual pid is present in the name + // grab BOX64ENV(trace_file), and change %pid to actual pid is present in the name openFTrace(NULL, 0); - box64_log = ftrace_name?LOG_INFO:(isatty(fileno(stdout))?LOG_INFO:LOG_NONE); //default LOG value different if stdout is redirected or not - p = getenv("BOX64_LOG"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0'+LOG_NONE && p[0]<='0'+LOG_NEVER) { - box64_log = p[0]-'0'; - if(box64_log == LOG_NEVER) { - --box64_log; - box64_dump = 1; - } - } - } else { - if(!strcasecmp(p, "NONE")) - box64_log = LOG_NONE; - else if(!strcasecmp(p, "INFO")) - box64_log = LOG_INFO; - else if(!strcasecmp(p, "DEBUG")) - box64_log = LOG_DEBUG; - else if(!strcasecmp(p, "DUMP")) { - box64_log = LOG_DEBUG; - box64_dump = 1; - } - } - if(!box64_nobanner) - printf_log(LOG_INFO, "Debug level is %d\n", box64_log); - } - if((box64_nobanner || box64_log) && ftrace==stdout) + + if ((BOX64ENV(nobanner) || BOX64ENV(log)) && ftrace==stdout) box64_stdout_no_w = 1; #if !defined(DYNAREC) && (defined(ARM64) || defined(RV64) || defined(LA64)) printf_log(LOG_INFO, "Warning: DynaRec is available on this host architecture, an interpreter-only build is probably not intended.\n"); #endif - p = getenv("BOX64_ROLLING_LOG"); - if(p) { - int cycle = 0; - if(sscanf(p, "%d", &cycle)==1) - cycle_log = cycle; - if(cycle_log==1) - cycle_log = 16; - if(cycle_log<0) - cycle_log = 0; - if(cycle_log && box64_log>LOG_INFO) { - cycle_log = 0; - printf_log(LOG_NONE, "Incompatible Rolling log and Debug Log, disabling Rolling log\n"); - } - } - if(!box64_nobanner && cycle_log) - printf_log(LOG_INFO, "Rolling log, showing last %d function call on signals\n", cycle_log); - p = getenv("BOX64_DUMP"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dump = p[0]-'0'; - } - } - if(!box64_nobanner && box64_dump) - printf_log(LOG_INFO, "Elf Dump if ON\n"); -#ifdef DYNAREC - #ifdef ARM64 - // unaligned atomic (with restriction) is supported in hardware - /*if(arm64_uscat) - box64_dynarec_aligned_atomics = 1;*/ // the unaligned support is not good enough for x86 emulation, so diabling - #endif - p = getenv("BOX64_DYNAREC_DUMP"); - if(p) { - if(strlen(p)==1) { - if (p[0] >= '0' && p[0] <= '2') - box64_dynarec_dump = p[0]-'0'; - } - if (box64_dynarec_dump) printf_log(LOG_INFO, "Dynarec blocks are dumped%s\n", (box64_dynarec_dump>1)?" in color":""); - } - p = getenv("BOX64_DYNAREC_LOG"); - if(p) { - if(strlen(p)==1) { - if((p[0]>='0'+LOG_NONE) && (p[0]<='0'+LOG_NEVER)) - box64_dynarec_log = p[0]-'0'; - } else { - if(!strcasecmp(p, "NONE")) - box64_dynarec_log = LOG_NONE; - else if(!strcasecmp(p, "INFO")) - box64_dynarec_log = LOG_INFO; - else if(!strcasecmp(p, "DEBUG")) - box64_dynarec_log = LOG_DEBUG; - else if(!strcasecmp(p, "VERBOSE")) - box64_dynarec_log = LOG_VERBOSE; - } - printf_log(LOG_INFO, "Dynarec log level is %d\n", box64_dynarec_log); - } - p = getenv("BOX64_DYNAREC"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec = p[0]-'0'; - } - printf_log(LOG_INFO, "Dynarec is %s\n", box64_dynarec?"on":"off"); - } - p = getenv("BOX64_DYNAREC_FORCED"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_forced = p[0]-'0'; - } - if(box64_dynarec_forced) - printf_log(LOG_INFO, "Dynarec is forced on all addresses\n"); - } - p = getenv("BOX64_DYNAREC_BIGBLOCK"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='3') - box64_dynarec_bigblock = p[0]-'0'; - } - if(!box64_dynarec_bigblock) - printf_log(LOG_INFO, "Dynarec will not try to make big block\n"); - else if (box64_dynarec_bigblock>1) - printf_log(LOG_INFO, "Dynarec will try to make bigger blocks%s\n", (box64_dynarec_bigblock>2)?" even on non-elf memory":""); + char* p; - } - p = getenv("BOX64_DYNAREC_FORWARD"); - if(p) { - int val = -1; - if(sscanf(p, "%d", &val)==1) { - if(val>=0) - box64_dynarec_forward = val; - } - if(box64_dynarec_forward) - printf_log(LOG_INFO, "Dynarec will continue block for %d bytes on forward jump\n", box64_dynarec_forward); - else - printf_log(LOG_INFO, "Dynarec will not continue block on forward jump\n"); - } - p = getenv("BOX64_DYNAREC_STRONGMEM"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='4') - box64_dynarec_strongmem = p[0]-'0'; - } - if(box64_dynarec_strongmem) - printf_log(LOG_INFO, "Dynarec will try to emulate a strong memory model%s\n", (box64_dynarec_strongmem==1)?" with limited performance loss":((box64_dynarec_strongmem>1)?" with more performance loss":"")); - } - p = getenv("BOX64_DYNAREC_WEAKBARRIER"); - if (p) { - if (strlen(p) == 1) { - if (p[0] >= '0' && p[0] <= '2') - box64_dynarec_weakbarrier = p[0] - '0'; - } - if (box64_dynarec_weakbarrier) - printf_log(LOG_INFO, "Dynarec will try to use weaker memory barriers to reduce the performance loss introduce by strong memory emulation\n"); - else - printf_log(LOG_INFO, "Dynarec will not use weakbarrier on strong memory emulation\n"); - } -#ifdef ARM64 - p = getenv("BOX64_DYNAREC_PAUSE"); - if (p) { - if (strlen(p) == 1) { - if (p[0] >= '0' && p[0] <= '3') - box64_dynarec_pause = p[0] - '0'; - } - if (box64_dynarec_pause) - printf_log(LOG_INFO, "Dynarec will use %s to emulate pause instruction\n", - box64_dynarec_pause == 1 ? "yield" : (box64_dynarec_pause == 2 ? "wfi" : "wfe")); - else - printf_log(LOG_INFO, "Dynarec will generate nothing for the pause instuction\n"); - } -#endif - p = getenv("BOX64_DYNAREC_X87DOUBLE"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_x87double = p[0]-'0'; - } - if(box64_dynarec_x87double) - printf_log(LOG_INFO, "Dynarec will use only double for x87 emulation\n"); - } - p = getenv("BOX64_DYNAREC_DIV0"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_div0 = p[0]-'0'; - } - if(box64_dynarec_div0) - printf_log(LOG_INFO, "Dynarec will check for divide by 0\n"); - } - p = getenv("BOX64_DYNAREC_FASTNAN"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_fastnan = p[0]-'0'; - } - if(!box64_dynarec_fastnan) - printf_log(LOG_INFO, "Dynarec will try to normalize generated NAN\n"); - } - p = getenv("BOX64_DYNAREC_FASTROUND"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='2') - box64_dynarec_fastround = p[0]-'0'; - } - if(!box64_dynarec_fastround) - printf_log(LOG_INFO, "Dynarec will try to generate x86 precise IEEE->int rounding and and set rounding mode for computation\n"); - else if(box64_dynarec_fastround==2) - printf_log(LOG_INFO, "Dynarec will generate x86 very imprecise double->float rounding\n"); - } - p = getenv("BOX64_DYNAREC_SAFEFLAGS"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='2') - box64_dynarec_safeflags = p[0]-'0'; - } - if(!box64_dynarec_safeflags) - printf_log(LOG_INFO, "Dynarec will not play it safe with x64 flags\n"); - else - printf_log(LOG_INFO, "Dynarec will play %s safe with x64 flags\n", (box64_dynarec_safeflags==1)?"moderatly":"it"); - } - p = getenv("BOX64_DYNAREC_CALLRET"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_callret = p[0]-'0'; - } - if(box64_dynarec_callret) - printf_log(LOG_INFO, "Dynarec will optimize CALL/RET\n"); - else - printf_log(LOG_INFO, "Dynarec will not optimize CALL/RET\n"); - } - p = getenv("BOX64_DYNAREC_BLEEDING_EDGE"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_bleeding_edge = p[0]-'0'; - } - if(!box64_dynarec_bleeding_edge) - printf_log(LOG_INFO, "Dynarec will not detect MonoBleedingEdge\n"); - } - p = getenv("BOX64_DYNAREC_JVM"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_jvm = p[0]-'0'; - } - if(!box64_jvm) - printf_log(LOG_INFO, "Dynarec will not detect libjvm\n"); - } - p = getenv("BOX64_DYNAREC_TBB"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_tbb = p[0]-'0'; - } - if(!box64_dynarec_tbb) - printf_log(LOG_INFO, "Dynarec will not detect libtbb\n"); - } - p = getenv("BOX64_DYNAREC_WAIT"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_wait = p[0]-'0'; - } - if(!box64_dynarec_wait) - printf_log(LOG_INFO, "Dynarec will not wait for FillBlock to ready and use Interpreter instead\n"); - } - p = getenv("BOX64_DYNAREC_GDBJIT"); - if (p) { - if (strlen(p) == 1) { - if (p[0] >= '0' && p[0] <= '2') - box64_dynarec_gdbjit = p[0] - '0'; - } - if (box64_dynarec_gdbjit) - printf_log(LOG_INFO, "Dynarec will generate debuginfo for gdbjit\n"); - } - p = getenv("BOX64_DYNAREC_PERFMAP"); - if (p) { - if (strlen(p) == 1) { - if (p[0] >= '0' && p[0] <= '1') - box64_dynarec_perf_map = p[0] - '0'; - } - if (box64_dynarec_perf_map) - printf_log(LOG_INFO, "Dynarec will generate map file /tmp/perf-%d.map for Linux perf tool\n", getpid()); - } - p = getenv("BOX64_DYNAREC_DF"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_df = p[0]-'0'; - } - if(!box64_dynarec_df) - printf_log(LOG_INFO, "Dynarec will not use/generate defered flags\n"); - } - p = getenv("BOX64_DYNAREC_DIRTY"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_dirty = p[0]-'0'; - } - if(box64_dynarec_dirty) - printf_log(LOG_INFO, "Dynarec will allow dirty block to continu running\n"); - } - p = getenv("BOX64_DYNAREC_ALIGNED_ATOMICS"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_aligned_atomics = p[0]-'0'; - } - if(box64_dynarec_aligned_atomics) - printf_log(LOG_INFO, "Dynarec will generate only aligned atomics code\n"); - } - p = getenv("BOX64_DYNAREC_NATIVEFLAGS"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_nativeflags = p[0]-'0'; - } - if(!box64_dynarec_nativeflags) - printf_log(LOG_INFO, "Dynarec will not use native flags if possible\n"); - } - p = getenv("BOX64_DYNAREC_MISSING"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='2') - box64_dynarec_missing = p[0]-'0'; - } - if(box64_dynarec_missing==1) - printf_log(LOG_INFO, "Dynarec will print missing opcodes\n"); - else if (box64_dynarec_missing==2) - printf_log(LOG_INFO, "Dynarec will print fallback to scalar opcodes\n"); - } - p = getenv("BOX64_NODYNAREC"); - if(p) { - if (strchr(p,'-')) { - if(sscanf(p, "%ld-%ld", &box64_nodynarec_start, &box64_nodynarec_end)!=2) { - if(sscanf(p, "0x%lX-0x%lX", &box64_nodynarec_start, &box64_nodynarec_end)!=2) - sscanf(p, "%lx-%lx", &box64_nodynarec_start, &box64_nodynarec_end); - } - printf_log(LOG_INFO, "No dynablock creation that start in the range %p - %p\n", (void*)box64_nodynarec_start, (void*)box64_nodynarec_end); - } - } - p = getenv("BOX64_DYNAREC_TEST"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_dynarec_test = p[0]-'0'; - box64_dynarec_test_start = 0x0; - box64_dynarec_test_end = 0x0; - } else if (strchr(p,'-')) { - if(sscanf(p, "%ld-%ld", &box64_dynarec_test_start, &box64_dynarec_test_end)!=2) { - if(sscanf(p, "0x%lX-0x%lX", &box64_dynarec_test_start, &box64_dynarec_test_end)!=2) - sscanf(p, "%lx-%lx", &box64_dynarec_test_start, &box64_dynarec_test_end); - } - if(box64_dynarec_test_end>box64_dynarec_test_start) { - box64_dynarec_test = 1; - printf_log(LOG_INFO, "Dynarec test in the range %p - %p\n", (void*)box64_dynarec_test_start, (void*)box64_dynarec_test_end); - } else { - box64_dynarec_test = 0; - printf_log(LOG_INFO, "Ignoring BOX64_NODYNAREC=%s (%p-%p)\n", p, (void*)box64_dynarec_test_start, (void*)box64_dynarec_test_end); - } - } - - if(box64_dynarec_test) { - box64_dynarec_fastnan = 0; - box64_dynarec_fastround = 0; - box64_dynarec_x87double = 1; - box64_dynarec_div0 = 1; - box64_dynarec_callret = 0; - #if defined( RV64) || defined(LA64) - box64_dynarec_nativeflags = 0; - #endif - printf_log(LOG_INFO, "Dynarec will compare it's execution with the interpreter (super slow, only for testing)\n"); - } - } + if (!BOX64ENV(nobanner) && BOX64ENV(rolling_log)) + printf_log(LOG_INFO, "Rolling log, showing last %d function call on signals\n", BOX64ENV(rolling_log)); -#endif -#ifdef HAVE_TRACE - p = getenv("BOX64_TRACE_XMM"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - trace_xmm = p[0]-'0'; - } - } - p = getenv("BOX64_TRACE_EMM"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - trace_emm = p[0]-'0'; - } - } - p = getenv("BOX64_TRACE_COLOR"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - trace_regsdiff = p[0]-'0'; - } - } - p = getenv("BOX64_TRACE_START"); - if(p) { - char* p2; - start_cnt = strtoll(p, &p2, 10); - printf_log(LOG_INFO, "Will start trace only after %lu instructions\n", start_cnt); - } -#ifdef DYNAREC - p = getenv("BOX64_DYNAREC_TRACE"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_dynarec_trace = p[0]-'0'; - if(box64_dynarec_trace) - printf_log(LOG_INFO, "Dynarec generated code will also print a trace\n"); - } - } -#endif -#endif - // Other BOX64 env. var. - p = getenv("BOX64_LIBCEF"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_libcef = p[0]-'0'; - } - if(!box64_libcef) - printf_log(LOG_INFO, "BOX64 will not detect libcef\n"); - } - p = getenv("BOX64_JVM"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_jvm = p[0]-'0'; - } - if(!box64_jvm) - printf_log(LOG_INFO, "BOX64 will not detect libjvm\n"); - } - p = getenv("BOX64_UNITYPLAYER"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_unityplayer = p[0]-'0'; - } - if(!box64_unityplayer) - printf_log(LOG_INFO, "BOX64 will not detect UnityPlayer.dll\n"); - } - p = getenv("BOX64_SDL2_JGUID"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='1') - box64_sdl2_jguid = p[0]-'0'; - } - if(!box64_sdl2_jguid) - printf_log(LOG_INFO, "BOX64 will workaround the use of SDL_GetJoystickGUIDInfo with 4 args instead of 5\n"); - } - p = getenv("BOX64_LOAD_ADDR"); - if(p) { - if(sscanf(p, "0x%zx", &box64_load_addr)!=1) - box64_load_addr = 0; - if(box64_load_addr) - printf_log(LOG_INFO, "Use a starting load address of %p\n", (void*)box64_load_addr); - } - p = getenv("BOX64_DLSYM_ERROR"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - dlsym_error = p[0]-'0'; - } - } - p = getenv("BOX64_X11THREADS"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_x11threads = p[0]-'0'; - } - 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) - box64_x11glx = p[0]-'0'; - } - 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) - box64_libGL = box_strdup(p); - if(!box64_libGL) { - p = getenv("SDL_VIDEO_GL_DRIVER"); - if(p) - box64_libGL = box_strdup(p); - } - if(box64_libGL) { - printf_log(LOG_INFO, "BOX64 using \"%s\" as libGL.so.1\n", p); - } - p = getenv("BOX64_ALLOWMISSINGLIBS"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - allow_missing_libs = p[0]-'0'; - } - if(allow_missing_libs) - printf_log(LOG_INFO, "Allow missing needed libs\n"); - } - p = getenv("BOX64_CRASHHANDLER"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_dummy_crashhandler = p[0]-'0'; - } - if(!box64_dummy_crashhandler) - printf_log(LOG_INFO, "Don't use dummy crashhandler lib\n"); - } - p = getenv("BOX64_MALLOC_HACK"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+2) - box64_malloc_hack = p[0]-'0'; - } - if(!box64_malloc_hack) { - if(box64_malloc_hack==1) { - printf_log(LOG_INFO, "Malloc hook will not be redirected\n"); - } else - printf_log(LOG_INFO, "Malloc hook will check for mmap/free occurrences\n"); - } - } - p = getenv("BOX64_NOPULSE"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_nopulse = p[0]-'0'; - } - if(box64_nopulse) - printf_log(LOG_INFO, "Disable the use of pulseaudio libs\n"); - } - p = getenv("BOX64_NOGTK"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_nogtk = p[0]-'0'; - } - if(box64_nogtk) - printf_log(LOG_INFO, "Disable the use of wrapped gtk libs\n"); - } - p = getenv("BOX64_NOVULKAN"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_novulkan = p[0]-'0'; - } - if(box64_novulkan) - printf_log(LOG_INFO, "Disable the use of wrapped vulkan libs\n"); - } - p = getenv("BOX64_FUTEX_WAITV"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_futex_waitv = p[0]-'0'; - } - #ifdef BAD_SIGNAL - if(box64_futex_waitv) - printf_log(LOG_INFO, "Enable the use of futex waitv syscall (if available on the system\n"); - #else - if(!box64_futex_waitv) - printf_log(LOG_INFO, "Disable the use of futex waitv syscall\n"); - #endif - } - p = getenv("BOX64_SHAEXT"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_shaext = p[0]-'0'; - } - if(!box64_shaext) - printf_log(LOG_INFO, "Do not expose SHAEXT capabilities\n"); - } - p = getenv("BOX64_SSE42"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_sse42 = p[0]-'0'; - } - if(!box64_sse42) - printf_log(LOG_INFO, "Do not expose SSE 4.2 capabilities\n"); - } - p = getenv("BOX64_AVX"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+2) - box64_avx = p[0]-'0'; - } - if(box64_avx) - printf_log(LOG_INFO, "Will expose AVX capabilities\n"); - if(box64_avx==2) { - box64_avx=1; - box64_avx2 = 1; - printf_log(LOG_INFO, "Will expose AVX2 capabilities\n"); - } - if(!box64_avx) - printf_log(LOG_INFO, "Will not expose AVX capabilities\n"); - if(!box64_avx2) - printf_log(LOG_INFO, "Will not expose AVX2 capabilities\n"); - } - p = getenv("BOX64_RDTSC_1GHZ"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_rdtsc_1ghz = p[0]-'0'; - } - if(!box64_rdtsc_1ghz) - printf_log(LOG_INFO, "Will require a hardware counter of 1GHz minimum or will fallback to software\n"); - } - p = getenv("BOX64_FIX_64BIT_INODES"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - fix_64bit_inodes = p[0]-'0'; - } - if(fix_64bit_inodes) - printf_log(LOG_INFO, "Fix 64bit inodes\n"); - } - p = getenv("BOX64_JITGDB"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+3) - jit_gdb = p[0]-'0'; - } - if(jit_gdb) - printf_log(LOG_INFO, "Launch %s on segfault\n", (jit_gdb==2)?"gdbserver":((jit_gdb==3)?"lldb":"gdb")); - } - p = getenv("BOX64_SHOWSEGV"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_showsegv = p[0]-'0'; - } - if(box64_showsegv) - printf_log(LOG_INFO, "Show Segfault signal even if a signal handler is present\n"); - } - p = getenv("BOX64_SHOWBT"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_showbt = p[0]-'0'; - } - if(box64_showbt) - printf_log(LOG_INFO, "Show a Backtrace when a Segfault signal is caught\n"); - } - p = getenv("BOX64_MAXCPU"); - if(p) { - int maxcpu = 0; - if(sscanf(p, "%d", &maxcpu)==1) - box64_maxcpu = maxcpu; - if(box64_maxcpu<0) - box64_maxcpu = 0; - if(box64_maxcpu) { - printf_log(LOG_NONE, "Will not expose more than %d cpu cores\n", box64_maxcpu); - } else { - printf_log(LOG_NONE, "Will not limit the number of cpu cores exposed\n"); - } - } - p = getenv("BOX64_MMAP32"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_mmap32 = p[0]-'0'; - } - if(box64_mmap32) - printf_log(LOG_INFO, "Will use 32bits address in priority for external MMAP (when 32bits process are detected)\n"); - else - printf_log(LOG_INFO, "Will not use 32bits address in priority for external MMAP (when 32bits process are detected)\n"); - } - p = getenv("BOX64_CPUTYPE"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_cputype = p[0]-'0'; - } - printf_log(LOG_INFO, "Will emulate an %s CPU\n", box64_cputype?"AMD":"Intel"); - } - p = getenv("BOX64_IGNOREINT3"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_ignoreint3 = p[0]-'0'; - } - if(box64_ignoreint3) - printf_log(LOG_INFO, "Will silently ignore INT3 in the code\n"); - } - p = getenv("BOX64_X11SYNC"); - if(p) { - if(strlen(p)==1) { - if(p[0]>='0' && p[0]<='0'+1) - box64_x11sync = p[0]-'0'; - } - } + if (!BOX64ENV(nobanner) && BOX64ENV(dump)) + printf_log(LOG_INFO, "Elf Dump if ON\n"); // grab pagesize box64_pagesize = sysconf(_SC_PAGESIZE); if(!box64_pagesize) @@ -1362,12 +466,10 @@ void LoadLogEnv() computeRDTSC(); } -EXPORTDYN -void LoadEnvPath(path_collection_t *col, const char* defpath, const char* env) +static void loadPath(path_collection_t *col, const char* defpath, const char* path) { - const char* p = getenv(env); - if(p) { - ParseList(p, col, 1); + if(path) { + ParseList(path, col, 1); } else { ParseList(defpath, col, 1); } @@ -1375,7 +477,7 @@ void LoadEnvPath(path_collection_t *col, const char* defpath, const char* env) void PrintCollection(path_collection_t* col, const char* env) { - if(LOG_INFO<=box64_log) { + if (LOG_INFO<=BOX64ENV(log)) { printf_log(LOG_INFO, "%s: ", env); for(int i=0; i<col->size; i++) printf_log(LOG_INFO, "%s%s", col->paths[i], (i==col->size-1)?"\n":":"); @@ -1426,60 +528,12 @@ void AddNewLibs(const char* list) printf_log(LOG_INFO, "BOX64: Adding %s to the libs\n", list); } -void PrintFlags() { - printf("Environment Variables:\n"); - printf(" BOX64_PATH is the box64 version of PATH (default is '.:bin')\n"); - printf(" BOX64_LD_LIBRARY_PATH is the box64 version LD_LIBRARY_PATH (default is '.:lib:lib64')\n"); - printf(" BOX64_LOG with 0/1/2/3 or NONE/INFO/DEBUG/DUMP to set the printed debug info (level 3 is level 2 + BOX64_DUMP)\n"); - printf(" BOX64_DUMP with 0/1 to dump elf infos\n"); - printf(" BOX64_NOBANNER with 0/1 to enable/disable the printing of box64 version and build at start\n"); -#ifdef DYNAREC - printf(" BOX64_DYNAREC_LOG with 0/1/2/3 or NONE/INFO/DEBUG/DUMP to set the printed dynarec info\n"); - printf(" BOX64_DYNAREC with 0/1 to disable or enable Dynarec (On by default)\n"); - printf(" BOX64_NODYNAREC with address interval (0x1234-0x4567) to forbid dynablock creation in the interval specified\n"); -#endif -#ifdef HAVE_TRACE - printf(" BOX64_TRACE with 1 to enable x86_64 execution trace\n"); - printf(" or with XXXXXX-YYYYYY to enable x86_64 execution trace only between address\n"); - printf(" or with FunctionName to enable x86_64 execution trace only in one specific function\n"); - printf(" use BOX64_TRACE_INIT instead of BOX64_TRACE to start trace before init of Libs and main program\n\t (function name will probably not work then)\n"); - printf(" BOX64_TRACE_EMM with 1 to enable dump of MMX registers along with regular registers\n"); - printf(" BOX64_TRACE_XMM with 1 to enable dump of SSE registers along with regular registers\n"); - printf(" BOX64_TRACE_COLOR with 1 to enable detection of changed general register values\n"); - printf(" BOX64_TRACE_START with N to enable trace after N instructions\n"); -#ifdef DYNAREC - printf(" BOX64_DYNAREC_TRACE with 0/1 to disable or enable Trace on generated code too\n"); -#endif -#endif - printf(" BOX64_TRACE_FILE with FileName to redirect logs in a file (or stderr to use stderr instead of stdout)\n"); - printf(" BOX64_DLSYM_ERROR with 1 to log dlsym errors\n"); - printf(" BOX64_LOAD_ADDR=0xXXXXXX try to load at 0xXXXXXX main binary (if binary is a PIE)\n"); - printf(" BOX64_NOSIGSEGV=1 to disable handling of SigSEGV\n"); - printf(" BOX64_NOSIGILL=1 to disable handling of SigILL\n"); - printf(" BOX64_SHOWSEGV=1 to show Segfault signal even if a signal handler is present\n"); - printf(" BOX64_X11THREADS=1 to call XInitThreads when loading X11 (for old Loki games with Loki_Compat lib)\n"); - printf(" BOX64_LIBGL=libXXXX set the name (and optionnally full path) for libGL.so.1\n"); - printf(" BOX64_LD_PRELOAD=XXXX[:YYYYY] force loading XXXX (and YYYY...) libraries with the binary\n"); - printf(" BOX64_ALLOWMISSINGLIBS with 1 to allow one to continue even if a lib is missing (unadvised, will probably crash later)\n"); - printf(" BOX64_PREFER_EMULATED=1 to prefer emulated libs first (execpt for glibc, alsa, pulse, GL, vulkan and X11)\n"); - printf(" BOX64_PREFER_WRAPPED if box64 will use wrapped libs even if the lib is specified with absolute path\n"); - printf(" BOX64_CRASHHANDLER=0 to not use a dummy crashhandler lib\n"); - printf(" BOX64_NOPULSE=1 to disable the loading of pulseaudio libs\n"); - printf(" BOX64_NOGTK=1 to disable the loading of wrapped gtk libs\n"); - printf(" BOX64_NOVULKAN=1 to disable the loading of wrapped vulkan libs\n"); - printf(" BOX64_ENV='XXX=yyyy' will add XXX=yyyy env. var.\n"); - printf(" BOX64_ENV1='XXX=yyyy' will add XXX=yyyy env. var. and continue with BOX86_ENV2 ... until var doesn't exist\n"); - printf(" BOX64_JITGDB with 1 to launch \"gdb\" when a segfault is trapped, attached to the offending process\n"); - printf(" BOX64_MMAP32=1 to use 32bits address space mmap in priority for external mmap as soon a 32bits process are detected (default for Snapdragon build)\n"); -} - void PrintHelp() { printf("This is Box64, the Linux x86_64 emulator with a twist.\n"); printf("\nUsage is 'box64 [options] path/to/software [args]' to launch x86_64 software.\n"); printf(" options are:\n"); printf(" '-v'|'--version' to print box64 version and quit\n"); printf(" '-h'|'--help' to print this and quit\n"); - printf(" '-f'|'--flags' to print box64 flags and quit\n"); } void addNewEnvVar(const char* s) @@ -1502,33 +556,17 @@ void addNewEnvVar(const char* s) EXPORTDYN void LoadEnvVars(box64context_t *context) { - // Check custom env. var. and add them if needed - { - char* p = getenv("BOX64_ENV"); - if(p) - addNewEnvVar(p); - int i = 1; - char box64_env[50]; - do { - sprintf(box64_env, "BOX64_ENV%d", i); - p = getenv(box64_env); - if(p) { - addNewEnvVar(p); - ++i; - } - } while(p); - } - - if(getenv("BOX64_EMULATED_LIBS")) { - char* p = getenv("BOX64_EMULATED_LIBS"); + if(BOX64ENV(emulated_libs)) { + char* p = BOX64ENV(emulated_libs); ParseList(p, &context->box64_emulated_libs, 0); - if (my_context->box64_emulated_libs.size && box64_log) { + if (my_context->box64_emulated_libs.size && BOX64ENV(log)) { printf_log(LOG_INFO, "BOX64 will force the used of emulated libs for "); for (int i=0; i<context->box64_emulated_libs.size; ++i) printf_log(LOG_INFO, "%s ", context->box64_emulated_libs.paths[i]); printf_log(LOG_INFO, "\n"); } } + // Add libssl and libcrypto (and a few others) to prefer the emulated version because multiple versions exist AddPath("libssl.so.1", &context->box64_emulated_libs, 0); AddPath("libssl.so.1.0.0", &context->box64_emulated_libs, 0); @@ -1541,77 +579,21 @@ void LoadEnvVars(box64context_t *context) AddPath("libtbbmalloc.so.2", &context->box64_emulated_libs, 0); AddPath("libtbbmalloc_proxy.so.2", &context->box64_emulated_libs, 0); - if(getenv("BOX64_SSE_FLUSHTO0")) { - if (strcmp(getenv("BOX64_SSE_FLUSHTO0"), "1")==0) { - box64_sse_flushto0 = 1; - printf_log(LOG_INFO, "BOX64: Direct apply of SSE Flush to 0 flag\n"); - } - } - if(getenv("BOX64_X87_NO80BITS")) { - if (strcmp(getenv("BOX64_X87_NO80BITS"), "1")==0) { - box64_x87_no80bits = 1; - printf_log(LOG_INFO, "BOX64: All 80bits x87 long double will be handle as double\n"); - } + if(BOX64ENV(nosigsegv)) { + context->no_sigsegv = 1; } - if(getenv("BOX64_SYNC_ROUNDING")) { - if (strcmp(getenv("BOX64_SYNC_ROUNDING"), "1")==0) { - box64_sync_rounding = 1; - printf_log(LOG_INFO, "BOX64: Rounding mode will be synced with fesetround/fegetround\n"); - } + if(BOX64ENV(nosigill)) { + context->no_sigill = 1; } - if(getenv("BOX64_PREFER_WRAPPED")) { - if (strcmp(getenv("BOX64_PREFER_WRAPPED"), "1")==0) { - box64_prefer_wrapped = 1; - printf_log(LOG_INFO, "BOX64: Prefering Wrapped libs\n"); - } - } - if(getenv("BOX64_PREFER_EMULATED")) { - if (strcmp(getenv("BOX64_PREFER_EMULATED"), "1")==0) { - box64_prefer_emulated = 1; - printf_log(LOG_INFO, "BOX64: Prefering Emulated libs\n"); - } + if(BOX64ENV(addlibs)) { + AddNewLibs(BOX64ENV(addlibs)); } - if(getenv("BOX64_WRAP_EGL")) { - char* p = getenv("BOX64_WRAP_EGL"); - if (*p>='0' && *p<='1') { - box64_wrap_egl = *p - '0'; - if(box64_wrap_egl) printf_log(LOG_INFO, "BOX64: Prefering Native(Wrapped) EGL/GLESv2\n"); - } - } - - if(getenv("BOX64_NOSIGSEGV")) { - if (strcmp(getenv("BOX64_NOSIGSEGV"), "1")==0) { - context->no_sigsegv = 1; - printf_log(LOG_INFO, "BOX64: Disabling handling of SigSEGV\n"); - } - } - if(getenv("BOX64_NOSIGILL")) { - if (strcmp(getenv("BOX64_NOSIGILL"), "1")==0) { - context->no_sigill = 1; - printf_log(LOG_INFO, "BOX64: Disabling handling of SigILL\n"); - } - } - if(getenv("BOX64_ADDLIBS")) { - AddNewLibs(getenv("BOX64_ADDLIBS")); - } - // check BOX64_PATH and load it - LoadEnvPath(&context->box64_path, ".:bin", "BOX64_PATH"); + loadPath(&context->box64_path, ".:bin", BOX64ENV(path)); if(getenv("PATH")) AppendList(&context->box64_path, getenv("PATH"), 1); // in case some of the path are for x86 world #ifdef HAVE_TRACE - char* p = getenv("BOX64_TRACE"); - if(p) { - if (strcmp(p, "0")) { - context->x64trace = 1; - box64_trace = p; - } - } - p = getenv("BOX64_TRACE_INIT"); - if(p) { - if (strcmp(p, "0")) { - context->x64trace = 1; - trace_init = p; - } + if((BOX64ENV(trace_init) && strcmp(BOX64ENV(trace_init), "0")) || (BOX64ENV(trace) && strcmp(BOX64ENV(trace), "0"))) { + context->x64trace = 1; } if(my_context->x64trace) { printf_log(LOG_INFO, "Initializing Zydis lib\n"); @@ -1626,13 +608,12 @@ void LoadEnvVars(box64context_t *context) EXPORTDYN void LoadLDPath(box64context_t *context) { - // check BOX64_LD_LIBRARY_PATH and load it #ifdef BOX32 if(box64_is32bits) - LoadEnvPath(&context->box64_ld_lib, ".:lib:i386:bin:libs", "BOX64_LD_LIBRARY_PATH"); + loadPath(&context->box64_ld_lib, ".:lib:i386:bin:libs", BOX64ENV(ld_library_path)); else #endif - LoadEnvPath(&context->box64_ld_lib, ".:lib:lib64:x86_64:bin64:libs64", "BOX64_LD_LIBRARY_PATH"); + loadPath(&context->box64_ld_lib, ".:lib:lib64:x86_64:bin64:libs64", BOX64ENV(ld_library_path)); #ifndef TERMUX if(box64_is32bits) { #ifdef BOX32 @@ -1687,7 +668,7 @@ EXPORTDYN void setupTraceInit() { #ifdef HAVE_TRACE - char* p = trace_init; + char* p = BOX64ENV(trace_init); if(p) { setbuf(stdout, NULL); uintptr_t s_trace_start=0, s_trace_end=0; @@ -1719,10 +700,8 @@ void setupTraceInit() } } } else { - p = box64_trace; - if(p) - if (strcmp(p, "0")) - SetTraceEmu(0, 1); + if(BOX64ENV(trace) && strcmp(BOX64ENV(trace), "0")) + SetTraceEmu(0, 1); } #endif } @@ -1758,7 +737,7 @@ EXPORTDYN void setupTrace() { #ifdef HAVE_TRACE - char* p = box64_trace; + char* p = BOX64ENV(trace); if(p) { setbuf(stdout, NULL); uintptr_t s_trace_start=0, s_trace_end=0; @@ -1838,11 +817,11 @@ void endBox64() FreeBox64Context(&my_context); #ifdef DYNAREC // disable dynarec now - box64_dynarec = 0; + SET_BOX64ENV(dynarec, 0); #endif - if(box64_libGL) { - box_free(box64_libGL); - box64_libGL = NULL; + if(BOX64ENV(libgl)) { + box_free(BOX64ENV(libgl)); + SET_BOX64ENV(libgl, NULL); } if(box64_custom_gstreamer) { box_free(box64_custom_gstreamer); @@ -1876,34 +855,6 @@ static void add_argv(const char* what) { } } -static void load_rcfiles() -{ - char* rcpath = getenv("BOX64_RCFILE"); - - if(rcpath && FileExist(rcpath, IS_FILE)) - LoadRCFile(rcpath); - #ifndef TERMUX - else if(FileExist("/etc/box64.box64rc", IS_FILE)) - LoadRCFile("/etc/box64.box64rc"); - else if(FileExist("/data/data/com.termux/files/usr/glibc/etc/box64.box64rc", IS_FILE)) - LoadRCFile("/data/data/com.termux/files/usr/glibc/etc/box64.box64rc"); - #else - else if(FileExist("/data/data/com.termux/files/usr/etc/box64.box64rc", IS_FILE)) - LoadRCFile("/data/data/com.termux/files/usr/etc/box64.box64rc"); - #endif - else - LoadRCFile(NULL); // load default rcfile - - char* p = getenv("HOME"); - if(p) { - char tmp[4096]; - strncpy(tmp, p, 4095); - strncat(tmp, "/.box64rc", 4095); - if(FileExist(tmp, IS_FILE)) - LoadRCFile(tmp); - } -} - #ifndef STATICBUILD void pressure_vessel(int argc, const char** argv, int nextarg, const char* prog); #endif @@ -1930,7 +881,7 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf printf("See 'box64 --help' for more information.\n"); exit(0); } - if(argc>1 && !strcmp(argv[1], "/usr/bin/gdb") && getenv("BOX64_TRACE_FILE")) + if(argc>1 && !strcmp(argv[1], "/usr/bin/gdb") && BOX64ENV(trace_file)) exit(0); // uname -m is redirected to box64 -m if(argc==2 && (!strcmp(argv[1], "-m") || !strcmp(argv[1], "-p") || !strcmp(argv[1], "-i"))) @@ -1939,14 +890,16 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf exit(0); } + ftrace = stdout; + + LoadEnvVariables(); + InitializeEnvFiles(); + // check BOX64_LOG debug level LoadLogEnv(); - if(!getenv("BOX64_NORCFILES")) { - load_rcfiles(); - } char* bashpath = NULL; { - char* p = getenv("BOX64_BASH"); + char* p = BOX64ENV(bash); if(p) { if(FileIsX64ELF(p)) { bashpath = p; @@ -1969,10 +922,6 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf PrintHelp(); exit(0); } - if(!strcmp(prog, "-f") || !strcmp(prog, "--flags")) { - PrintFlags(); - exit(0); - } // other options? if(!strcmp(prog, "--")) { prog = argv[++nextarg]; @@ -1985,8 +934,7 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf printf("BOX64: Nothing to run\n"); exit(0); } - if(!box64_nobanner) - PrintBox64Version(); + if (!BOX64ENV(nobanner)) PrintBox64Version(); // precheck, for win-preload const char* prog_ = strrchr(prog, '/'); if(!prog_) prog_ = prog; else ++prog_; @@ -2028,8 +976,8 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf // special case for winedbg, doesn't work anyway if(argv[nextarg+1] && strstr(argv[nextarg+1], "winedbg")==argv[nextarg+1]) { if(getenv("BOX64_WINEDBG")) { - box64_nobanner = 1; - box64_log = 0; + SET_BOX64ENV(nobanner, 1); + BOX64ENV(log) = 0; } else { printf_log(LOG_NONE, "winedbg detected, not launching it!\n"); exit(0); // exiting, it doesn't work anyway @@ -2045,13 +993,10 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf strcat(tmp, "/../lib64/gstreamer-1.0"); // check if it exist if(FileExist(tmp, 0)) { - //printf_log(LOG_INFO, "BOX64: Custom gstreamer detected, disable gtk wrapping\n"); - //box64_nogtk = 1; - //is_custom_gstreamer = 1; box64_custom_gstreamer = box_strdup(tmp); } } - // Try to get the name of the exe being run, to ApplyParams laters + // Try to get the name of the exe being run, to ApplyEnvFileEntry laters if(argv[nextarg+1] && argv[nextarg+1][0]!='-' && strlen(argv[nextarg+1])>4 && !strcasecmp(argv[nextarg+1]+strlen(argv[nextarg+1])-4, ".exe")) { const char* pp = strrchr(argv[nextarg+1], '/'); if(pp) @@ -2112,7 +1057,7 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf if(getenv("BOX64_LD_PRELOAD")) { char* p = getenv("BOX64_LD_PRELOAD"); ParseList(p, &ld_preload, 0); - if (ld_preload.size && box64_log) { + if (ld_preload.size && BOX64ENV(log)) { printf_log(LOG_INFO, "BOX64 trying to Preload "); for (int i=0; i<ld_preload.size; ++i) printf_log(LOG_INFO, "%s ", ld_preload.paths[i]); @@ -2130,7 +1075,7 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf if(strstr(p, "libasan.so")) box64_tcmalloc_minimal = 1; // it seems Address Sanitizer doesn't handle dlsym'd malloc very well AppendList(&ld_preload, p, 0); - if (ld_preload.size && box64_log) { + if (ld_preload.size && BOX64ENV(log)) { printf_log(LOG_INFO, "BOX64 trying to Preload "); for (int i=0; i<ld_preload.size; ++i) printf_log(LOG_INFO, "%s ", ld_preload.paths[i]); @@ -2148,7 +1093,7 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf my_context->argv[0] = ResolveFileSoft(prog, &my_context->box64_path); // GatherEnv(&my_context->envv, environ?environ:env, my_context->argv[0]); - if(box64_dump || box64_log<=LOG_DEBUG) { + if (BOX64ENV(dump) || BOX64ENV(log)<=LOG_DEBUG) { for (int i=0; i<my_context->envc; ++i) printf_dump(LOG_DEBUG, " Env[%02d]: %s\n", i, my_context->envv[i]); } @@ -2186,10 +1131,10 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf printf_log(LOG_INFO, "Zoom detected, Trying to use system libturbojpeg if possible\n"); box64_zoom = 1; } - // special case for bash (add BOX86_NOBANNER=1 if not there) + // special case for bash if(!strcmp(prgname, "bash") || !strcmp(prgname, "box64-bash")) { printf_log(LOG_INFO, "bash detected, disabling banner\n"); - if (!box64_nobanner) { + if (!BOX64ENV(nobanner)) { setenv("BOX86_NOBANNER", "1", 0); setenv("BOX64_NOBANNER", "1", 0); } @@ -2203,46 +1148,37 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf if(bashpath) my_context->bashpath = box_strdup(bashpath); - /*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); - }*/ - /*if(!strcmp(prgname, "gdb")) { - exit(-1); - }*/ - ApplyParams("*"); // [*] is a special setting for all process - ApplyParams(prgname); - if(box64_wine && wine_prog) { - ApplyParams(wine_prog); + ApplyEnvFileEntry(prgname); + if (box64_wine && wine_prog) { + ApplyEnvFileEntry(wine_prog); wine_prog = NULL; } - if(box64_wine) - box64_maxcpu_immutable = 1; // cannot change once wine is loaded + PrintEnvVariables(); for(int i=1; i<my_context->argc; ++i) { my_context->argv[i] = box_strdup(argv[i+nextarg]); printf_log(LOG_INFO, "argv[%i]=\"%s\"\n", i, my_context->argv[i]); } - if(box64_nosandbox) + if(BOX64ENV(nosandbox)) { add_argv("--no-sandbox"); } - if(box64_inprocessgpu) + if(BOX64ENV(inprocessgpu)) { add_argv("--in-process-gpu"); } - if(box64_cefdisablegpu) + if(BOX64ENV(cefdisablegpu)) { add_argv("-cef-disable-gpu"); } - if(box64_cefdisablegpucompositor) + if(BOX64ENV(cefdisablegpucompositor)) { add_argv("-cef-disable-gpu-compositor"); } // add new args only if there is no args already - if(box64_new_args) { + if(BOX64ENV(args)) { char tmp[256]; - char* p = box64_new_args; + char* p = BOX64ENV(args); int state = 0; char* p2 = p; if(my_context->argc==1 || (my_context->argc==2 && box64_wine)) @@ -2264,12 +1200,10 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf } ++p2; } - box_free(box64_new_args); - box64_new_args = NULL; } - if(box64_insert_args) { + if(BOX64ENV(insert_args)) { char tmp[256]; - char* p = box64_insert_args; + char* p = BOX64ENV(insert_args); int state = 0; char* p2 = p; while(state>=0) { @@ -2290,8 +1224,6 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf } ++p2; } - box_free(box64_insert_args); - box64_insert_args = NULL; } // check if file exist if(!my_context->argv[0] || !FileExist(my_context->argv[0], IS_FILE)) { @@ -2459,8 +1391,9 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf printf_log(LOG_NONE, "Error setting process name (%s)\n", strerror(errno)); else printf_log(LOG_INFO, "Rename process to \"%s\"\n", p); - if(strcmp(prgname, p)) - ApplyParams(p); + if(strcmp(prgname, p)) { + ApplyEnvFileEntry(p); + } // and now all change the argv (so libs libs mesa find the correct program names) char* endp = (char*)argv[argc-1]; while(*endp) @@ -2567,15 +1500,6 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf setupTrace(); *emulator = emu; - -#ifdef DYNAREC - if (box64_dynarec_perf_map) { - char pathname[32]; - snprintf(pathname, sizeof(pathname), "/tmp/perf-%d.map", getpid()); - box64_dynarec_perf_map_fd = open(pathname, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR); - } -#endif - return 0; } @@ -2616,11 +1540,10 @@ int emulate(x64emu_t* emu, elfheader_t* elf_header) #endif #ifdef DYNAREC - if (box64_dynarec_perf_map && box64_dynarec_perf_map_fd != -1) { - close(box64_dynarec_perf_map_fd); - box64_dynarec_perf_map_fd = -1; + if (BOX64ENV(dynarec_perf_map) && BOX64ENV(dynarec_perf_map_fd) != -1) { + close(BOX64ENV(dynarec_perf_map_fd)); + SET_BOX64ENV(dynarec_perf_map_fd, -1); } #endif - return ret; } |