about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-12-19 13:57:33 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-12-19 13:57:33 +0100
commita8000cb629eae569563b92e1ab7c5929bda3bb5f (patch)
treeabd716f5cc524790bee72b27a1a23c7ce3fd124b /src
parent17f2371804b31d3829f029f27dad53eba2081a38 (diff)
downloadbox64-a8000cb629eae569563b92e1ab7c5929bda3bb5f.tar.gz
box64-a8000cb629eae569563b92e1ab7c5929bda3bb5f.zip
[BOX32] More fixes on libc wrapping
Diffstat (limited to 'src')
-rwxr-xr-xsrc/libtools/myalign32.c10
-rw-r--r--src/libtools/signal32.c21
-rw-r--r--src/wrapped32/generated/functions_list.txt18
-rw-r--r--src/wrapped32/generated/wrappedlibctypes32.h13
-rw-r--r--src/wrapped32/generated/wrapper32.c10
-rw-r--r--src/wrapped32/generated/wrapper32.h5
-rwxr-xr-xsrc/wrapped32/wrappedlibc.c202
-rwxr-xr-xsrc/wrapped32/wrappedlibc_private.h28
8 files changed, 185 insertions, 122 deletions
diff --git a/src/libtools/myalign32.c b/src/libtools/myalign32.c
index cd703549..0ce60bfc 100755
--- a/src/libtools/myalign32.c
+++ b/src/libtools/myalign32.c
@@ -1486,7 +1486,6 @@ void AlignMsgHdr_32(void* dest, void* dest_iov, void* dest_cmsg, void* source, i
     struct msghdr* d = dest;
     struct i386_msghdr* s = source;
     struct i386_iovec* s_iov = from_ptrv(s->msg_iov);
-
     d->msg_name = from_ptrv(s->msg_name);
     d->msg_namelen = s->msg_namelen;
     d->msg_iov = iov;
@@ -1495,11 +1494,11 @@ void AlignMsgHdr_32(void* dest, void* dest_iov, void* dest_cmsg, void* source, i
         AlignIOV_32(d->msg_iov+i, s_iov+i);
     }
     d->msg_iovlen = s->msg_iovlen;
-    d->msg_controllen = s->msg_controllen+(convert_control?0:4);
+    d->msg_controllen = s->msg_controllen;
     if(convert_control) {
         if(s->msg_control) {
             d->msg_control = dest_cmsg;
-            struct i386_cmsghdr* cmsg = from_ptrv(s->msg_control);
+            struct i386_cmsghdr* cmsg = (s->msg_controllen)?from_ptrv(s->msg_control):NULL;
             struct cmsghdr* dcmsg = dest_cmsg;
             while(cmsg) {
                 dcmsg->cmsg_len = from_ulong(cmsg->cmsg_len);
@@ -1515,11 +1514,13 @@ void AlignMsgHdr_32(void* dest, void* dest_iov, void* dest_cmsg, void* source, i
                 uintptr_t next_diff = (uintptr_t)next-((uintptr_t)dcmsg+dcmsg->cmsg_len);
                 if(cmsg)
                     d->msg_controllen+=next_diff;
+                dcmsg = next;
                 
             }
         } else 
             d->msg_control = NULL;
     } else {
+        if(d->msg_controllen) d->msg_controllen+=4;
         d->msg_control = (s->msg_control)?dest_cmsg:NULL;
         if(d->msg_control) memset(d->msg_control, 0, d->msg_controllen);
     }
@@ -1532,7 +1533,6 @@ void UnalignMsgHdr_32(void* dest, void* source)
     struct i386_msghdr* d = dest;
     struct iovec* s_iov = s->msg_iov;
     struct i386_iovec* d_iov = from_ptrv(d->msg_iov);
-
     d->msg_name = to_ptrv(s->msg_name);
     d->msg_namelen = s->msg_namelen;
     // TODO: check if iovlen is too big
@@ -1543,7 +1543,7 @@ void UnalignMsgHdr_32(void* dest, void* source)
     d->msg_controllen = s->msg_controllen;
     if(s->msg_control) {
         struct i386_cmsghdr* dcmsg = from_ptrv(d->msg_control);
-        struct cmsghdr* scmsg = s->msg_control;
+        struct cmsghdr* scmsg = (s->msg_controllen)?s->msg_control:NULL;
         while(scmsg) {
             dcmsg->cmsg_len = to_ulong(scmsg->cmsg_len);
             dcmsg->cmsg_level = scmsg->cmsg_level;
diff --git a/src/libtools/signal32.c b/src/libtools/signal32.c
index 3742d0c7..1bb13338 100644
--- a/src/libtools/signal32.c
+++ b/src/libtools/signal32.c
@@ -447,6 +447,23 @@ uint32_t RunFunctionHandler32(int* exit, int dynarec, i386_ucontext_t* sigcontex
 
     return ret;
 }
+void convert_siginfo_to_32(void* d, void* s, int sig)
+{
+    if(!s || !d) return;
+    my_siginfo32_t* dst = d;
+    siginfo_t* src = s;
+
+    memcpy(dst, src, sizeof(my_siginfo32_t));
+    if(sig==SIGILL || sig==SIGFPE || sig==SIGSEGV || sig==SIGBUS)
+        dst->_sifields._sigfault.__si_addr = to_ptrv(src->si_addr);
+    if(sig==SIGCHLD) {
+        dst->_sifields._sigchld.__si_pid = src->si_pid;
+        dst->_sifields._sigchld.__si_uid = src->si_uid;
+        dst->_sifields._sigchld.__si_status = src->si_status;
+        dst->_sifields._sigchld.__si_stime = src->si_stime;
+        dst->_sifields._sigchld.__si_utime = src->si_utime;
+    }
+}
 int write_opcode(uintptr_t rip, uintptr_t native_ip, int is32bits);
 #define is_memprot_locked (1<<1)
 #define is_dyndump_locked (1<<8)
@@ -520,9 +537,7 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
     void* xstate = (void*)frame;
     frame -= sizeof(my_siginfo32_t);
     my_siginfo32_t* info2 = (my_siginfo32_t*)frame;
-    memcpy(info2, info, sizeof(my_siginfo32_t));
-    if(sig==SIGILL || sig==SIGFPE || sig==SIGSEGV || sig==SIGBUS)
-        info2->_sifields._sigfault.__si_addr = to_ptrv(info->si_addr);
+    convert_siginfo_to_32(info2, info, sig);
     // try to fill some sigcontext....
     frame -= sizeof(i386_ucontext_t);
     i386_ucontext_t   *sigcontext = (i386_ucontext_t*)frame;
diff --git a/src/wrapped32/generated/functions_list.txt b/src/wrapped32/generated/functions_list.txt
index 856e0f96..3f40c384 100644
--- a/src/wrapped32/generated/functions_list.txt
+++ b/src/wrapped32/generated/functions_list.txt
@@ -136,10 +136,10 @@
 #() vFbuuipWCCp_ -> vFB
 #() vFbWWpWpWpWp_ -> vFB
 #() LEbiiiiiiiiilt_ -> LEB
-#() LEriiiiiiiiilt_ -> LEB
 #() pEriiiiiiiiilt_ -> pEB
 #() vEEv -> vEEv
 #() vFEv -> vFEv
+#() vFEi -> vFEi
 #() vEEp -> vEEp
 #() vFEp -> vFEp
 #() vFEX -> vFEX
@@ -390,6 +390,7 @@
 #() vFbll_rllll_ -> vFBB
 #() iFXbiiuuLip_ -> iFXB
 #() iFpruuipWCCp_ -> iFpB
+#() lEEriiiiiiiiilt_ -> lEEB
 #() pEriiiiiiiiilt_p -> pEBp
 #() iEiBLLLLLLLLLLLLLLLLLL_ -> iEiB
 #() vEEip -> vEEip
@@ -918,7 +919,6 @@
 #() iFippp -> iFippp
 #() iEipON -> iEipON
 #() iFuiup -> iFuiup
-#() iEuupi -> iEuupi
 #() iFuppp -> iFuppp
 #() iFpiii -> iFpiii
 #() iFpiiL -> iFpiiL
@@ -1199,6 +1199,7 @@
 #() iEEipii -> iEEipii
 #() iEEipuu -> iEEipuu
 #() iEEippL -> iEEippL
+#() iEEuupi -> iEEuupi
 #() iEEpipp -> iEEpipp
 #() iFEpipp -> iFEpipp
 #() iEEpipV -> iEEpipV
@@ -1929,6 +1930,8 @@ wrappedlibasound:
   - snd_pcm_mmap_begin
 wrappedlibc:
 - vEv:
+- vFi:
+  - exit
 - vEp:
   - freeaddrinfo
   - regfree
@@ -1939,8 +1942,6 @@ wrappedlibc:
   - __close_nocancel
 - iEL:
 - iEp:
-  - posix_spawn_file_actions_destroy
-  - posix_spawn_file_actions_init
   - shmdt
   - sysinfo
 - iEO:
@@ -1990,6 +1991,7 @@ wrappedlibc:
   - getifaddrs
 - pErl_:
   - ctime
+- lEriiiiiiiiilt_:
 - pEriiiiiiiiilt_:
   - asctime
 - vEip:
@@ -2008,11 +2010,9 @@ wrappedlibc:
   - setrlimit
 - iEpi:
   - backtrace
-  - posix_spawn_file_actions_addclose
 - iEpL:
 - iEpp:
   - alphasort64
-  - execvp
   - statvfs
   - statvfs64
   - utimes
@@ -2054,13 +2054,11 @@ wrappedlibc:
 - iEipp:
 - iEipV:
 - iEpii:
-  - posix_spawn_file_actions_adddup2
 - iEpLi:
 - iEppi:
   - regcomp
 - iEppp:
   - __isoc23_vsscanf
-  - execvpe
   - vswscanf
 - iEppV:
   - __isoc23_sscanf
@@ -2116,6 +2114,8 @@ wrappedlibc:
   - utimensat
 - iEippL:
   - readlinkat
+- iEuupi:
+  - waitid
 - iEpipp:
 - iEpipV:
 - iEpuiL:
@@ -2140,7 +2140,6 @@ wrappedlibc:
 - iEpiipV:
 - iEpiLpp:
 - iEpipOi:
-  - posix_spawn_file_actions_addopen
 - iEppupi:
   - regexec
 - iEpppLp:
@@ -2157,7 +2156,6 @@ wrappedlibc:
 - iFpppupp:
   - gethostbyname_r
 - iEpppppp:
-  - posix_spawn
 - lEipLpLL:
   - process_vm_readv
   - process_vm_writev
diff --git a/src/wrapped32/generated/wrappedlibctypes32.h b/src/wrapped32/generated/wrappedlibctypes32.h
index 45a2a970..ef6b1621 100644
--- a/src/wrapped32/generated/wrappedlibctypes32.h
+++ b/src/wrapped32/generated/wrappedlibctypes32.h
@@ -12,6 +12,7 @@
 #endif
 
 typedef void (*vEv_t)(void);
+typedef void (*vFi_t)(int32_t);
 typedef void (*vEp_t)(void*);
 typedef void (*vFp_t)(void*);
 typedef int32_t (*iEv_t)(void);
@@ -38,6 +39,7 @@ typedef void* (*pES_t)(void*);
 typedef char* (*tEp_t)(void*);
 typedef int32_t (*iEbp__t)(struct_p_t*);
 typedef void* (*pErl__t)(struct_l_t*);
+typedef intptr_t (*lEriiiiiiiiilt__t)(struct_iiiiiiiiilt_t*);
 typedef void* (*pEriiiiiiiiilt__t)(struct_iiiiiiiiilt_t*);
 typedef void (*vEip_t)(int32_t, void*);
 typedef void (*vEpi_t)(void*, int32_t);
@@ -103,6 +105,7 @@ typedef int32_t (*iEipii_t)(int32_t, void*, int32_t, int32_t);
 typedef int32_t (*iEipuu_t)(int32_t, void*, uint32_t, uint32_t);
 typedef int32_t (*iEippi_t)(int32_t, void*, void*, int32_t);
 typedef int32_t (*iEippL_t)(int32_t, void*, void*, uintptr_t);
+typedef int32_t (*iEuupi_t)(uint32_t, uint32_t, void*, int32_t);
 typedef int32_t (*iEpipp_t)(void*, int32_t, void*, void*);
 typedef int32_t (*iEpipV_t)(void*, int32_t, void*, ...);
 typedef int32_t (*iEpuiL_t)(void*, uint32_t, int32_t, uintptr_t);
@@ -140,12 +143,11 @@ typedef int32_t (*iEpLiLppp_t)(void*, uintptr_t, int32_t, uintptr_t, void*, void
 typedef int32_t (*iFpuippupp_t)(void*, uint32_t, int32_t, void*, void*, uint32_t, void*, void*);
 
 #define SUPER() ADDED_FUNCTIONS() \
+	GO(exit, vFi_t) \
 	GO(freeaddrinfo, vEp_t) \
 	GO(regfree, vEp_t) \
 	GO(_ZGTtdlPv, vFp_t) \
 	GO(__close_nocancel, iEi_t) \
-	GO(posix_spawn_file_actions_destroy, iEp_t) \
-	GO(posix_spawn_file_actions_init, iEp_t) \
 	GO(shmdt, iEp_t) \
 	GO(sysinfo, iEp_t) \
 	GO(getwc, uES_t) \
@@ -184,9 +186,7 @@ typedef int32_t (*iFpuippupp_t)(void*, uint32_t, int32_t, void*, void*, uint32_t
 	GO(getrlimit, iEup_t) \
 	GO(setrlimit, iEup_t) \
 	GO(backtrace, iEpi_t) \
-	GO(posix_spawn_file_actions_addclose, iEpi_t) \
 	GO(alphasort64, iEpp_t) \
-	GO(execvp, iEpp_t) \
 	GO(statvfs, iEpp_t) \
 	GO(statvfs64, iEpp_t) \
 	GO(utimes, iEpp_t) \
@@ -205,10 +205,8 @@ typedef int32_t (*iFpuippupp_t)(void*, uint32_t, int32_t, void*, void*, uint32_t
 	GO(vsyslog, vEipp_t) \
 	GO(syslog, vEipV_t) \
 	GO(_ITM_addUserCommitAction, vEpup_t) \
-	GO(posix_spawn_file_actions_adddup2, iEpii_t) \
 	GO(regcomp, iEppi_t) \
 	GO(__isoc23_vsscanf, iEppp_t) \
-	GO(execvpe, iEppp_t) \
 	GO(vswscanf, iEppp_t) \
 	GO(__isoc23_sscanf, iEppV_t) \
 	GO(swscanf, iEppV_t) \
@@ -236,19 +234,18 @@ typedef int32_t (*iFpuippupp_t)(void*, uint32_t, int32_t, void*, void*, uint32_t
 	GO(sendmmsg, iEipuu_t) \
 	GO(utimensat, iEippi_t) \
 	GO(readlinkat, iEippL_t) \
+	GO(waitid, iEuupi_t) \
 	GO(getaddrinfo, iEpppp_t) \
 	GO(regerror, uEippu_t) \
 	GO(statx, iEipiup_t) \
 	GO(getopt_long, iEipppp_t) \
 	GO(getgrgid_r, iEuppLp_t) \
 	GO(getpwuid_r, iEuppLp_t) \
-	GO(posix_spawn_file_actions_addopen, iEpipOi_t) \
 	GO(regexec, iEppupi_t) \
 	GO(getgrnam_r, iEpppLp_t) \
 	GO(getpwnam_r, iEpppLp_t) \
 	GO(recvmmsg, iEipuurLL__t) \
 	GO(gethostbyname_r, iFpppupp_t) \
-	GO(posix_spawn, iEpppppp_t) \
 	GO(process_vm_readv, lEipLpLL_t) \
 	GO(process_vm_writev, lEipLpLL_t) \
 	GO(gethostbyaddr_r, iFpuippupp_t)
diff --git a/src/wrapped32/generated/wrapper32.c b/src/wrapped32/generated/wrapper32.c
index 0ef9949f..a6e0b8c2 100644
--- a/src/wrapped32/generated/wrapper32.c
+++ b/src/wrapped32/generated/wrapper32.c
@@ -230,10 +230,10 @@ typedef int32_t (*iEBllll__t)(struct_llll_t*);
 typedef void (*vFbuuipWCCp__t)(struct_uuipWCCp_t*);
 typedef void (*vFbWWpWpWpWp__t)(struct_WWpWpWpWp_t*);
 typedef uintptr_t (*LEbiiiiiiiiilt__t)(struct_iiiiiiiiilt_t*);
-typedef uintptr_t (*LEriiiiiiiiilt__t)(struct_iiiiiiiiilt_t*);
 typedef void* (*pEriiiiiiiiilt__t)(struct_iiiiiiiiilt_t*);
 typedef void (*vEEv_t)(x64emu_t*);
 typedef void (*vFEv_t)(x64emu_t*);
+typedef void (*vFEi_t)(x64emu_t*, int32_t);
 typedef void (*vEEp_t)(x64emu_t*, void*);
 typedef void (*vFEp_t)(x64emu_t*, void*);
 typedef void (*vFEX_t)(x64emu_t*, void*);
@@ -484,6 +484,7 @@ typedef void* (*pErppppii_p_t)(struct_ppppii_t*, void*);
 typedef void (*vFbll_rllll__t)(struct_ll_t*, struct_llll_t*);
 typedef int32_t (*iFXbiiuuLip__t)(void*, struct_iiuuLip_t*);
 typedef int32_t (*iFpruuipWCCp__t)(void*, struct_uuipWCCp_t*);
+typedef intptr_t (*lEEriiiiiiiiilt__t)(x64emu_t*, struct_iiiiiiiiilt_t*);
 typedef void* (*pEriiiiiiiiilt_p_t)(struct_iiiiiiiiilt_t*, void*);
 typedef int32_t (*iEiBLLLLLLLLLLLLLLLLLL__t)(int32_t, struct_LLLLLLLLLLLLLLLLLL_t*);
 typedef void (*vEEip_t)(x64emu_t*, int32_t, void*);
@@ -1012,7 +1013,6 @@ typedef int32_t (*iEippL_t)(int32_t, void*, void*, uintptr_t);
 typedef int32_t (*iFippp_t)(int32_t, void*, void*, void*);
 typedef int32_t (*iEipON_t)(int32_t, void*, int32_t, ...);
 typedef int32_t (*iFuiup_t)(uint32_t, int32_t, uint32_t, void*);
-typedef int32_t (*iEuupi_t)(uint32_t, uint32_t, void*, int32_t);
 typedef int32_t (*iFuppp_t)(uint32_t, void*, void*, void*);
 typedef int32_t (*iFpiii_t)(void*, int32_t, int32_t, int32_t);
 typedef int32_t (*iFpiiL_t)(void*, int32_t, int32_t, uintptr_t);
@@ -1293,6 +1293,7 @@ typedef int32_t (*iEEiipV_t)(x64emu_t*, int32_t, int32_t, void*, void*);
 typedef int32_t (*iEEipii_t)(x64emu_t*, int32_t, void*, int32_t, int32_t);
 typedef int32_t (*iEEipuu_t)(x64emu_t*, int32_t, void*, uint32_t, uint32_t);
 typedef int32_t (*iEEippL_t)(x64emu_t*, int32_t, void*, void*, uintptr_t);
+typedef int32_t (*iEEuupi_t)(x64emu_t*, uint32_t, uint32_t, void*, int32_t);
 typedef int32_t (*iEEpipp_t)(x64emu_t*, void*, int32_t, void*, void*);
 typedef int32_t (*iFEpipp_t)(x64emu_t*, void*, int32_t, void*, void*);
 typedef int32_t (*iEEpipV_t)(x64emu_t*, void*, int32_t, void*, void*);
@@ -2034,10 +2035,10 @@ void iEBllll__32(x64emu_t *emu, uintptr_t fcn) { iEBllll__t fn = (iEBllll__t)fcn
 void vFbuuipWCCp__32(x64emu_t *emu, uintptr_t fcn) { vFbuuipWCCp__t fn = (vFbuuipWCCp__t)fcn; struct_uuipWCCp_t arg_4={0}; if (*(ptr_t*)(from_ptr((R_ESP + 4)))) from_struct_uuipWCCp(&arg_4, *(ptr_t*)(from_ptr((R_ESP + 4)))); fn(*(ptr_t*)(from_ptr((R_ESP + 4))) ? &arg_4 : NULL); if (*(ptr_t*)(from_ptr((R_ESP + 4)))) to_struct_uuipWCCp(*(ptr_t*)(from_ptr((R_ESP + 4))), &arg_4); }
 void vFbWWpWpWpWp__32(x64emu_t *emu, uintptr_t fcn) { vFbWWpWpWpWp__t fn = (vFbWWpWpWpWp__t)fcn; struct_WWpWpWpWp_t arg_4={0}; if (*(ptr_t*)(from_ptr((R_ESP + 4)))) from_struct_WWpWpWpWp(&arg_4, *(ptr_t*)(from_ptr((R_ESP + 4)))); fn(*(ptr_t*)(from_ptr((R_ESP + 4))) ? &arg_4 : NULL); if (*(ptr_t*)(from_ptr((R_ESP + 4)))) to_struct_WWpWpWpWp(*(ptr_t*)(from_ptr((R_ESP + 4))), &arg_4); }
 void LEbiiiiiiiiilt__32(x64emu_t *emu, uintptr_t fcn) { LEbiiiiiiiiilt__t fn = (LEbiiiiiiiiilt__t)fcn; errno = emu->libc_err; struct_iiiiiiiiilt_t arg_4={0}; if (*(ptr_t*)(from_ptr((R_ESP + 4)))) from_struct_iiiiiiiiilt(&arg_4, *(ptr_t*)(from_ptr((R_ESP + 4)))); R_EAX = to_ulong(fn(*(ptr_t*)(from_ptr((R_ESP + 4))) ? &arg_4 : NULL)); if (*(ptr_t*)(from_ptr((R_ESP + 4)))) to_struct_iiiiiiiiilt(*(ptr_t*)(from_ptr((R_ESP + 4))), &arg_4); emu->libc_err = errno; }
-void LEriiiiiiiiilt__32(x64emu_t *emu, uintptr_t fcn) { LEriiiiiiiiilt__t fn = (LEriiiiiiiiilt__t)fcn; errno = emu->libc_err; struct_iiiiiiiiilt_t arg_4={0}; if (*(ptr_t*)(from_ptr((R_ESP + 4)))) from_struct_iiiiiiiiilt(&arg_4, *(ptr_t*)(from_ptr((R_ESP + 4)))); R_EAX = to_ulong(fn(*(ptr_t*)(from_ptr((R_ESP + 4))) ? &arg_4 : NULL)); emu->libc_err = errno; }
 void pEriiiiiiiiilt__32(x64emu_t *emu, uintptr_t fcn) { pEriiiiiiiiilt__t fn = (pEriiiiiiiiilt__t)fcn; errno = emu->libc_err; struct_iiiiiiiiilt_t arg_4={0}; if (*(ptr_t*)(from_ptr((R_ESP + 4)))) from_struct_iiiiiiiiilt(&arg_4, *(ptr_t*)(from_ptr((R_ESP + 4)))); R_EAX = to_ptrv(fn(*(ptr_t*)(from_ptr((R_ESP + 4))) ? &arg_4 : NULL)); emu->libc_err = errno; }
 void vEEv_32(x64emu_t *emu, uintptr_t fcn) { vEEv_t fn = (vEEv_t)fcn; errno = emu->libc_err; fn(emu); emu->libc_err = errno; }
 void vFEv_32(x64emu_t *emu, uintptr_t fcn) { vFEv_t fn = (vFEv_t)fcn; fn(emu); }
+void vFEi_32(x64emu_t *emu, uintptr_t fcn) { vFEi_t fn = (vFEi_t)fcn; fn(emu, from_ptri(int32_t, R_ESP + 4)); }
 void vEEp_32(x64emu_t *emu, uintptr_t fcn) { vEEp_t fn = (vEEp_t)fcn; errno = emu->libc_err; fn(emu, from_ptriv(R_ESP + 4)); emu->libc_err = errno; }
 void vFEp_32(x64emu_t *emu, uintptr_t fcn) { vFEp_t fn = (vFEp_t)fcn; fn(emu, from_ptriv(R_ESP + 4)); }
 void vFEX_32(x64emu_t *emu, uintptr_t fcn) { vFEX_t fn = (vFEX_t)fcn; fn(emu, getDisplay(from_ptriv(R_ESP + 4))); }
@@ -2288,6 +2289,7 @@ void pErppppii_p_32(x64emu_t *emu, uintptr_t fcn) { pErppppii_p_t fn = (pErppppi
 void vFbll_rllll__32(x64emu_t *emu, uintptr_t fcn) { vFbll_rllll__t fn = (vFbll_rllll__t)fcn; struct_ll_t arg_4={0}; if (*(ptr_t*)(from_ptr((R_ESP + 4)))) from_struct_ll(&arg_4, *(ptr_t*)(from_ptr((R_ESP + 4)))); struct_llll_t arg_8={0}; if (*(ptr_t*)(from_ptr((R_ESP + 8)))) from_struct_llll(&arg_8, *(ptr_t*)(from_ptr((R_ESP + 8)))); fn(*(ptr_t*)(from_ptr((R_ESP + 4))) ? &arg_4 : NULL, *(ptr_t*)(from_ptr((R_ESP + 8))) ? &arg_8 : NULL); if (*(ptr_t*)(from_ptr((R_ESP + 4)))) to_struct_ll(*(ptr_t*)(from_ptr((R_ESP + 4))), &arg_4); }
 void iFXbiiuuLip__32(x64emu_t *emu, uintptr_t fcn) { iFXbiiuuLip__t fn = (iFXbiiuuLip__t)fcn; struct_iiuuLip_t arg_8={0}; if (*(ptr_t*)(from_ptr((R_ESP + 8)))) from_struct_iiuuLip(&arg_8, *(ptr_t*)(from_ptr((R_ESP + 8)))); R_EAX = fn(getDisplay(from_ptriv(R_ESP + 4)), *(ptr_t*)(from_ptr((R_ESP + 8))) ? &arg_8 : NULL); if (*(ptr_t*)(from_ptr((R_ESP + 8)))) to_struct_iiuuLip(*(ptr_t*)(from_ptr((R_ESP + 8))), &arg_8); }
 void iFpruuipWCCp__32(x64emu_t *emu, uintptr_t fcn) { iFpruuipWCCp__t fn = (iFpruuipWCCp__t)fcn; struct_uuipWCCp_t arg_8={0}; if (*(ptr_t*)(from_ptr((R_ESP + 8)))) from_struct_uuipWCCp(&arg_8, *(ptr_t*)(from_ptr((R_ESP + 8)))); R_EAX = fn(from_ptriv(R_ESP + 4), *(ptr_t*)(from_ptr((R_ESP + 8))) ? &arg_8 : NULL); }
+void lEEriiiiiiiiilt__32(x64emu_t *emu, uintptr_t fcn) { lEEriiiiiiiiilt__t fn = (lEEriiiiiiiiilt__t)fcn; errno = emu->libc_err; struct_iiiiiiiiilt_t arg_4={0}; if (*(ptr_t*)(from_ptr((R_ESP + 4)))) from_struct_iiiiiiiiilt(&arg_4, *(ptr_t*)(from_ptr((R_ESP + 4)))); R_EAX = to_long(fn(emu, *(ptr_t*)(from_ptr((R_ESP + 4))) ? &arg_4 : NULL)); emu->libc_err = errno; }
 void pEriiiiiiiiilt_p_32(x64emu_t *emu, uintptr_t fcn) { pEriiiiiiiiilt_p_t fn = (pEriiiiiiiiilt_p_t)fcn; errno = emu->libc_err; struct_iiiiiiiiilt_t arg_4={0}; if (*(ptr_t*)(from_ptr((R_ESP + 4)))) from_struct_iiiiiiiiilt(&arg_4, *(ptr_t*)(from_ptr((R_ESP + 4)))); R_EAX = to_ptrv(fn(*(ptr_t*)(from_ptr((R_ESP + 4))) ? &arg_4 : NULL, from_ptriv(R_ESP + 8))); emu->libc_err = errno; }
 void iEiBLLLLLLLLLLLLLLLLLL__32(x64emu_t *emu, uintptr_t fcn) { iEiBLLLLLLLLLLLLLLLLLL__t fn = (iEiBLLLLLLLLLLLLLLLLLL__t)fcn; errno = emu->libc_err; struct_LLLLLLLLLLLLLLLLLL_t arg_8={0}; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), *(ptr_t*)(from_ptr((R_ESP + 8))) ? &arg_8 : NULL); if (*(ptr_t*)(from_ptr((R_ESP + 8)))) to_struct_LLLLLLLLLLLLLLLLLL(*(ptr_t*)(from_ptr((R_ESP + 8))), &arg_8); emu->libc_err = errno; }
 void vEEip_32(x64emu_t *emu, uintptr_t fcn) { vEEip_t fn = (vEEip_t)fcn; errno = emu->libc_err; fn(emu, from_ptri(int32_t, R_ESP + 4), from_ptriv(R_ESP + 8)); emu->libc_err = errno; }
@@ -2816,7 +2818,6 @@ void iEippL_32(x64emu_t *emu, uintptr_t fcn) { iEippL_t fn = (iEippL_t)fcn; errn
 void iFippp_32(x64emu_t *emu, uintptr_t fcn) { iFippp_t fn = (iFippp_t)fcn; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), from_ptriv(R_ESP + 8), from_ptriv(R_ESP + 12), from_ptriv(R_ESP + 16)); }
 void iEipON_32(x64emu_t *emu, uintptr_t fcn) { iEipON_t fn = (iEipON_t)fcn; errno = emu->libc_err; R_EAX = fn(from_ptri(int32_t, R_ESP + 4), from_ptriv(R_ESP + 8), of_convert32(from_ptri(int32_t, R_ESP + 12)), from_ptriv(R_ESP + 16)); emu->libc_err = errno; }
 void iFuiup_32(x64emu_t *emu, uintptr_t fcn) { iFuiup_t fn = (iFuiup_t)fcn; R_EAX = fn(from_ptri(uint32_t, R_ESP + 4), from_ptri(int32_t, R_ESP + 8), from_ptri(uint32_t, R_ESP + 12), from_ptriv(R_ESP + 16)); }
-void iEuupi_32(x64emu_t *emu, uintptr_t fcn) { iEuupi_t fn = (iEuupi_t)fcn; errno = emu->libc_err; R_EAX = fn(from_ptri(uint32_t, R_ESP + 4), from_ptri(uint32_t, R_ESP + 8), from_ptriv(R_ESP + 12), from_ptri(int32_t, R_ESP + 16)); emu->libc_err = errno; }
 void iFuppp_32(x64emu_t *emu, uintptr_t fcn) { iFuppp_t fn = (iFuppp_t)fcn; R_EAX = fn(from_ptri(uint32_t, R_ESP + 4), from_ptriv(R_ESP + 8), from_ptriv(R_ESP + 12), from_ptriv(R_ESP + 16)); }
 void iFpiii_32(x64emu_t *emu, uintptr_t fcn) { iFpiii_t fn = (iFpiii_t)fcn; R_EAX = fn(from_ptriv(R_ESP + 4), from_ptri(int32_t, R_ESP + 8), from_ptri(int32_t, R_ESP + 12), from_ptri(int32_t, R_ESP + 16)); }
 void iFpiiL_32(x64emu_t *emu, uintptr_t fcn) { iFpiiL_t fn = (iFpiiL_t)fcn; R_EAX = fn(from_ptriv(R_ESP + 4), from_ptri(int32_t, R_ESP + 8), from_ptri(int32_t, R_ESP + 12), from_ulong(from_ptri(ulong_t, R_ESP + 16))); }
@@ -3097,6 +3098,7 @@ void iEEiipV_32(x64emu_t *emu, uintptr_t fcn) { iEEiipV_t fn = (iEEiipV_t)fcn; e
 void iEEipii_32(x64emu_t *emu, uintptr_t fcn) { iEEipii_t fn = (iEEipii_t)fcn; errno = emu->libc_err; R_EAX = fn(emu, from_ptri(int32_t, R_ESP + 4), from_ptriv(R_ESP + 8), from_ptri(int32_t, R_ESP + 12), from_ptri(int32_t, R_ESP + 16)); emu->libc_err = errno; }
 void iEEipuu_32(x64emu_t *emu, uintptr_t fcn) { iEEipuu_t fn = (iEEipuu_t)fcn; errno = emu->libc_err; R_EAX = fn(emu, from_ptri(int32_t, R_ESP + 4), from_ptriv(R_ESP + 8), from_ptri(uint32_t, R_ESP + 12), from_ptri(uint32_t, R_ESP + 16)); emu->libc_err = errno; }
 void iEEippL_32(x64emu_t *emu, uintptr_t fcn) { iEEippL_t fn = (iEEippL_t)fcn; errno = emu->libc_err; R_EAX = fn(emu, from_ptri(int32_t, R_ESP + 4), from_ptriv(R_ESP + 8), from_ptriv(R_ESP + 12), from_ulong(from_ptri(ulong_t, R_ESP + 16))); emu->libc_err = errno; }
+void iEEuupi_32(x64emu_t *emu, uintptr_t fcn) { iEEuupi_t fn = (iEEuupi_t)fcn; errno = emu->libc_err; R_EAX = fn(emu, from_ptri(uint32_t, R_ESP + 4), from_ptri(uint32_t, R_ESP + 8), from_ptriv(R_ESP + 12), from_ptri(int32_t, R_ESP + 16)); emu->libc_err = errno; }
 void iEEpipp_32(x64emu_t *emu, uintptr_t fcn) { iEEpipp_t fn = (iEEpipp_t)fcn; errno = emu->libc_err; R_EAX = fn(emu, from_ptriv(R_ESP + 4), from_ptri(int32_t, R_ESP + 8), from_ptriv(R_ESP + 12), from_ptriv(R_ESP + 16)); emu->libc_err = errno; }
 void iFEpipp_32(x64emu_t *emu, uintptr_t fcn) { iFEpipp_t fn = (iFEpipp_t)fcn; R_EAX = fn(emu, from_ptriv(R_ESP + 4), from_ptri(int32_t, R_ESP + 8), from_ptriv(R_ESP + 12), from_ptriv(R_ESP + 16)); }
 void iEEpipV_32(x64emu_t *emu, uintptr_t fcn) { iEEpipV_t fn = (iEEpipV_t)fcn; errno = emu->libc_err; R_EAX = fn(emu, from_ptriv(R_ESP + 4), from_ptri(int32_t, R_ESP + 8), from_ptriv(R_ESP + 12), from_ptrv(R_ESP + 16)); emu->libc_err = errno; }
diff --git a/src/wrapped32/generated/wrapper32.h b/src/wrapped32/generated/wrapper32.h
index 49a2cce5..3da70e46 100644
--- a/src/wrapped32/generated/wrapper32.h
+++ b/src/wrapped32/generated/wrapper32.h
@@ -177,10 +177,10 @@ void iEBllll__32(x64emu_t *emu, uintptr_t fnc);
 void vFbuuipWCCp__32(x64emu_t *emu, uintptr_t fnc);
 void vFbWWpWpWpWp__32(x64emu_t *emu, uintptr_t fnc);
 void LEbiiiiiiiiilt__32(x64emu_t *emu, uintptr_t fnc);
-void LEriiiiiiiiilt__32(x64emu_t *emu, uintptr_t fnc);
 void pEriiiiiiiiilt__32(x64emu_t *emu, uintptr_t fnc);
 void vEEv_32(x64emu_t *emu, uintptr_t fnc);
 void vFEv_32(x64emu_t *emu, uintptr_t fnc);
+void vFEi_32(x64emu_t *emu, uintptr_t fnc);
 void vEEp_32(x64emu_t *emu, uintptr_t fnc);
 void vFEp_32(x64emu_t *emu, uintptr_t fnc);
 void vFEX_32(x64emu_t *emu, uintptr_t fnc);
@@ -431,6 +431,7 @@ void pErppppii_p_32(x64emu_t *emu, uintptr_t fnc);
 void vFbll_rllll__32(x64emu_t *emu, uintptr_t fnc);
 void iFXbiiuuLip__32(x64emu_t *emu, uintptr_t fnc);
 void iFpruuipWCCp__32(x64emu_t *emu, uintptr_t fnc);
+void lEEriiiiiiiiilt__32(x64emu_t *emu, uintptr_t fnc);
 void pEriiiiiiiiilt_p_32(x64emu_t *emu, uintptr_t fnc);
 void iEiBLLLLLLLLLLLLLLLLLL__32(x64emu_t *emu, uintptr_t fnc);
 void vEEip_32(x64emu_t *emu, uintptr_t fnc);
@@ -959,7 +960,6 @@ void iEippL_32(x64emu_t *emu, uintptr_t fnc);
 void iFippp_32(x64emu_t *emu, uintptr_t fnc);
 void iEipON_32(x64emu_t *emu, uintptr_t fnc);
 void iFuiup_32(x64emu_t *emu, uintptr_t fnc);
-void iEuupi_32(x64emu_t *emu, uintptr_t fnc);
 void iFuppp_32(x64emu_t *emu, uintptr_t fnc);
 void iFpiii_32(x64emu_t *emu, uintptr_t fnc);
 void iFpiiL_32(x64emu_t *emu, uintptr_t fnc);
@@ -1240,6 +1240,7 @@ void iEEiipV_32(x64emu_t *emu, uintptr_t fnc);
 void iEEipii_32(x64emu_t *emu, uintptr_t fnc);
 void iEEipuu_32(x64emu_t *emu, uintptr_t fnc);
 void iEEippL_32(x64emu_t *emu, uintptr_t fnc);
+void iEEuupi_32(x64emu_t *emu, uintptr_t fnc);
 void iEEpipp_32(x64emu_t *emu, uintptr_t fnc);
 void iFEpipp_32(x64emu_t *emu, uintptr_t fnc);
 void iEEpipV_32(x64emu_t *emu, uintptr_t fnc);
diff --git a/src/wrapped32/wrappedlibc.c b/src/wrapped32/wrappedlibc.c
index 82ffca71..bd649363 100755
--- a/src/wrapped32/wrappedlibc.c
+++ b/src/wrapped32/wrappedlibc.c
@@ -42,6 +42,7 @@
 #include <regex.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
+#include <sys/wait.h>
 
 #include "wrappedlibs.h"
 
@@ -418,7 +419,7 @@ static void* findcompare64Fct(void* fct)
 {
     if(!fct) return NULL;
     void* p;
-    if((p = GetNativeFnc((uintptr_t)fct))) return p;
+    if((p = GetNativeFnc((uintptr_t)fct))) { if(p==my32_alphasort64) return alphasort64; else return p; }
     #define GO(A) if(my32_compare64_fct_##A == (uintptr_t)fct) return my32_compare64_##A;
     SUPER()
     #undef GO
@@ -562,13 +563,11 @@ int my32_dl_iterate_phdr(x64emu_t *emu, void* F, void *data);
 
 pid_t EXPORT my32_fork(x64emu_t* emu)
 {
-/*    #if 1
+    #if 1
     emu->quit = 1;
     emu->fork = 1;
     return 0;
     #else
-    return 0;
-    #endif*/
     // execute atforks prepare functions, in reverse order
     for (int i=my_context->atfork_sz-1; i>=0; --i)
         if(my_context->atforks[i].prepare)
@@ -594,13 +593,14 @@ pid_t EXPORT my32_fork(x64emu_t* emu)
                 RunFunctionWithEmu(emu, 0, my_context->atforks[i].child, 0);
     }
     return v;
+    #endif
 }
 pid_t EXPORT my32___fork(x64emu_t* emu) __attribute__((alias("my32_fork")));
 pid_t EXPORT my32_vfork(x64emu_t* emu)
 {
     #if 1
     emu->quit = 1;
-    emu->fork = 1;  // use regular fork...
+    emu->fork = 3;
     return 0;
     #else
     return 0;
@@ -1417,13 +1417,15 @@ EXPORT void* my32_readdir(x64emu_t* emu, void* dirp)
 {
     struct dirent64 *dp64 = readdir64((DIR *)dirp);
     if (!dp64) return NULL;
+    static struct i386_dirent dp32 = {0};
     uint32_t ino32 = dp64->d_ino ^ (dp64->d_ino >> 32);
     int32_t off32 = dp64->d_off;
-    struct i386_dirent *dp32 = (struct i386_dirent *)&(dp64->d_off);
-    dp32->d_ino = ino32;
-    dp32->d_off = off32;
-    dp32->d_reclen -= 8;
-    return dp32;
+    dp32.d_ino = ino32;
+    dp32.d_off = off32;
+    dp32.d_reclen = sizeof(struct i386_dirent);
+    dp32.d_type = dp64->d_type;
+    strncpy(dp32.d_name, dp64->d_name, sizeof(dp32.d_name));
+    return &dp32;
 }
 #if 0
 
@@ -1640,46 +1642,40 @@ EXPORT int32_t my32_glob64(x64emu_t *emu, void* pat, int32_t flags, void* errfnc
 }
 #endif
 #endif
-EXPORT int my32_scandir(x64emu_t *emu, void* dir, void* namelist, void* sel, void* comp)
+EXPORT int my32_scandir(x64emu_t *emu, void* dir, ptr_t* namelist, void* sel, void* comp)
 {
-    struct dirent64** list;
-    int ret = scandir64(dir, &list, findfilter64Fct(sel), findcompare64Fct(comp));
-    if(ret>=0)
-        *(ptr_t*)namelist = to_ptrv(list);
+    struct dirent64** list = NULL;
+    int ret = scandir64(dir, &list, findfilter_dirFct(sel), findcompare_dirFct(comp));
+    *namelist = to_ptrv(list);
     if (ret>0) {
-        // adjust the array of dirent...
-        ptr_t* dp32_list = (ptr_t*)list;
-        struct dirent64** dp64_list = list;
+        // adjust the array of dirent... inplace adjust of listname and inplace of dirent too
         for(int i=0; i<ret; ++i) {
-            struct dirent64* dp64 = dp64_list[i];
+            struct dirent64* dp64 = list[i];
+            struct i386_dirent *dp32 = (struct i386_dirent*)dp64;
+            // inplace shrink dirent
             uint32_t ino32 = dp64->d_ino ^ (dp64->d_ino >> 32);
             int32_t off32 = dp64->d_off;
-            struct i386_dirent *dp32 = (struct i386_dirent *)&(dp64->d_off);
             dp32->d_ino = ino32;
             dp32->d_off = off32;
-            dp32->d_reclen -= 8;
-            *dp32_list = to_ptrv(dp32);
-            ++dp32_list;
-            ++dp64;
+            dp32->d_reclen = dp64->d_reclen-12;
+            dp32->d_type = dp64->d_type;
+            memmove(dp32->d_name, dp64->d_name, dp32->d_reclen-(sizeof(struct i386_dirent)-sizeof(dp32->d_name)));
+            // inplace shrink pointer to
+            ((ptr_t*)list)[i] = to_ptrv(list[i]);
         }
     }
     return ret;
 }
-EXPORT int my32_scandir64(x64emu_t *emu, void* dir, void* namelist, void* sel, void* comp)
+EXPORT int my32_scandir64(x64emu_t *emu, void* dir, ptr_t* namelist, void* sel, void* comp)
 {
     struct dirent64** list;
-    int ret = scandir64(dir, &list, findfilter_dirFct(sel), findcompare_dirFct(comp));
+    int ret = scandir64(dir, &list, findfilter64Fct(sel), findcompare64Fct(comp));
     if(ret>=0)
-        *(ptr_t*)namelist = to_ptrv(list);
+        *namelist = to_ptrv(list);
     if (ret>0) {
-        // adjust the array of dirent...
-        ptr_t* dp32_list = (ptr_t*)list;
-        struct dirent64** dp64_list = list;
+        // inplace shrink of the array of dirent pointer (the dirent themselves are ok)
         for(int i=0; i<ret; ++i) {
-            struct dirent64* dp64 = dp64_list[i];
-            *dp32_list = to_ptrv(dp64);
-            ++dp32_list;
-            ++dp64;
+            ((ptr_t*)list)[i] = to_ptrv(list[i]);
         }
     }
     return ret;
@@ -1715,14 +1711,18 @@ EXPORT int32_t my32_nftw64(x64emu_t* emu, void* pathname, void* B, int32_t nopen
     return nftw64(pathname, findnftw64Fct(B), nopenfd, flags);
 }
 
+EXPORT ptr_t my32_environ = 0; //char**
+EXPORT ptr_t my32__environ = 0; //char**
+EXPORT ptr_t my32___environ = 0;  //char**
+
 EXPORT int32_t my32_execv(x64emu_t* emu, const char* path, ptr_t argv[])
 {
     int self = isProcSelf(path, "exe");
     int x86 = FileIsX86ELF(path);
     int x64 = FileIsX64ELF(path);
     int script = (my_context->bashpath && FileIsShell(path))?1:0;
-    printf_log(LOG_DEBUG, "execv(\"%s\", %p) is x86=%d\n", path, argv, x86);
-    if (x86 || x64 || self) {
+    printf_log(LOG_DEBUG, "execv(\"%s\", %p[%s, %s]) is x64=%d, x86=%d, script=%d\n", path, argv, argv[0]?from_ptrv(argv[0]):"", argv[1]?from_ptrv(argv[1]):"", x64, x86, script);
+    if (x86 || x64 || script || self) {
         int skip_first = 0;
         if(strlen(path)>=strlen("wine-preloader") && strcmp(path+strlen(path)-strlen("wine-preloader"), "wine-preloader")==0)
             skip_first++;
@@ -1730,10 +1730,11 @@ EXPORT int32_t my32_execv(x64emu_t* emu, const char* path, ptr_t argv[])
         int n=skip_first;
         while(argv[n]) ++n;
         int toadd = script?2:1;
-        const char** newargv = (const char**)calloc(n+toadd+2, sizeof(char*));
+        const char** newargv = (const char**)box_calloc(n+toadd+2, sizeof(char*));
         newargv[0] = x64?emu->context->box64path:emu->context->box64path;
+        if(script) newargv[1] = emu->context->bashpath; // script needs to be launched with bash
         for(int i=0; i<n; ++i)
-            newargv[i+1] = from_ptrv(argv[skip_first+i]);
+            newargv[i+toadd] = from_ptrv(argv[skip_first+i]);
         if(self)
             newargv[1] = emu->context->fullpath;
         else {
@@ -1744,16 +1745,18 @@ EXPORT int32_t my32_execv(x64emu_t* emu, const char* path, ptr_t argv[])
         }
         printf_log(LOG_DEBUG, " => execv(\"%s\", %p [\"%s\", \"%s\", \"%s\"...:%d])\n", emu->context->box64path, newargv, newargv[0], n?newargv[1]:"", (n>1)?newargv[2]:"",n);
         int ret = execv(newargv[0], (char* const*)newargv);
-        free(newargv);
+        box_free(newargv);
         return ret;
     }
     // count argv and create the 64bits argv version
     int n=0;
     while(argv[n]) ++n;
-    char** newargv = (char**)calloc(n+1, sizeof(char*));
+    char** newargv = (char**)box_calloc(n+1, sizeof(char*));
     for(int i=0; i<=n; ++i)
         newargv[i] = from_ptrv(argv[i]);
-    return execv(path, (void*)newargv);
+    int ret = execv(path, (void*)newargv);
+    box_free(newargv);
+    return ret;
 }
 
 EXPORT int32_t my32_execve(x64emu_t* emu, const char* path, ptr_t argv[], ptr_t envp[])
@@ -1768,11 +1771,12 @@ EXPORT int32_t my32_execve(x64emu_t* emu, const char* path, ptr_t argv[], ptr_t
     else {
         int n=0;
         while(envp[n]) ++n;
-        const char** newenvp = (const char**)calloc(n+1, sizeof(char*));
+        newenvp = (char**)box_calloc(n+1, sizeof(char*));
         for(int i=0; i<=n; ++i)
-            newenvp[i+1] = from_ptrv(envp[i]);
+            newenvp[i] = from_ptrv(envp[i]);
     }
-    printf_log(LOG_DEBUG, "execve(\"%s\", %p, %p) is x86=%d\n", path, argv, envp, x86);
+    int ret;
+    printf_log(LOG_DEBUG, "execve(\"%s\", %p, %p(%p)) is x86=%d\n", path, argv, envp, newenvp, x86);
     if (x86 || x64 || self) {
         int skip_first = 0;
         if(strlen(path)>=strlen("wine-preloader") && strcmp(path+strlen(path)-strlen("wine-preloader"), "wine-preloader")==0)
@@ -1780,20 +1784,21 @@ EXPORT int32_t my32_execve(x64emu_t* emu, const char* path, ptr_t argv[], ptr_t
         // count argv...
         int n=skip_first;
         while(argv[n]) ++n;
-        const char** newargv = (const char**)calloc(n+2, sizeof(char*));
+        const char** newargv = (const char**)box_calloc(n+2, sizeof(char*));
         newargv[0] = x64?emu->context->box64path:emu->context->box64path;
         for(int i=0; i<n; ++i)
             newargv[i+1] = from_ptrv(argv[skip_first+i]);
         if(self) newargv[1] = emu->context->fullpath;
         printf_log(LOG_DEBUG, " => execve(\"%s\", %p [\"%s\", \"%s\", \"%s\"...:%d])\n", emu->context->box64path, newargv, newargv[0], n?newargv[1]:"", (n>1)?newargv[2]:"",n);
-        int ret = execve(newargv[0], (char* const*)newargv, newenvp);
-        free(newargv);
+        ret = execve(newargv[0], (char* const*)newargv, newenvp);
+        box_free(newargv);
+        box_free(newenvp);
         return ret;
     }
     // count argv and create the 64bits argv version
     int n=0;
     while(argv[n]) ++n;
-    const char** newargv = (const char**)calloc(n+1, sizeof(char*));
+    const char** newargv = (const char**)box_calloc(n+1, sizeof(char*));
     for(int i=0; i<=n; ++i)
         newargv[i] = from_ptrv(argv[i]);
 
@@ -1803,10 +1808,11 @@ EXPORT int32_t my32_execve(x64emu_t* emu, const char* path, ptr_t argv[], ptr_t
         // uname -m is redirected to box32 -m
         path = my_context->box64path;
         const char *argv2[3] = { my_context->box64path, newargv[1], NULL };
-        return execve(path, (void*)argv2, newenvp);
-    }
-
-    return execve(path, (void*)newargv, newenvp);
+        ret = execve(path, (void*)argv2, newenvp);
+    } else
+        ret = execve(path, (void*)newargv, newenvp);
+    box_free(newenvp);
+    return ret;
 }
 
 // execvp should use PATH to search for the program first
@@ -1818,31 +1824,45 @@ EXPORT int32_t my32_execvp(x64emu_t* emu, const char* path, ptr_t argv[])
     int self = isProcSelf(fullpath, "exe");
     int x86 = FileIsX86ELF(fullpath);
     int x64 = FileIsX64ELF(fullpath);
-    printf_log(LOG_DEBUG, "execvp(\"%s\", %p) is x86=%d\n", fullpath, argv, x86);
-    if (x86 || x64 || self) {
+    int script = (my_context->bashpath && FileIsShell(path))?1:0;
+    int ret;
+    printf_log(LOG_DEBUG, "execvp(\"%s\", %p) is x86=%d, x64=%d script=%d\n", fullpath, argv, x86, x64, script);
+    if (x86 || x64 || script || self) {
         int skip_first = 0;
         if(strlen(fullpath)>=strlen("wine-preloader") && strcmp(fullpath+strlen(fullpath)-strlen("wine-preloader"), "wine-preloader")==0)
             skip_first++;
         // count argv...
         int n=skip_first;
         while(argv[n]) ++n;
-        const char** newargv = (const char**)calloc(n+2, sizeof(char*));
+        int toadd = script?2:1;
+        const char** newargv = (const char**)box_calloc(n+toadd+2, sizeof(char*));
         newargv[0] = x64?emu->context->box64path:emu->context->box64path;
+        if(script) newargv[1] = emu->context->bashpath; // script needs to be launched with bash
         for(int i=0; i<n; ++i)
-            newargv[i+1] = from_ptrv(argv[skip_first+i]);
+            newargv[i+toadd] = from_ptrv(argv[skip_first+i]);
         if(self) newargv[1] = emu->context->fullpath;
         printf_log(LOG_DEBUG, " => execv(\"%s\", %p [\"%s\", \"%s\", \"%s\"...:%d])\n", emu->context->box64path, newargv, newargv[0], n?newargv[1]:"", (n>1)?newargv[2]:"",n);
         int ret = execv(newargv[0], (char* const*)newargv);
-        free(newargv);
+        box_free(newargv);
         return ret;
     }
     // count argv and create the 64bits argv version
     int n=0;
     while(argv[n]) ++n;
-    char** newargv = (char**)calloc(n+1, sizeof(char*));
+    char** newargv = (char**)box_calloc(n+1, sizeof(char*));
     for(int i=0; i<=n; ++i)
         newargv[i] = from_ptrv(argv[i]);
-    return execv(fullpath, (void*)newargv);
+    if(!strcmp(path + strlen(path) - strlen("/uname"), "/uname")
+     && newargv[1] && (!strcmp(newargv[1], "-m") || !strcmp(newargv[1], "-p") || !strcmp(newargv[1], "-i"))
+     && !newargv[2]) {
+        // uname -m is redirected to box32 -m
+        path = my_context->box64path;
+        const char *argv2[3] = { my_context->box64path, newargv[1], NULL };
+        ret = execv(path, (void*)argv2);
+    } else
+        ret = execv(fullpath, (void*)newargv);
+    box_free(newargv);
+    return ret;
 }
 // execvp should use PATH to search for the program first
 EXPORT int32_t my32_execvpe(x64emu_t* emu, const char* path, ptr_t argv[], ptr_t envp[])
@@ -1853,6 +1873,7 @@ EXPORT int32_t my32_execvpe(x64emu_t* emu, const char* path, ptr_t argv[], ptr_t
     int self = isProcSelf(fullpath, "exe");
     int x86 = FileIsX86ELF(fullpath);
     int x64 = FileIsX64ELF(fullpath);
+    int script = (my_context->bashpath && FileIsShell(path))?1:0;
     char** newenvp = NULL;
     // hack to update the environ var if needed
     if(envp == from_ptrv(my_context->envv32) && environ)
@@ -1860,27 +1881,29 @@ EXPORT int32_t my32_execvpe(x64emu_t* emu, const char* path, ptr_t argv[], ptr_t
     else {
         int n=0;
         while(envp[n]) ++n;
-        const char** newenvp = (const char**)calloc(n+1, sizeof(char*));
+        newenvp = (char**)box_calloc(n+1, sizeof(char*));
         for(int i=0; i<=n; ++i)
-            newenvp[i+1] = from_ptrv(envp[i]);
+            newenvp[i] = from_ptrv(envp[i]);
     }
-    printf_log(LOG_DEBUG, "execvpe(\"%s\", %p, %p) is x86=%d\n", fullpath, argv, envp, x86);
-    if (x86 || x64 || self) {
+    printf_log(LOG_DEBUG, "execvpe(\"%s\", %p, %p(%p%s)) is x86=%d x64=%d, scrit=%d\n", fullpath, argv, envp, newenvp, (newenvp==environ)?"=environ":"", x86, x64, script);
+    if (x86 || x64 || script || self) {
         int skip_first = 0;
         if(strlen(fullpath)>=strlen("wine-preloader") && strcmp(fullpath+strlen(fullpath)-strlen("wine-preloader"), "wine-preloader")==0)
             skip_first++;
         // count argv...
         int n=skip_first;
         while(argv[n]) ++n;
-        const char** newargv = (const char**)calloc(n+2, sizeof(char*));
+        int toadd = script?2:1;
+        const char** newargv = (const char**)box_calloc(n+toadd+2, sizeof(char*));
         newargv[0] = x64?emu->context->box64path:emu->context->box64path;
-        for(int i=0; i<n; ++i)
-            newargv[i+1] = from_ptrv(argv[skip_first+i]);
+        if(script) newargv[1] = emu->context->bashpath; // script needs to be launched with bash
+        for(int i=0; i<=n; ++i)
+            newargv[i+toadd] = from_ptrv(argv[skip_first+i]);
         if(self) newargv[1] = emu->context->fullpath;
         printf_log(LOG_DEBUG, " => execv(\"%s\", %p [\"%s\", \"%s\", \"%s\"...:%d], %p)\n", emu->context->box64path, newargv, newargv[0], n?newargv[1]:"", (n>1)?newargv[2]:"",n, newenvp);
         int ret = execve(newargv[0], (char* const*)newargv, (char* const*)newenvp);
-        free(newargv);
-        free(newenvp);
+        box_free(newargv);
+        box_free(newenvp);
         return ret;
     }
     // count argv and create the 64bits argv version
@@ -1889,9 +1912,21 @@ EXPORT int32_t my32_execvpe(x64emu_t* emu, const char* path, ptr_t argv[], ptr_t
     char** newargv = (char**)calloc(n+1, sizeof(char*));
     for(int i=0; i<=n; ++i)
         newargv[i] = from_ptrv(argv[i]);
+    if((!strcmp(fullpath + strlen(fullpath) - strlen("/uname"), "/uname") || !strcmp(path, "uname"))
+     && newargv[1] && (!strcmp(newargv[1], "-m") || !strcmp(newargv[1], "-p") || !strcmp(newargv[1], "-i"))
+     && !newargv[2]) {
+        // uname -m is redirected to box64 -m
+        path = my_context->box64path;
+        char *argv2[3] = { my_context->box64path, newargv[1], NULL };
+
+        int ret = execvpe(path, argv2, newenvp);
+        box_free(newargv);
+        box_free(newenvp);
+        return ret;
+    }
     int ret = execve(fullpath, (void*)newargv, (void*)newenvp);
-    free(newargv);
-    free(newenvp);
+    box_free(newargv);
+    box_free(newenvp);
     return ret;
 }
 
@@ -1985,7 +2020,7 @@ EXPORT int32_t my32_posix_spawn(x64emu_t* emu, pid_t* pid, const char* fullpath,
         while(envp[n]) ++n;
         const char** newenvp = (const char**)calloc(n+1, sizeof(char*));
         for(int i=0; i<=n; ++i)
-            newenvp[i+1] = from_ptrv(envp[i]);
+            newenvp[i] = from_ptrv(envp[i]);
     }
     printf_log(LOG_DEBUG, "posix_spawn(%p, \"%s\", %p, %p, %p, %p), IsX86=%d / fullpath=\"%s\"\n", pid, fullpath, actions, attrp, argv, envp, x86, fullpath);
     if ((x86 || self)) {
@@ -2036,7 +2071,7 @@ EXPORT int32_t my32_posix_spawnp(x64emu_t* emu, pid_t* pid, const char* path,
         while(envp[n]) ++n;
         const char** newenvp = (const char**)calloc(n+1, sizeof(char*));
         for(int i=0; i<=n; ++i)
-            newenvp[i+1] = from_ptrv(envp[i]);
+            newenvp[i] = from_ptrv(envp[i]);
     }
     printf_log(LOG_DEBUG, "posix_spawnp(%p, \"%s\", %p, %p, %p, %p), IsX86=%d / fullpath=\"%s\"\n", pid, path, actions, attrp, argv, envp, x86, fullpath);
     free(fullpath);
@@ -2113,6 +2148,16 @@ EXPORT void* my32_localtime(x64emu_t* emu, void* t)
     return NULL;
 }
 
+EXPORT long my32_timegm(x64emu_t* emu, void* t)
+{
+    long ret = timegm(t);
+    if((ret>0 && ret>0x7fffffffLL) || (ret<0 && ret<-0x80000000LL)) {
+        ret = -1;
+        errno = EOVERFLOW;
+    }
+    return ret;
+}
+
 EXPORT void* my32_localtime_r(x64emu_t* emu, void* t, void* res)
 {
     struct_L_t t_ = {0};
@@ -3251,10 +3296,6 @@ EXPORT int my32_on_exit(x64emu_t* emu, void* f, void* args)
 #endif
 #endif
 
-EXPORT ptr_t my32_environ = 0; //char**
-EXPORT ptr_t my32__environ = 0; //char**
-EXPORT ptr_t my32___environ = 0;  //char**
-
 EXPORT char* my32___progname = NULL;
 EXPORT char* my32___progname_full = NULL;
 EXPORT char* my32_program_invocation_name = NULL;
@@ -3285,6 +3326,15 @@ EXPORT void* my32___errno_location(x64emu_t* emu)
     return &emu->libc_err;
 }
 
+void convert_siginfo_to_32(void* d, void* s, int sig);
+EXPORT int my32_waitid(x64emu_t* emu, uint32_t idtype, uint32_t id, void* siginfo, int options)
+{
+    siginfo_t siginfo_l;
+    int ret = waitid(idtype, id, siginfo?(&siginfo_l):NULL, options);
+    convert_siginfo_to_32(siginfo, &siginfo_l, SIGCHLD);
+    return ret;
+}
+
 #undef HAS_MY
 
 #define PRE_INIT\
diff --git a/src/wrapped32/wrappedlibc_private.h b/src/wrapped32/wrappedlibc_private.h
index 5a2390ec..72b8ada8 100755
--- a/src/wrapped32/wrappedlibc_private.h
+++ b/src/wrapped32/wrappedlibc_private.h
@@ -291,13 +291,13 @@ GO(eventfd, iEui)
 //GO(eventfd_read, iEip)
 //GO(eventfd_write, iEiU)
 GO2(execl, iEEpV, my32_execv)
-//GO2(execle, iEEpV, my_32execve)  // Nope! This one needs wrapping, because is char*, char*, ..., char*[]
+//GO2(execle, iEEpV, my32_execve)  // Nope! This one needs wrapping, because is char*, char*, ..., char*[]
 GO2(execlp, iEpV, my32_execvp)
-GOWM(execv, iEEpp)     //%%
-GOM(execve, iEEppp)   //%% and this one too...
-GOWM(execvp, iEEpp)
-GOWM(execvpe, iEEppp)
-GO(exit, vEi)
+GOWM(execv, iEEpp)      //%%
+GOM(execve, iEEppp)     //%% and this one too...
+GOWM(execvp, iEEpp)     //%%
+GOWM(execvpe, iEEppp)   //%%
+GO2(exit, vFEi, my_exit)
 GO(_exit, vEi)
 GOW(_Exit, vEi)
 GOM(__explicit_bzero_chk, vEEpuu)    //%% not always defined
@@ -1270,7 +1270,7 @@ GO(posix_fallocate64, iEiII)
 GO(posix_madvise, iEpLi)
 GOW(posix_memalign, iEBp_LL)
 // posix_openpt // Weak
-GOM(posix_spawn, iEEpppppp)
+GOM(posix_spawn, iEEpppppp) //%%
 GO(posix_spawnattr_destroy, iFp)
 // posix_spawnattr_getflags
 // posix_spawnattr_getpgroup
@@ -1285,11 +1285,11 @@ GO(posix_spawnattr_init, iFp)
 // posix_spawnattr_setschedpolicy
 // posix_spawnattr_setsigdefault
 // posix_spawnattr_setsigmask
-GOM(posix_spawn_file_actions_addclose, iEEpi)
-GOM(posix_spawn_file_actions_adddup2, iEEpii)
-GOM(posix_spawn_file_actions_addopen, iEEpipOi)
-GOM(posix_spawn_file_actions_destroy, iEEp)
-GOM(posix_spawn_file_actions_init, iEEp)
+GOM(posix_spawn_file_actions_addclose, iEEpi)   //%%
+GOM(posix_spawn_file_actions_adddup2, iEEpii)   //%%
+GOM(posix_spawn_file_actions_addopen, iEEpipOi) //%%
+GOM(posix_spawn_file_actions_destroy, iEEp) //%%
+GOM(posix_spawn_file_actions_init, iEEp)    //%%
 GOM(posix_spawnp, iEEpppppp) //%%
 GO(ppoll, iEpurLL_p)
 GO(__ppoll_chk, iEpurLL_pL)
@@ -1830,7 +1830,7 @@ GO(tempnam, pEpp)
 GOW(textdomain, tEp)
 // tfind    // Weak
 GO(time, LEBL_)
-GO(timegm, LEriiiiiiiiilt_)
+GOM(timegm, lEEriiiiiiiiilt_)   //%%
 // timelocal    // Weak
 GO(timerfd_create, iEii)
 //GO(timerfd_gettime, iEip)
@@ -1950,7 +1950,7 @@ GOW(wait, iEp)
 //GOW(__wait, iEp)
 //GOW(wait3, iEpip)
 //GOW(wait4, iEipip)
-GOW(waitid, iEuupi) // might need to wrap "p", it's a siginfo_t *
+GOWM(waitid, iEEuupi)
 GOW(waitpid, iEipi)
 GOW(__waitpid, lElpi)
 //GO(warn, vEppppppppp)