about summary refs log tree commit diff stats
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/env.c501
-rw-r--r--src/tools/my_cpuid.c84
-rw-r--r--src/tools/rcfile.c783
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, &current_env, is_wildcard_name);
+            is_wildcard_name = (line[1] == '*' && line[(intptr_t)(strchr(line, ']') - line) - 1] == '*');
+            memset(&current_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, &current_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, &current_param, (decor==2));
-            if(line[1]=='*' && line[(intptr_t)(strchr(line, ']')-line)-1]=='*')
-                decor = 2;
-            else
-                decor = 1;
-            // prepare a new entry
-            memset(&current_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, &current_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;
-    }
-}