about summary refs log tree commit diff stats
path: root/src/wrapped/wrappedlibc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wrapped/wrappedlibc.c')
-rw-r--r--src/wrapped/wrappedlibc.c314
1 files changed, 188 insertions, 126 deletions
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index cc68c216..ff20404e 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -24,7 +24,7 @@
 #include <poll.h>
 #include <sys/epoll.h>
 #include <ftw.h>
-#include <sys/syscall.h> 
+#include <sys/syscall.h>
 #include <sys/socket.h>
 #include <sys/utsname.h>
 #include <sys/mman.h>
@@ -131,10 +131,10 @@ GO(15)
 
 // compare
 #define GO(A)   \
-static uintptr_t my_compare_fct_##A = 0;        \
-static int my_compare_##A(void* a, void* b)     \
-{                                               \
-    return (int)RunFunction(my_context, my_compare_fct_##A, 2, a, b);\
+static uintptr_t my_compare_fct_##A = 0;                                    \
+static int my_compare_##A(void* a, void* b)                                 \
+{                                                                           \
+    return (int)RunFunctionFmt(my_compare_fct_##A, "pp", a, b);       \
 }
 SUPER()
 #undef GO
@@ -160,7 +160,7 @@ static int my_ftw64_##A(void* fpath, void* sb, int flag)    \
 {                                                           \
     struct x64_stat64 x64st;                                \
     UnalignStat64(sb, &x64st);                              \
-    return (int)RunFunction(my_context, my_ftw64_fct_##A, 3, fpath, &x64st, flag);  \
+    return (int)RunFunctionFmt(my_ftw64_fct_##A, "ppi", fpath, &x64st, flag);         \
 }
 SUPER()
 #undef GO
@@ -182,9 +182,9 @@ static void* findftw64Fct(void* fct)
 static uintptr_t my_nftw64_fct_##A = 0;                                     \
 static int my_nftw64_##A(void* fpath, void* sb, int flag, void* ftwbuff)    \
 {                                                                           \
-    struct x64_stat64 x64st;                                              \
-    UnalignStat64(sb, &x64st);                                             \
-    return (int)RunFunction(my_context, my_nftw64_fct_##A, 4, fpath, &x64st, flag, ftwbuff);   \
+    struct x64_stat64 x64st;                                                \
+    UnalignStat64(sb, &x64st);                                              \
+    return (int)RunFunctionFmt(my_nftw64_fct_##A, "ppip", fpath, &x64st, flag, ftwbuff);          \
 }
 SUPER()
 #undef GO
@@ -202,10 +202,10 @@ static void* findnftw64Fct(void* fct)
 }
 // globerr
 #define GO(A)   \
-static uintptr_t my_globerr_fct_##A = 0;                                        \
-static int my_globerr_##A(void* epath, int eerrno)                              \
-{                                                                               \
-    return (int)RunFunction(my_context, my_globerr_fct_##A, 2, epath, eerrno);  \
+static uintptr_t my_globerr_fct_##A = 0;                                                \
+static int my_globerr_##A(void* epath, int eerrno)                                      \
+{                                                                                       \
+    return (int)RunFunctionFmt(my_globerr_fct_##A, "pi", epath, eerrno);          \
 }
 SUPER()
 #undef GO
@@ -225,10 +225,10 @@ static void* findgloberrFct(void* fct)
 }
 // free
 #define GO(A)   \
-static uintptr_t my_free_fct_##A = 0;               \
-static void my_free_##A(void* p)                    \
-{                                                   \
-    RunFunction(my_context, my_free_fct_##A, 1, p); \
+static uintptr_t my_free_fct_##A = 0;                       \
+static void my_free_##A(void* p)                            \
+{                                                           \
+    RunFunctionFmt(my_free_fct_##A, "p", p);          \
 }
 SUPER()
 #undef GO
@@ -251,10 +251,10 @@ static void* findfreeFct(void* fct)
 #undef dirent
 // filter_dir
 #define GO(A)   \
-static uintptr_t my_filter_dir_fct_##A = 0;                               \
-static int my_filter_dir_##A(const struct dirent* a)                    \
-{                                                                       \
-    return (int)RunFunction(my_context, my_filter_dir_fct_##A, 1, a);     \
+static uintptr_t my_filter_dir_fct_##A = 0;                                 \
+static int my_filter_dir_##A(const struct dirent* a)                        \
+{                                                                           \
+    return (int)RunFunctionFmt(my_filter_dir_fct_##A, "p", a);        \
 }
 SUPER()
 #undef GO
@@ -274,10 +274,10 @@ static void* findfilter_dirFct(void* fct)
 }
 // compare_dir
 #define GO(A)   \
-static uintptr_t my_compare_dir_fct_##A = 0;                                  \
-static int my_compare_dir_##A(const struct dirent* a, const struct dirent* b)    \
-{                                                                           \
-    return (int)RunFunction(my_context, my_compare_dir_fct_##A, 2, a, b);     \
+static uintptr_t my_compare_dir_fct_##A = 0;                                    \
+static int my_compare_dir_##A(const struct dirent* a, const struct dirent* b)   \
+{                                                                               \
+    return (int)RunFunctionFmt(my_compare_dir_fct_##A, "pp", a, b);       \
 }
 SUPER()
 #undef GO
@@ -299,10 +299,10 @@ static void* findcompare_dirFct(void* fct)
 
 // filter64
 #define GO(A)   \
-static uintptr_t my_filter64_fct_##A = 0;                               \
-static int my_filter64_##A(const struct dirent64* a)                    \
-{                                                                       \
-    return (int)RunFunction(my_context, my_filter64_fct_##A, 1, a);     \
+static uintptr_t my_filter64_fct_##A = 0;                                   \
+static int my_filter64_##A(const struct dirent64* a)                        \
+{                                                                           \
+    return (int)RunFunctionFmt(my_filter64_fct_##A, "p", a);          \
 }
 SUPER()
 #undef GO
@@ -325,7 +325,7 @@ static void* findfilter64Fct(void* fct)
 static uintptr_t my_compare64_fct_##A = 0;                                      \
 static int my_compare64_##A(const struct dirent64* a, const struct dirent64* b) \
 {                                                                               \
-    return (int)RunFunction(my_context, my_compare64_fct_##A, 2, a, b);         \
+    return (int)RunFunctionFmt(my_compare64_fct_##A, "pp", a, b);         \
 }
 SUPER()
 #undef GO
@@ -345,10 +345,10 @@ static void* findcompare64Fct(void* fct)
 }
 // printf_output
 #define GO(A)   \
-static uintptr_t my_printf_output_fct_##A = 0;                                  \
-static int my_printf_output_##A(void* a, void* b, void* c)                      \
-{                                                                               \
-    return (int)RunFunction(my_context, my_printf_output_fct_##A, 3, a, b, c);  \
+static uintptr_t my_printf_output_fct_##A = 0;                                          \
+static int my_printf_output_##A(void* a, void* b, void* c)                              \
+{                                                                                       \
+    return (int)RunFunctionFmt(my_printf_output_fct_##A, "ppp", a, b, c);         \
 }
 SUPER()
 #undef GO
@@ -368,10 +368,10 @@ static void* findprintf_outputFct(void* fct)
 }
 // printf_arginfo
 #define GO(A)   \
-static uintptr_t my_printf_arginfo_fct_##A = 0;                                     \
-static int my_printf_arginfo_##A(void* a, size_t b, void* c, void* d)               \
-{                                                                                   \
-    return (int)RunFunction(my_context, my_printf_arginfo_fct_##A, 4, a, b, c, d);  \
+static uintptr_t my_printf_arginfo_fct_##A = 0;                                             \
+static int my_printf_arginfo_##A(void* a, size_t b, void* c, void* d)                       \
+{                                                                                           \
+    return (int)RunFunctionFmt(my_printf_arginfo_fct_##A, "pLpp", a, b, c, d);        \
 }
 SUPER()
 #undef GO
@@ -391,10 +391,10 @@ static void* findprintf_arginfoFct(void* fct)
 }
 // printf_type
 #define GO(A)   \
-static uintptr_t my_printf_type_fct_##A = 0;                   \
-static void my_printf_type_##A(void* a, va_list* b)            \
-{                                                              \
-    RunFunction(my_context, my_printf_type_fct_##A, 2, a, b);  \
+static uintptr_t my_printf_type_fct_##A = 0;                        \
+static void my_printf_type_##A(void* a, va_list* b)                 \
+{                                                                   \
+    RunFunctionFmt(my_printf_type_fct_##A, "pp", a, b);       \
 }
 SUPER()
 #undef GO
@@ -416,8 +416,8 @@ static void* findprintf_typeFct(void* fct)
 #undef SUPER
 
 // some my_XXX declare and defines
-int32_t my___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, char * *), 
-    int argc, char * * ubp_av, void (*init) (void), void (*fini) (void), 
+int32_t my___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, char * *),
+    int argc, char * * ubp_av, void (*init) (void), void (*fini) (void),
     void (*rtld_fini) (void), void (* stack_end)); // implemented in x64run_private.c
 EXPORT void my___libc_init_first(x64emu_t* emu, int argc, char* arg0, char** b)
 {
@@ -437,7 +437,7 @@ void EXPORT my___stack_chk_fail(x64emu_t* emu)
     if(cycle_log) {
         print_cycle_log(LOG_INFO);
     }
-    StopEmu(emu, buff);
+    StopEmu(emu, buff, emu->segs[_CS]==0x23);
 }
 void EXPORT my___gmon_start__(x64emu_t *emu)
 {
@@ -482,6 +482,11 @@ int my_dl_iterate_phdr(x64emu_t *emu, void* F, void *data);
 
 pid_t EXPORT my_fork(x64emu_t* emu)
 {
+    #if 1
+    emu->quit = 1;
+    emu->fork = 3;  // use regular fork...
+    return 0;
+    #else
     // execute atforks prepare functions, in reverse order
     for (int i=my_context->atfork_sz-1; i>=0; --i)
         if(my_context->atforks[i].prepare)
@@ -494,7 +499,7 @@ pid_t EXPORT my_fork(x64emu_t* emu)
     if(v<0) {
         printf_log(LOG_NONE, "BOX64: Warning, fork errored... (%d)\n", v);
         // error...
-    } else if(v>0) {  
+    } else if(v>0) {
         // execute atforks parent functions
         for (int i=0; i<my_context->atfork_sz; --i)
             if(my_context->atforks[i].parent)
@@ -507,6 +512,7 @@ pid_t EXPORT my_fork(x64emu_t* emu)
                 RunFunctionWithEmu(emu, 0, my_context->atforks[i].child, 0);
     }
     return v;
+    #endif
 }
 pid_t EXPORT my___fork(x64emu_t* emu) __attribute__((alias("my_fork")));
 pid_t EXPORT my_vfork(x64emu_t* emu)
@@ -684,32 +690,17 @@ EXPORT int my___fprintf_chk(x64emu_t *emu, void* F, int flag, void* fmt, void* b
     return vfprintf(F, fmt, VARARGS);
 }
 
-#if 0
-EXPORT int my_wprintf(x64emu_t *emu, void* fmt, void* b, va_list V) {
-    #ifndef NOALIGN
-    // need to align on arm
-    myStackAlignW((const char*)fmt, b, emu->scratch);
-    PREPARE_VALIST;
-    void* f = vwprintf;
-    return ((iFpp_t)f)(fmt, VARARGS);
+EXPORT int my_vwprintf(x64emu_t *emu, void* fmt, x64_va_list_t b) {
+    (void)emu;
+    #ifdef CONVERT_VALIST
+    CONVERT_VALIST(b);
     #else
-    // other platform don't need that
-    return vwprintf((const wchar_t*)fmt, V);
-    #endif
-}
-EXPORT int my___wprintf_chk(x64emu_t *emu, int flag, void* fmt, void* b, va_list V) {
-    #ifndef NOALIGN
-    // need to align on arm
-    myStackAlignW((const char*)fmt, b, emu->scratch);
+    myStackAlignWValist(emu, (const char*)fmt, emu->scratch, b);
     PREPARE_VALIST;
-    void* f = vwprintf;
-    return ((iFpp_t)f)(fmt, VARARGS);
-    #else
-    // other platform don't need that
-    return vwprintf((const wchar_t*)fmt, V);
     #endif
+    int r = vwprintf(fmt, VARARGS);
+    return r;
 }
-#endif
 
 EXPORT int my_fwprintf(x64emu_t *emu, void* F, void* fmt, void* b)  {
     myStackAlignW(emu, (const char*)fmt, b, emu->scratch, R_EAX, 2);
@@ -742,19 +733,42 @@ EXPORT int my___vfwprintf_chk(x64emu_t *emu, void* F, int flag, void* fmt, x64_v
     return vfwprintf(F, fmt, VARARGS);
 }
 
-#if 0
-EXPORT int my_vwprintf(x64emu_t *emu, void* fmt, void* b) {
-    #ifndef NOALIGN
-    myStackAlignW((const char*)fmt, b, emu->scratch);
+EXPORT int my_dprintf(x64emu_t *emu, int d, void* fmt, void* b) {
+    myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 2);
     PREPARE_VALIST;
-    void* f = vwprintf;
-    return ((iFpp_t)f)(fmt, VARARGS);
+    return vdprintf(d, fmt, VARARGS);
+}
+
+EXPORT int my___dprintf_chk(x64emu_t *emu, int d, int flag, void* fmt, void* b)  {
+    (void)flag;
+    myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 3);
+    PREPARE_VALIST;
+    return vdprintf(d, fmt, VARARGS);
+}
+
+
+EXPORT int my_vdprintf(x64emu_t *emu, int d, void* fmt, x64_va_list_t b) {
+    #ifdef CONVERT_VALIST
+    CONVERT_VALIST(b);
     #else
-    void* f = vwprintf;
-    return ((iFpp_t)f)(fmt, b);
+    myStackAlignValist(emu, (const char*)fmt, emu->scratch, b);
+    PREPARE_VALIST;
     #endif
+    return vdprintf(d, fmt, VARARGS);
 }
 
+EXPORT int my___vdprintf_chk(x64emu_t *emu, int d, int flag, void* fmt, x64_va_list_t b)  {
+    (void)flag;
+    #ifdef CONVERT_VALIST
+    CONVERT_VALIST(b);
+    #else
+    myStackAlignValist(emu, (const char*)fmt, emu->scratch, b);
+    PREPARE_VALIST;
+    #endif
+    return vdprintf(d, fmt, VARARGS);
+}
+
+#if 0
 EXPORT void *my_div(void *result, int numerator, int denominator) {
     *(div_t *)result = div(numerator, denominator);
     return result;
@@ -909,6 +923,14 @@ EXPORT int my___isoc99_sscanf(x64emu_t* emu, void* stream, void* fmt, uint64_t*
   return vsscanf(stream, fmt, VARARGS);
 }
 
+EXPORT int my___isoc99_swscanf(x64emu_t* emu, void* stream, void* fmt, uint64_t* b)
+{
+  myStackAlignScanf(emu, (const char*)fmt, b, emu->scratch, 2);
+  PREPARE_VALIST;
+
+  return vswscanf(stream, fmt, VARARGS);
+}
+
 EXPORT int my_vsnprintf(x64emu_t* emu, void* buff, size_t s, void * fmt, x64_va_list_t b) {
     (void)emu;
     #ifdef CONVERT_VALIST
@@ -1649,7 +1671,7 @@ EXPORT int32_t my___open(x64emu_t* emu, void* pathname, int32_t flags, uint32_t
 //            unprotectDB((uintptr_t)p, count-ret, 1);
 //            int l;
 //            do {
-//                l = read(fd, p, count-ret); 
+//                l = read(fd, p, count-ret);
 //                if(l>0) {
 //                    p+=l; ret+=l;
 //                }
@@ -1873,11 +1895,11 @@ EXPORT int32_t my_execv(x64emu_t* emu, const char* path, char* const argv[])
         int n=skip_first;
         while(argv[n]) ++n;
         int toadd = script?2:1;
-        const char** newargv = (const char**)box_calloc(n+toadd+1, sizeof(char*));
+        const char** newargv = (const char**)box_calloc(n+toadd+2, sizeof(char*));
         newargv[0] = x86?emu->context->box86path:emu->context->box64path;
         if(script) newargv[1] = emu->context->bashpath; // script needs to be launched with bash
         memcpy(newargv+toadd, argv+skip_first, sizeof(char*)*(n+toadd));
-        if(self) 
+        if(self)
             newargv[1] = emu->context->fullpath;
         else {
             // TODO check if envp is not environ and add the value on a copy
@@ -2053,7 +2075,7 @@ EXPORT int32_t my_execvp(x64emu_t* emu, const char* path, char* const argv[])
         // uname -m is redirected to box64 -m
         path = my_context->box64path;
         char *argv2[3] = { my_context->box64path, argv[1], NULL };
-        
+
         return execvp(path, argv2);
     }
 
@@ -2067,7 +2089,7 @@ EXPORT int32_t my_execl(x64emu_t* emu, const char* path)
     int x64 = FileIsX64ELF(path);
     int x86 = my_context->box86path?FileIsX86ELF(path):0;
     int script = (my_context->bashpath && FileIsShell(path))?1:0;
-    printf_log(LOG_DEBUG, "execl(\"%s\", ...), IsX86=%d, self=%d\n", path, x64, self);
+    printf_log(LOG_DEBUG, "execle(\"%s\", ...), IsX86=%d, self=%d\n", path, x64, self);
     // count argv...
     int i=0;
     while(getVargN(emu, i+1)) ++i;
@@ -2080,12 +2102,42 @@ EXPORT int32_t my_execl(x64emu_t* emu, const char* path)
     for (int k=0; k<i; ++k)
         newargv[j++] = getVargN(emu, k+1);
     if(self) newargv[1] = emu->context->fullpath;
-    printf_log(LOG_DEBUG, " => execl(\"%s\", %p [\"%s\", \"%s\"...:%d])\n", newargv[0], newargv, newargv[1], i?newargv[2]:"", i);
+    printf_log(LOG_DEBUG, " => execle(\"%s\", %p [\"%s\", \"%s\"...:%d])\n", newargv[0], newargv, newargv[1], i?newargv[2]:"", i);
     int ret = execv(newargv[0], newargv);
     box_free(newargv);
     return ret;
 }
 
+EXPORT int32_t my_execle(x64emu_t* emu, const char* path)
+{
+    int self = isProcSelf(path, "exe");
+    int x64 = FileIsX64ELF(path);
+    int x86 = my_context->box86path?FileIsX86ELF(path):0;
+    int script = (my_context->bashpath && FileIsShell(path))?1:0;
+    printf_log(LOG_DEBUG, "execl(\"%s\", ...), IsX86=%d, self=%d\n", path, x64, self);
+    // hack to update the environ var if needed
+    // count argv...
+    int i=0;
+    while(getVargN(emu, i+1)) ++i;
+    int toadd = script?2:((x64||self)?1:0);
+    char** newargv = (char**)box_calloc(i+toadd+1, sizeof(char*));
+    char** envp = (char**)getVargN(emu, i+2);
+    if(envp == my_context->envv && environ) {
+        envp = environ;
+    }
+    int j=0;
+    if ((x64 || x86 || script || self))
+        newargv[j++] = x86?emu->context->box86path:emu->context->box64path;
+    if(script) newargv[j++] = emu->context->bashpath;
+    for (int k=0; k<i; ++k)
+        newargv[j++] = getVargN(emu, k+1);
+    if(self) newargv[1] = emu->context->fullpath;
+    printf_log(LOG_DEBUG, " => execle(\"%s\", %p [\"%s\", \"%s\"...:%d], %p)\n", newargv[0], newargv, newargv[1], i?newargv[2]:"", i, envp);
+    int ret = execve(newargv[0], newargv, envp);
+    box_free(newargv);
+    return ret;
+}
+
 EXPORT int32_t my_execlp(x64emu_t* emu, const char* path)
 {
     // need to use BOX64_PATH / PATH here...
@@ -2124,7 +2176,7 @@ EXPORT int32_t my_execlp(x64emu_t* emu, const char* path)
     return ret;
 }
 
-EXPORT int32_t my_posix_spawn(x64emu_t* emu, pid_t* pid, const char* fullpath, 
+EXPORT int32_t my_posix_spawn(x64emu_t* emu, pid_t* pid, const char* fullpath,
     const posix_spawn_file_actions_t *actions, const posix_spawnattr_t* attrp,  char* const argv[], char* const envp[])
 {
     int self = isProcSelf(fullpath, "exe");
@@ -2157,13 +2209,13 @@ EXPORT int32_t my_posix_spawn(x64emu_t* emu, pid_t* pid, const char* fullpath,
         ret = posix_spawn(pid, newargv[0], actions, attrp, (char* const*)newargv, envp);
         printf_log(/*LOG_DEBUG*/LOG_INFO, "posix_spawn returned %d\n", ret);
         //box_free(newargv);
-    } else 
+    } else
         ret = posix_spawn(pid, fullpath, actions, attrp, argv, envp);
     return ret;
 }
 
 // execvp should use PATH to search for the program first
-EXPORT int32_t my_posix_spawnp(x64emu_t* emu, pid_t* pid, const char* path, 
+EXPORT int32_t my_posix_spawnp(x64emu_t* emu, pid_t* pid, const char* path,
     const posix_spawn_file_actions_t *actions, const posix_spawnattr_t* attrp,  char* const argv[], char* const envp[])
 {
     // need to use BOX64_PATH / PATH here...
@@ -2232,7 +2284,7 @@ EXPORT int32_t my___register_atfork(x64emu_t *emu, void* prepare, void* parent,
 EXPORT uint64_t my___umoddi3(uint64_t a, uint64_t b)
 {
     return a%b;
-}  
+}
 EXPORT uint64_t my___udivdi3(uint64_t a, uint64_t b)
 {
     return a/b;
@@ -2297,8 +2349,8 @@ EXPORT int32_t my_fcntl(x64emu_t* emu, int32_t a, int32_t b, void* c)
     int ret = fcntl(a, b, c);
     if(b==F_GETFL && ret!=-1)
         ret = of_unconvert(ret);
-    
-    return ret;    
+
+    return ret;
 }
 EXPORT int32_t my___fcntl(x64emu_t* emu, int32_t a, int32_t b, void* c) __attribute__((alias("my_fcntl")));
 
@@ -2371,10 +2423,10 @@ void InitCpuModel()
     my___cpu_model.__cpu_vendor = VENDOR_INTEL;
     my___cpu_model.__cpu_type = INTEL_PENTIUM_M;
     my___cpu_model.__cpu_subtype = 0; // N/A
-    my___cpu_model.__cpu_features[0] = (1<<FEATURE_CMOV) 
-                                     | (1<<FEATURE_MMX) 
-                                     | (1<<FEATURE_SSE) 
-                                     | (1<<FEATURE_SSE2) 
+    my___cpu_model.__cpu_features[0] = (1<<FEATURE_CMOV)
+                                     | (1<<FEATURE_MMX)
+                                     | (1<<FEATURE_SSE)
+                                     | (1<<FEATURE_SSE2)
                                      | (1<<FEATURE_SSE3)
                                      | (1<<FEATURE_SSSE3)
                                      | (1<<FEATURE_MOVBE)
@@ -2393,12 +2445,6 @@ void ctSetup()
     my___ctype_tolower = *(__ctype_tolower_loc());
 }
 
-EXPORT void* my___libc_stack_end;
-void stSetup(box64context_t* context)
-{
-    my___libc_stack_end = context->stack;   // is this the end, or should I add stasz?
-}
-
 EXPORT void my___register_frame_info(void* a, void* b)
 {
     // nothing
@@ -2514,7 +2560,7 @@ EXPORT int my_readlinkat(x64emu_t* emu, int fd, void* path, void* buf, size_t bu
 EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, int64_t offset)
 {
     (void)emu;
-    if(prot&PROT_WRITE) 
+    if(prot&PROT_WRITE)
         prot|=PROT_READ;    // PROT_READ is implicit with PROT_WRITE on i386
     if(box64_log<LOG_DEBUG) {dynarec_log(LOG_DEBUG, "mmap64(%p, %lu, 0x%x, 0x%x, %d, %ld) => ", addr, length, prot, flags, fd, offset);}
     #ifndef NOALIGN
@@ -2530,7 +2576,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
     #endif
     void* ret = mmap64(addr, length, prot, flags, fd, offset);
     #ifndef NOALIGN
-    if((ret!=(void*)-1) && (flags&0x40) && 
+    if((ret!=(void*)-1) && (flags&0x40) &&
       (((uintptr_t)ret>0xffffffffLL) || (box64_wine && ((uintptr_t)ret&0xffff)))) {
         printf_log(LOG_DEBUG, "Warning, mmap on 32bits didn't worked, ask %p, got %p ", addr, ret);
         munmap(ret, length);
@@ -2581,7 +2627,7 @@ EXPORT void* my_mremap(x64emu_t* emu, void* old_addr, size_t old_size, size_t ne
     uint32_t prot = getProtection((uintptr_t)old_addr)&~PROT_CUSTOM;
     if(ret==old_addr) {
         if(old_size && old_size<new_size) {
-            setProtection((uintptr_t)ret+old_size, new_size-old_size, prot);
+            setProtection_mmap((uintptr_t)ret+old_size, new_size-old_size, prot);
             #ifdef DYNAREC
             if(box64_dynarec)
                 addDBFromAddressRange((uintptr_t)ret+old_size, new_size-old_size);
@@ -2590,10 +2636,10 @@ EXPORT void* my_mremap(x64emu_t* emu, void* old_addr, size_t old_size, size_t ne
             freeProtection((uintptr_t)ret+new_size, old_size-new_size);
             #ifdef DYNAREC
             if(box64_dynarec)
-                cleanDBFromAddressRange((uintptr_t)ret+new_size, new_size-old_size, 1);
+                cleanDBFromAddressRange((uintptr_t)ret+new_size, old_size-new_size, 1);
             #endif
         } else if(!old_size) {
-            setProtection((uintptr_t)ret, new_size, prot);
+            setProtection_mmap((uintptr_t)ret, new_size, prot);
             #ifdef DYNAREC
             if(box64_dynarec)
                 addDBFromAddressRange((uintptr_t)ret, new_size);
@@ -2640,19 +2686,26 @@ EXPORT int my_mprotect(x64emu_t* emu, void *addr, unsigned long len, int prot)
 {
     (void)emu;
     dynarec_log(LOG_DEBUG, "mprotect(%p, %lu, 0x%x)\n", addr, len, prot);
-    if(prot&PROT_WRITE) 
+    if(prot&PROT_WRITE)
         prot|=PROT_READ;    // PROT_READ is implicit with PROT_WRITE on x86_64
     int ret = mprotect(addr, len, prot);
     #ifdef DYNAREC
-    if(box64_dynarec && !ret) {
+    if(box64_dynarec && !ret && len) {
         if(prot& PROT_EXEC)
             addDBFromAddressRange((uintptr_t)addr, len);
         else
-            cleanDBFromAddressRange((uintptr_t)addr, len, 0);
+            cleanDBFromAddressRange((uintptr_t)addr, len, 1);
     }
     #endif
-    if(!ret)
-        updateProtection((uintptr_t)addr, len, prot);
+    if(!ret && len) {
+        if(prot)
+            updateProtection((uintptr_t)addr, len, prot);
+        else {
+            // avoid allocating detailled protection for a no prot 0
+            freeProtection((uintptr_t)addr, len);
+            setProtection_mmap((uintptr_t)addr, len, prot);
+        }
+    }
     return ret;
 }
 
@@ -2696,7 +2749,13 @@ EXPORT int my_getopt_long_only(int argc, char* const argv[], const char* optstri
     return ret;
 }
 
-#if 0
+typedef struct {
+   void  *read;
+   void *write;
+   void  *seek;
+   void *close;
+} my_cookie_io_functions_t;
+
 typedef struct my_cookie_s {
     uintptr_t r, w, s, c;
     void* cookie;
@@ -2705,39 +2764,41 @@ typedef struct my_cookie_s {
 static ssize_t my_cookie_read(void *p, char *buf, size_t size)
 {
     my_cookie_t* cookie = (my_cookie_t*)p;
-    return (ssize_t)RunFunction(my_context, cookie->r, 3, cookie->cookie, buf, size);
+    return (ssize_t)RunFunctionFmt(cookie->r, "ppL", cookie->cookie, buf, size)       ;
 }
 static ssize_t my_cookie_write(void *p, const char *buf, size_t size)
 {
     my_cookie_t* cookie = (my_cookie_t*)p;
-    return (ssize_t)RunFunction(my_context, cookie->w, 3, cookie->cookie, buf, size);
+    return (ssize_t)RunFunctionFmt(cookie->w, "ppL", cookie->cookie, buf, size)       ;
 }
 static int my_cookie_seek(void *p, off64_t *offset, int whence)
 {
     my_cookie_t* cookie = (my_cookie_t*)p;
-    return RunFunction(my_context, cookie->s, 3, cookie->cookie, offset, whence);
+    return RunFunctionFmt(cookie->s, "ppi", cookie->cookie, offset, whence)       ;
 }
 static int my_cookie_close(void *p)
 {
     my_cookie_t* cookie = (my_cookie_t*)p;
     int ret = 0;
     if(cookie->c)
-        ret = RunFunction(my_context, cookie->c, 1, cookie->cookie);
+        ret = RunFunctionFmt(cookie->c, "p", cookie->cookie)      ;
     box_free(cookie);
     return ret;
 }
-EXPORT void* my_fopencookie(x64emu_t* emu, void* cookie, void* mode, void* read, void* write, void* seek, void* close)
+EXPORT void* my_fopencookie(x64emu_t* emu, void* cookie, void* mode, my_cookie_io_functions_t *s)
 {
-    cookie_io_functions_t io_funcs = {read?my_cookie_read:NULL, write?my_cookie_write:NULL, seek?my_cookie_seek:NULL, my_cookie_close};
+    cookie_io_functions_t io_funcs = {s->read?my_cookie_read:NULL, s->write?my_cookie_write:NULL, s->seek?my_cookie_seek:NULL, my_cookie_close};
     my_cookie_t *cb = (my_cookie_t*)box_calloc(1, sizeof(my_cookie_t));
-    cb->r = (uintptr_t)read;
-    cb->w = (uintptr_t)write;
-    cb->s = (uintptr_t)seek;
-    cb->c = (uintptr_t)close;
+    cb->r = (uintptr_t)s->read;
+    cb->w = (uintptr_t)s->write;
+    cb->s = (uintptr_t)s->seek;
+    cb->c = (uintptr_t)s->close;
     cb->cookie = cookie;
     return fopencookie(cb, mode, io_funcs);
 }
 
+#if 0
+
 EXPORT long my_prlimit64(void* pid, uint32_t res, void* new_rlim, void* old_rlim)
 {
     return syscall(__NR_prlimit64, pid, res, new_rlim, old_rlim);
@@ -2933,7 +2994,7 @@ EXPORT int my_backtrace(x64emu_t* emu, void** buffer, int size)
     buffer[0] = (void*)addr;
     while (++idx < size) {
         uintptr_t ret_addr = get_parent_registers(unwind, FindElfAddress(my_context, addr), addr, &success);
-        if (ret_addr == (uintptr_t)GetExit()) {
+        if (ret_addr == my_context->exit_bridge) {
             // TODO: do something to be able to get the function name
             buffer[idx] = (void*)ret_addr;
             success = 2;
@@ -2963,7 +3024,7 @@ EXPORT int my_backtrace_ip(x64emu_t* emu, void** buffer, int size)
     buffer[0] = (void*)addr;
     while ((++idx < size) && success) {
         uintptr_t ret_addr = get_parent_registers(unwind, FindElfAddress(my_context, addr), addr, &success);
-        if (ret_addr == (uintptr_t)GetExit()) {
+        if (ret_addr == my_context->exit_bridge) {
             // TODO: do something to be able to get the function name
             buffer[idx] = (void*)ret_addr;
             success = 2;
@@ -2994,7 +3055,7 @@ EXPORT int my_backtrace_ip(x64emu_t* emu, void** buffer, int size)
                         unwind->regs[7] += 8;
                         buffer[idx] = (void*)ret_addr;
                         success = 2;
-                    } else 
+                    } else
                         break;
                 }
             } else
@@ -3041,7 +3102,7 @@ EXPORT void my_backtrace_symbols_fd(x64emu_t* emu, uintptr_t* buffer, int size,
         if(!sz) sz=0x100;   // arbitrary value...
         if(symbname && buffer[i]>=start && (buffer[i]<(start+sz) || !sz))
             snprintf(s, 200, "%s+%ld [%p]\n", symbname, buffer[i] - start, (void*)buffer[i]);
-        else 
+        else
             snprintf(s, 200, "??? [%p]\n", (void*)buffer[i]);
         int dummy = write(fd, s, strlen(s));
         (void)dummy;
@@ -3138,8 +3199,8 @@ EXPORT int my_clone(x64emu_t* emu, void* fn, void* stack, int flags, void* args,
     void* mystack = NULL;
     clone_arg_t* arg = (clone_arg_t*)box_calloc(1, sizeof(clone_arg_t));
     x64emu_t * newemu = NewX64Emu(emu->context, R_RIP, (uintptr_t)stack, 0, 0);
-    SetupX64Emu(newemu);
-    CloneEmu(newemu, emu);
+    SetupX64Emu(newemu, emu);
+    //CloneEmu(newemu, emu);
     if(my_context->stack_clone_used) {
         printf_log(LOG_DEBUG, " no free stack_clone ");
         mystack = box_malloc(1024*1024);  // stack for own process... memory leak, but no practical way to remove it
@@ -3197,6 +3258,7 @@ EXPORT int my_register_printf_type(x64emu_t* emu, void* f)
     return my->register_printf_type(findprintf_typeFct(f));
 }
 
+extern int box64_quit;
 EXPORT void my_exit(x64emu_t* emu, int code)
 {
     if(emu->quitonexit) {
@@ -3206,6 +3268,7 @@ EXPORT void my_exit(x64emu_t* emu, int code)
         return;
     }
     emu->quit = 1;
+    box64_quit = 1;
     exit(code);
 }
 
@@ -3242,7 +3305,6 @@ EXPORT char my___libc_single_threaded = 0;
     box64->libclib = lib;   \
     /*InitCpuModel();*/         \
     ctSetup();              \
-    stSetup(box64);         \
     obstackSetup();         \
     my_environ = my__environ = my___environ = box64->envv;                      \
     my___progname_full = my_program_invocation_name = box64->argv[0];           \