diff options
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/env.c | 501 | ||||
| -rw-r--r-- | src/tools/my_cpuid.c | 84 | ||||
| -rw-r--r-- | src/tools/rcfile.c | 783 |
3 files changed, 543 insertions, 825 deletions
diff --git a/src/tools/env.c b/src/tools/env.c new file mode 100644 index 00000000..dc31dbe7 --- /dev/null +++ b/src/tools/env.c @@ -0,0 +1,501 @@ +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> + +#include "env.h" +#include "khash.h" +#include "debug.h" +#include "fileutils.h" +#include "box64context.h" + +box64env_t box64env = { 0 }; + +KHASH_MAP_INIT_STR(box64env_entry, box64env_t) +static kh_box64env_entry_t* box64env_entries = NULL; +static kh_box64env_entry_t* box64env_entries_gen = NULL; + + +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" +; + +static void applyCustomRules() +{ + if (BOX64ENV(log) == LOG_NEVER) { + SET_BOX64ENV(log, BOX64ENV(log) - 1); + SET_BOX64ENV(dump, 1); + } + + if (BOX64ENV(rolling_log) == 1) { + SET_BOX64ENV(rolling_log, 16); + } + if (BOX64ENV(rolling_log) && BOX64ENV(log) > LOG_INFO) { + SET_BOX64ENV(rolling_log, 0); + } + + if (box64env.is_dynarec_test_str_overridden) { + if (strlen(box64env.dynarec_test_str) == 1) { + if (box64env.dynarec_test_str[0] >= '0' && box64env.dynarec_test_str[0] <= '1') + box64env.dynarec_test = box64env.dynarec_test_str[0] - '0'; + + box64env.dynarec_test_start = 0x0; + box64env.dynarec_test_end = 0x0; + } else if (strchr(box64env.dynarec_test_str, '-')) { + if (sscanf(box64env.dynarec_test_str, "%ld-%ld", &box64env.dynarec_test_start, &box64env.dynarec_test_end) != 2) { + if (sscanf(box64env.dynarec_test_str, "0x%lX-0x%lX", &box64env.dynarec_test_start, &box64env.dynarec_test_end) != 2) + sscanf(box64env.dynarec_test_str, "%lx-%lx", &box64env.dynarec_test_start, &box64env.dynarec_test_end); + } + if (box64env.dynarec_test_end > box64env.dynarec_test_start) { + box64env.dynarec_test = 1; + } else { + box64env.dynarec_test = 0; + } + } + } + + if (box64env.is_nodynarec_overridden) { + if(box64env.nodynarec) { + if (strchr(box64env.nodynarec,'-')) { + if(sscanf(box64env.nodynarec, "%ld-%ld", &box64env.nodynarec_start, &box64env.nodynarec_end)!=2) { + if(sscanf(box64env.nodynarec, "0x%lX-0x%lX", &box64env.nodynarec_start, &box64env.nodynarec_end)!=2) + sscanf(box64env.nodynarec, "%lx-%lx", &box64env.nodynarec_start, &box64env.nodynarec_end); + } + } + } + } + + if (box64env.dynarec_test) { + SET_BOX64ENV(dynarec_fastnan, 0); + SET_BOX64ENV(dynarec_fastround, 0); + SET_BOX64ENV(dynarec_x87double, 1); + SET_BOX64ENV(dynarec_div0, 1); + SET_BOX64ENV(dynarec_callret, 0); +#if defined(RV64) || defined(LA64) + SET_BOX64ENV(dynarec_nativeflags, 0); +#endif + } + + if (box64env.maxcpu == 0 || (!box64_wine && box64env.new_maxcpu < box64env.maxcpu)) { + box64env.maxcpu = box64env.new_maxcpu; + } + + if (box64env.dynarec_perf_map) { + char pathname[32]; + snprintf(pathname, sizeof(pathname), "/tmp/perf-%d.map", getpid()); + SET_BOX64ENV(dynarec_perf_map_fd, open(pathname, O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR)); + } + if (!box64env.libgl) { + const char *p = getenv("SDL_VIDEO_GL_DRIVER"); + if(p) SET_BOX64ENV(libgl, box_strdup(p)); + } + if (box64env.avx == 2) { + box64env.avx = 1; + box64env.avx2 = 1; + } + + if (box64env.exit) exit(0); + + if (box64env.env) setenv("BOX64_ENV", "1", 1); + if (box64env.env1) setenv("BOX64_ENV1", "1", 1); + if (box64env.env2) setenv("BOX64_ENV2", "1", 1); + if (box64env.env3) setenv("BOX64_ENV3", "1", 1); + if (box64env.env4) setenv("BOX64_ENV4", "1", 1); + if (box64env.env5) setenv("BOX64_ENV5", "1", 1); +} + +static void trimStringInplace(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)); +} + +static void freeEnv(box64env_t* env) +{ +#define INTEGER(NAME, name, default, min, max) +#define INTEGER64(NAME, name, default) +#define BOOLEAN(NAME, name, default) +#define ADDRESS(NAME, name) +#define STRING(NAME, name) box_free(env->name); + ENVSUPER() +#undef INTEGER +#undef INTEGER64 +#undef BOOLEAN +#undef ADDRESS +#undef STRING +} + +static void pushNewEntry(const char* name, box64env_t* env, int gen) +{ + khint_t k; + kh_box64env_entry_t* khp = gen ? box64env_entries_gen : box64env_entries; + k = kh_get(box64env_entry, khp, name); + if (k == kh_end(khp)) { + int ret; + k = kh_put(box64env_entry, khp, strdup(name), &ret); + } else { + freeEnv(&kh_value(khp, k)); + } + box64env_t* p = &kh_value(khp, k); + memcpy(p, env, sizeof(box64env_t)); +} + +#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 + +static void initializeEnvFile(const char* filename) +{ + if (box64env.noenvfiles) return; + + 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("Error: Cannot open env file %s\n", filename); + return; + } + + if (!box64env_entries) + box64env_entries = kh_init(box64env_entry); + if (!box64env_entries_gen) + box64env_entries_gen = kh_init(box64env_entry); + + box64env_t current_env = { 0 }; + size_t linesize = 0, len = 0; + char *line = NULL, *current_name = NULL; + int ret; + bool is_wildcard_name = false; + while ((ret = getline(&line, &linesize, f)) != -1) { + // remove comments + char* p = strchr(line, '#'); + if (p) *p = '\0'; + trimStringInplace(line); + len = strlen(line); + if (line[0] == '[' && strchr(line, ']')) { + // new entry, push the previous one + if (current_name) + pushNewEntry(current_name, ¤t_env, is_wildcard_name); + is_wildcard_name = (line[1] == '*' && line[(intptr_t)(strchr(line, ']') - line) - 1] == '*'); + memset(¤t_env, 0, sizeof(current_env)); + box_free(current_name); + current_name = LowerCase(line + (is_wildcard_name ? 2 : 1)); + *(strchr(current_name, ']') + 1 - (is_wildcard_name ? 2 : 1)) = '\0'; + trimStringInplace(current_name); + } else if (strchr(line, '=')) { + char* key = line; + char* val = strchr(key, '=') + 1; + *strchr(key, '=') = '\0'; + trimStringInplace(key); + trimStringInplace(val); +#define INTEGER(NAME, name, default, min, max) \ + else if (!strcmp(key, #NAME)) \ + { \ + int v = strtol(val, &p, 0); \ + if (p != val && v >= min && v <= max) { \ + current_env.is_##name##_overridden = 1; \ + current_env.name = v; \ + } \ + } +#define INTEGER64(NAME, name, default) \ + else if (!strcmp(key, #NAME)) \ + { \ + int64_t v = strtoll(val, &p, 0); \ + if (p != val) { \ + current_env.is_##name##_overridden = 1; \ + current_env.name = v; \ + } \ + } +#define BOOLEAN(NAME, name, default) \ + else if (!strcmp(key, #NAME)) \ + { \ + if (strcmp(val, "0")) { \ + current_env.is_##name##_overridden = 1; \ + current_env.name = 1; \ + } else { \ + current_env.is_##name##_overridden = 1; \ + current_env.name = 0; \ + } \ + } +#define ADDRESS(NAME, name) \ + else if (!strcmp(key, #NAME)) \ + { \ + uintptr_t v = (uintptr_t)strtoll(val, &p, 0); \ + if (p != val) { \ + current_env.is_##name##_overridden = 1; \ + current_env.name = v; \ + } \ + } +#define STRING(NAME, name) \ + else if (!strcmp(key, #NAME)) \ + { \ + current_env.is_##name##_overridden = 1; \ + if (current_env.name) box_free(current_env.name); \ + current_env.name = strdup(val); \ + } + if (0) + ; + ENVSUPER() + else if (len && current_name) + { + printf_log(LOG_INFO, "BOX64ENV: Warning, unsupported %s=%s for [%s] in %s\n", key, val, current_name, filename); + } +#undef INTEGER +#undef INTEGER64 +#undef BOOLEAN +#undef ADDRESS +#undef STRING + } + } + // push the last entry + if (current_name) { + pushNewEntry(current_name, ¤t_env, is_wildcard_name); + box_free(current_name); + } + box_free(line); + fclose(f); +} + + +void InitializeEnvFiles() +{ + if (BOX64ENV(envfile) && FileExist(BOX64ENV(envfile), IS_FILE)) + initializeEnvFile(BOX64ENV(envfile)); +#ifndef TERMUX + else if (FileExist("/etc/box64.box64rc", IS_FILE)) + initializeEnvFile("/etc/box64.box64rc"); + else if (FileExist("/data/data/com.termux/files/usr/glibc/etc/box64.box64rc", IS_FILE)) + initializeEnvFile("/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)) + initializeEnvFile("/data/data/com.termux/files/usr/etc/box64.box64rc"); +#endif + else + initializeEnvFile(NULL); // load default rcfile + + char* p = getenv("HOME"); + if (p) { + static char tmp[4096]; + strncpy(tmp, p, 4095); + strncat(tmp, "/.box64rc", 4095); + if (FileExist(tmp, IS_FILE)) { + initializeEnvFile(tmp); + } + } +} + +static char old_entryname[256] = ""; +const char* GetLastApplyEntryName() +{ + return old_entryname; +} +static void internalEnvFileEntry(const char* entryname, const box64env_t* env) +{ +#define INTEGER(NAME, name, default, min, max) \ + if (env->is_##name##_overridden) { \ + box64env.name = env->name; \ + box64env.is_##name##_overridden = 1; \ + } +#define INTEGER64(NAME, name, default) \ + if (env->is_##name##_overridden) { \ + box64env.name = env->name; \ + box64env.is_##name##_overridden = 1; \ + } +#define BOOLEAN(NAME, name, default) \ + if (env->is_##name##_overridden) { \ + box64env.name = env->name; \ + box64env.is_##name##_overridden = 1; \ + } +#define ADDRESS(NAME, name) \ + if (env->is_##name##_overridden) { \ + box64env.name = env->name; \ + box64env.is_##name##_overridden = 1; \ + } +#define STRING(NAME, name) \ + if (env->is_##name##_overridden) { \ + box64env.name = env->name; \ + box64env.is_##name##_overridden = 1; \ + } + ENVSUPER() +#undef INTEGER +#undef INTEGER64 +#undef BOOLEAN +#undef ADDRESS +#undef STRING +} + +void ApplyEnvFileEntry(const char* entryname) +{ + if (!entryname || !box64env_entries) return; + if (!strcasecmp(entryname, old_entryname)) return; + + strncpy(old_entryname, entryname, 255); + khint_t k1; + { + char* lowercase_entryname = LowerCase(entryname); + k1 = kh_get(box64env_entry, box64env_entries, lowercase_entryname); + box64env_t* env; + const char* k2; + kh_foreach_ref(box64env_entries_gen, k2, env, + if (strstr(lowercase_entryname, k2)) + internalEnvFileEntry(entryname, env);) + box_free(lowercase_entryname); + } + if (k1 == kh_end(box64env_entries)) return; + + box64env_t* env = &kh_value(box64env_entries, k1); + internalEnvFileEntry(entryname, env); + applyCustomRules(); +} + +void LoadEnvVariables() +{ +#define INTEGER(NAME, name, default, min, max) box64env.name = default; +#define INTEGER64(NAME, name, default) box64env.name = default; +#define BOOLEAN(NAME, name, default) box64env.name = default; +#define ADDRESS(NAME, name) box64env.name = 0; +#define STRING(NAME, name) box64env.name = NULL; + ENVSUPER() +#undef INTEGER +#undef INTEGER64 +#undef BOOLEAN +#undef ADDRESS +#undef STRING + + char* p; + // load env vars from getenv() +#define INTEGER(NAME, name, default, min, max) \ + p = getenv(#NAME); \ + if (p) { \ + box64env.name = atoi(p); \ + if (box64env.name < min || box64env.name > max) { \ + box64env.name = default; \ + } else { \ + box64env.is_##name##_overridden = 1; \ + } \ + } +#define INTEGER64(NAME, name, default) \ + p = getenv(#NAME); \ + if (p) { \ + box64env.name = atoll(p); \ + box64env.is_##name##_overridden = 1; \ + } +#define BOOLEAN(NAME, name, default) \ + p = getenv(#NAME); \ + if (p) { \ + box64env.name = p[0] != '0'; \ + box64env.is_##name##_overridden = 1; \ + } +#define ADDRESS(NAME, name) \ + p = getenv(#NAME); \ + if (p) { \ + box64env.name = (uintptr_t)atoll(p); \ + box64env.is_##name##_overridden = 1; \ + } +#define STRING(NAME, name) \ + p = getenv(#NAME); \ + if (p) { \ + box64env.name = strdup(p); \ + box64env.is_##name##_overridden = 1; \ + } + ENVSUPER() +#undef INTEGER +#undef INTEGER64 +#undef BOOLEAN +#undef ADDRESS +#undef STRING + applyCustomRules(); +} + +void PrintEnvVariables() +{ + printf_log(LOG_INFO, "BOX64ENV: Variables overridden via env and/or RC file:\n"); +#define INTEGER(NAME, name, default, min, max) \ + if (box64env.is_##name##_overridden) \ + printf_log(LOG_INFO, "\t%s=%d\n", #NAME, box64env.name); +#define INTEGER64(NAME, name, default) \ + if (box64env.is_##name##_overridden) \ + printf_log(LOG_INFO, "\t%s=%lld\n", #NAME, box64env.name); +#define BOOLEAN(NAME, name, default) \ + if (box64env.is_##name##_overridden) \ + printf_log(LOG_INFO, "\t%s=%d\n", #NAME, box64env.name); +#define ADDRESS(NAME, name) \ + if (box64env.is_##name##_overridden) \ + printf_log(LOG_INFO, "\t%s=%p\n", #NAME, (void*)box64env.name); +#define STRING(NAME, name) \ + if (box64env.is_##name##_overridden) \ + printf_log(LOG_INFO, "\t%s=%s\n", #NAME, box64env.name); + ENVSUPER() +#undef INTEGER +#undef INTEGER64 +#undef BOOLEAN +#undef ADDRESS +#undef STRING +} diff --git a/src/tools/my_cpuid.c b/src/tools/my_cpuid.c index 7316937a..b07e19c9 100644 --- a/src/tools/my_cpuid.c +++ b/src/tools/my_cpuid.c @@ -108,8 +108,8 @@ int getNCpu() { if(!nCPU) grabNCpu(); - if(box64_maxcpu && nCPU>box64_maxcpu) - return box64_maxcpu; + if(BOX64ENV(maxcpu) && nCPU>BOX64ENV(maxcpu)) + return BOX64ENV(maxcpu); return nCPU; } @@ -200,7 +200,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) int ncpu = getNCpu(); if(!ncpu) ncpu = 1; int ncluster = 1; - if(box64_cputype) { + if(BOX64ENV(cputype)) { while(ncpu>256) { ncluster++; // do cluster of 256 cpus... if(ncpu>=256) @@ -228,8 +228,8 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) switch(tmp32u) { case 0x0: // emulate a P4. TODO: Emulate a Core2? - R_EAX = box64_cputype?0x0000000f:0x0000000f;//was 0x15 before, but something seems wrong for leaf 0x15, and cpu-z take that as pure cpu speed... - if(box64_cputype) { + R_EAX = BOX64ENV(cputype)?0x0000000f:0x0000000f;//was 0x15 before, but something seems wrong for leaf 0x15, and cpu-z take that as pure cpu speed... + if(BOX64ENV(cputype)) { // return AuthenticAMD R_EBX = 0x68747541; R_ECX = 0x444d4163; @@ -242,7 +242,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0x1: - if(box64_cputype) { + if(BOX64ENV(cputype)) { R_EAX = (0xc<<0) | // stepping 0-3 (0x1<<4) | // base model 4-7 (0xf<<8) | // base familly 8-11 @@ -261,7 +261,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) (0x0<<20)| // extended familly 0 ; // family and all, simulating Haswell type of cpu } - R_EBX = 0 | (8<<0x8) | ((box64_cputype?0:ncluster)<<16); // Brand index, CLFlush (8), Max APIC ID (16-23), Local APIC ID (24-31) + R_EBX = 0 | (8<<0x8) | ((BOX64ENV(cputype)?0:ncluster)<<16); // Brand index, CLFlush (8), Max APIC ID (16-23), Local APIC ID (24-31) /*{ int cpu = sched_getcpu(); if(cpu<0) cpu=0; @@ -289,31 +289,31 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) | 1<<24 // fxsr (fxsave, fxrestore) | 1<<25 // SSE | 1<<26 // SSE2 - | (box64_cputype?0:1)<<28 // HT / Multi-core + | (BOX64ENV(cputype)?0:1)<<28 // HT / Multi-core ; R_ECX = 1<<0 // SSE3 | 1<<1 // PCLMULQDQ - | (box64_cputype?0:1)<<2 // DS 64bits + | (BOX64ENV(cputype)?0:1)<<2 // DS 64bits | 1<<3 // Monitor/MWait (priviledge instructions) - | (box64_cputype?0:1)<<5 // VMX //is that usefull + | (BOX64ENV(cputype)?0:1)<<5 // VMX //is that usefull | 1<<9 // SSSE3 - | box64_avx2<<12 // fma + | BOX64ENV(avx2)<<12 // fma | 1<<13 // cx16 (cmpxchg16) | 1<<19 // SSE4_1 - | box64_sse42<<20 // SSE4_2 can be hiden + | BOX64ENV(sse42)<<20 // SSE4_2 can be hiden | 1<<22 // MOVBE | 1<<23 // POPCOUNT | 1<<25 // aesni - | box64_avx<<26 // xsave - | box64_avx<<27 // osxsave - | box64_avx<<28 // AVX - | box64_avx<<29 // F16C - | box64_avx2<<30 // RDRAND + | BOX64ENV(avx)<<26 // xsave + | BOX64ENV(avx)<<27 // osxsave + | BOX64ENV(avx)<<28 // AVX + | BOX64ENV(avx)<<29 // F16C + | BOX64ENV(avx2)<<30 // RDRAND | 0<<31 // Hypervisor guest running ; break; case 0x2: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // reserved R_EAX = R_EBX = R_ECX = R_EDX = 0 ; } else { @@ -326,7 +326,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) break; case 0x4: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // reserved R_EAX = R_EBX = R_ECX = R_EDX = 0 ; } else { @@ -381,23 +381,23 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) if(R_ECX==0) { R_EAX = 0; R_EBX = - box64_avx<<3 | // BMI1 - box64_avx2<<5 | //AVX2 - (box64_cputype?0:1)<<6 | // FDP_EXCPTN_ONLY + BOX64ENV(avx)<<3 | // BMI1 + BOX64ENV(avx2)<<5 | //AVX2 + (BOX64ENV(cputype)?0:1)<<6 | // FDP_EXCPTN_ONLY 1<<7 | // SMEP - box64_avx2<<8 | //BMI2 - (box64_cputype?0:1)<<9 | // Enhanced REP MOVSB // is it a good idea? + BOX64ENV(avx2)<<8 | //BMI2 + (BOX64ENV(cputype)?0:1)<<9 | // Enhanced REP MOVSB // is it a good idea? 1<<10 | //INVPCID (priviledge instruction - (box64_cputype?0:1)<<13 | // Deprecates FPU CS and FPU DS + (BOX64ENV(cputype)?0:1)<<13 | // Deprecates FPU CS and FPU DS 0<<18 | // RDSEED - box64_avx2<<19 | //ADX + BOX64ENV(avx2)<<19 | //ADX 1<<23 | // CLFLUSHOPT 1<<24 | // CLWB - box64_shaext<<29| // SHA extension + BOX64ENV(shaext)<<29| // SHA extension 0; R_RCX = - box64_avx<<9 | //VAES - box64_avx2<<10 | //VPCLMULQDQ. + BOX64ENV(avx)<<9 | //VAES + BOX64ENV(avx2)<<10 | //VPCLMULQDQ. 1<<22 | // RDPID 0; R_RDX = 0; @@ -405,7 +405,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } else {R_EAX = R_ECX = R_EBX = R_EDX = 0;} break; case 0xB: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // reserved R_EAX = R_EBX = R_ECX = R_EDX = 0 ; } else { @@ -416,7 +416,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0xC: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // reserved R_EAX = R_EBX = R_ECX = R_EDX = 0 ; } else { @@ -453,7 +453,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) R_EAX = 0; break; case 0xF: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // reserved R_EAX = R_EBX = R_ECX = R_EDX = 0 ; } else { @@ -475,7 +475,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0x14: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // reserved R_EAX = R_EBX = R_ECX = R_EDX = 0 ; } else { @@ -492,7 +492,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0x15: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // reserved R_EAX = R_EBX = R_ECX = R_EDX = 0 ; } else { @@ -512,7 +512,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) break; case 0x80000000: // max extended - if(box64_cputype) { + if(BOX64ENV(cputype)) { R_EAX = 0x8000001a; R_EBX = 0x68747541; R_ECX = 0x444d4163; @@ -522,7 +522,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0x80000001: //Extended Processor Signature and Feature Bits - if(box64_cputype) { + if(BOX64ENV(cputype)) { R_EAX = (0xc<<0) | // stepping 0-3 (0x1<<4) | // base model 4-7 (0xf<<8) | // base familly 8-11 @@ -606,7 +606,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) R_EDX = ((uint32_t*)branding)[11]; break; case 0x80000005: - if(box64_cputype) { + if(BOX64ENV(cputype)) { //L1 cache and TLB R_EAX = 0; R_EBX = 0; @@ -620,7 +620,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0x80000006: // L2 cache line size and associativity - if(box64_cputype) { + if(BOX64ENV(cputype)) { R_EAX = 0; R_EBX = 0; R_ECX = 64 | (0x6<<12) | (256<<16); // bits: 0-7 line size, 15-12: assoc (using special encoding), 31-16: size in K //TODO: read info from /sys/devices/system/cpu/cpuX/cache/index2 @@ -633,7 +633,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0x80000007: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // Advanced Power Management Information R_EAX = 0; R_EBX = 0; @@ -648,7 +648,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0x80000008: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // Address Size And Physical Core Count Information R_EAX = 0; // 23-16 guest / 15-8 linear / 7-0 phys R_EBX = 0; // reserved @@ -663,7 +663,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0x8000000a: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // SVM Revision and Feature Identification R_EAX = 0; R_EBX = 0; @@ -678,7 +678,7 @@ void my_cpuid(x64emu_t* emu, uint32_t tmp32u) } break; case 0x8000001a: - if(box64_cputype) { + if(BOX64ENV(cputype)) { // Performance Optimization Identifiers R_EAX = 1<<0 // FP128 | 1<<1 // MOVU diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c deleted file mode 100644 index 674ec52d..00000000 --- a/src/tools/rcfile.c +++ /dev/null @@ -1,783 +0,0 @@ -#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" - -// 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_WRAP_EGl, box64_wrap_egl) \ -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) \ -ENTRYSTRING_(BOX64_ARGS, new_args) \ -ENTRYSTRING_(BOX64_INSERT_ARGS, insert_args) \ -ENTRYBOOL(BOX64_RESERVE_HIGH, new_reserve_high) \ -ENTRYINT(BOX64_CPUTYPE, box64_cputype, 0, 1, 1) \ - -#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, 3, 2) \ -ENTRYINT(BOX64_DYNAREC_WEAKBARRIER, box64_dynarec_weakbarrier, 0, 2, 2) \ -ENTRYINT(BOX64_DYNAREC_PAUSE, box64_dynarec_pause, 0, 3, 2) \ -ENTRYBOOL(BOX64_DYNAREC_X87DOUBLE, box64_dynarec_x87double) \ -ENTRYBOOL(BOX64_DYNAREC_DIV0, box64_dynarec_div0) \ -ENTRYBOOL(BOX64_DYNAREC_FASTNAN, box64_dynarec_fastnan) \ -ENTRYINT(BOX64_DYNAREC_FASTROUND, box64_dynarec_fastround, 0, 2, 2) \ -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_NATIVEFLAGS, box64_dynarec_nativeflags) \ -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) \ -ENTRYBOOL(BOX64_DYNAREC_DF, box64_dynarec_df) \ -ENTRYBOOL(BOX64_DYNAREC_DIRTY, box64_dynarec_dirty) \ - -#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_WEAKBARRIER) \ -IGNORE(BOX64_DYNAREC_PAUSE) \ -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_NATIVEFLAGS) \ -IGNORE(BOX64_DYNAREC_WAIT) \ -IGNORE(BOX64_NODYNAREC) \ -IGNORE(BOX64_DYNAREC_TEST) \ -IGNORE(BOX64_DYNAREC_MISSING) \ -IGNORE(BOX64_DYNAREC_DF) \ -IGNORE(BOX64_DYNAREC_DIRTY) \ - -#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 kh_params_t *params_gen = 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) box_free(param->name); - #define ENTRYSTRING_(NAME, name) box_free(param->name); - #define ENTRYDSTRING(NAME, name) box_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, int gen) -{ - khint_t k; - kh_params_t* khp = gen?params_gen:params; - k = kh_get(params, khp, name); - if(k==kh_end(khp)) { - int ret; - k = kh_put(params, khp, box_strdup(name), &ret); - } else { - clearParam(&kh_value(khp, k)); - } - my_params_t *p = &kh_value(khp, 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); - if(!params_gen) - params_gen = 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; - int decor = 1; - // 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, (decor==2)); - if(line[1]=='*' && line[(intptr_t)(strchr(line, ']')-line)-1]=='*') - decor = 2; - else - decor = 1; - // prepare a new entry - memset(¤t_param, 0, sizeof(current_param)); - box_free(current_name); - current_name = LowerCase(line+decor); - *(strchr(current_name, ']')+1-decor) = '\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) box_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, (decor==2)); - box_free(current_name); - } - box_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, box_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; -extern char* box64_new_args; -extern char* box64_insert_args; -void openFTrace(const char* newtrace, int reopen); -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 internal_ApplyParams(const char* name, const my_params_t* param); -void ApplyParams(const char* name) -{ - if(!name || !params) - return; - if(!strcasecmp(name, old_name)) { - return; - } - strncpy(old_name, name, 255); - khint_t k1; - { - char* lname = LowerCase(name); - k1 = kh_get(params, params, lname); - my_params_t* param; - const char* k2; - kh_foreach_ref(params_gen, k2, param, - if(strstr(lname, k2)) - internal_ApplyParams(name, param); - ) - box_free(lname); - } - if(k1 == kh_end(params)) - return; - my_params_t* param = &kh_value(params, k1); - internal_ApplyParams(name, param); -} - -void internal_ApplyParams(const char* name, const my_params_t* param) { - 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; - 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) {printf_log(LOG_INFO, "Applying %s=%d\n", #NAME, param->name); name = param->name;} - #define ENTRYBOOL(NAME, name) ENTRYINT(NAME, name, 0, 1, 1) - #define CENTRYBOOL(NAME, name) if(param->is_##name##_present) {printf_log(LOG_INFO, "Applying %s=%d\n", #NAME, param->name); my_context->name = param->name;} - #define ENTRYINTPOS(NAME, name) if(param->is_##name##_present) {printf_log(LOG_INFO, "Applying %s=%d\n", #NAME, param->name); name = param->name;} - #define ENTRYSTRING(NAME, name) if(param->is_##name##_present) {printf_log(LOG_INFO, "Applying %s=%s\n", #NAME, param->name); name = param->name;} - #define ENTRYSTRING_(NAME, name) - #define ENTRYDSTRING(NAME, name) if(param->is_##name##_present) {printf_log(LOG_INFO, "Applying %s=%s\n", #NAME, param->name); if(name) box_free(name); name = box_strdup(param->name);} - #define ENTRYADDR(NAME, name) if(param->is_##name##_present) {printf_log(LOG_INFO, "Applying %s=%zd\n", #NAME, param->name); name = param->name;} - #define ENTRYULONG(NAME, name) if(param->is_##name##_present) {printf_log(LOG_INFO, "Applying %s=%lld\n", #NAME, param->name); 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_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) { - // 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, 0); - } - if(param->is_emulated_libs_present) { - printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_EMULATED_LIBS", param->emulated_libs); - AppendList(&my_context->box64_emulated_libs, param->emulated_libs, 0); - } - if(param->is_new_addlibs_present) { - AddNewLibs(param->new_addlibs); - } - if(param->is_new_env_present) { - printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV", param->new_env); - addNewEnvVar(param->new_env); - } - if(param->is_new_env1_present) { - printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV1", param->new_env1); - addNewEnvVar(param->new_env1); - } - if(param->is_new_env2_present) { - printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV2", param->new_env2); - addNewEnvVar(param->new_env2); - } - if(param->is_new_env3_present) { - printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV3", param->new_env3); - addNewEnvVar(param->new_env3); - } - if(param->is_new_env4_present) { - printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_ENV4", param->new_env4); - addNewEnvVar(param->new_env4); - } - if(param->is_new_args_present) { - printf_log(LOG_INFO, "Adding \"%s\" arguments to command line\n", param->new_args); - if(box64_new_args) - box_free(box64_new_args); - box64_new_args = box_strdup(param->new_args); - } - if(param->is_insert_args_present) { - printf_log(LOG_INFO, "Adding \"%s\" arguments to command line\n", param->insert_args); - if(box64_insert_args) - box_free(box64_insert_args); - box64_insert_args = box_strdup(param->insert_args); - } - if(param->is_bash_present && FileIsX64ELF(param->bash)) { - printf_log(LOG_INFO, "Applying %s=%s\n", "BOX64_BASH", param->bash); - if(my_context->bashpath) - box_free(my_context->bashpath); - my_context->bashpath = box_strdup(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; - printf_log(LOG_INFO, "Appling BOX64_DYNAREC_TEST=%d\n", box64_dynarec_test); - } 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) { - printf_log(LOG_INFO, "Appling BOX64_DYNAREC_FORWARD=%d\n", box64_dynarec_forward); - box64_dynarec_forward = 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; - #if defined(RV64) || defined(LA64) - box64_dynarec_nativeflags = 0; - #endif - } - #endif - if(box64_log==3) { - box64_log = 2; - box64_dump = 1; - } -} |