about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-11-04 11:43:27 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-11-04 11:43:27 +0100
commit3448e941710dbf11d2772d5782a0b2d44e7892b1 (patch)
tree2c9ee9d17416e124b7baaa53eefafc2f0a0a7942 /src
parent08085be36070ba22b9e2e99529826d60d5ba149f (diff)
downloadbox64-3448e941710dbf11d2772d5782a0b2d44e7892b1.tar.gz
box64-3448e941710dbf11d2772d5782a0b2d44e7892b1.zip
Improve handling of memory protection, and excution bit
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c10
-rw-r--r--src/dynarec/dynablock.c3
-rw-r--r--src/dynarec/dynarec_native_functions.c2
-rw-r--r--src/emu/modrm.h6
-rw-r--r--src/emu/x64run.c11
-rw-r--r--src/emu/x64run0f.c13
-rw-r--r--src/emu/x64runf20f.c1
-rw-r--r--src/include/signals.h1
-rw-r--r--src/libtools/signal32.c37
-rw-r--r--src/libtools/signals.c93
-rw-r--r--src/wrapped/wrappedlibc.c33
11 files changed, 162 insertions, 48 deletions
diff --git a/src/custommem.c b/src/custommem.c
index 524e5f25..be9f39ed 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -1438,8 +1438,11 @@ void unprotectDB(uintptr_t addr, size_t size, int mark)
                 if(mark)
                     cleanDBFromAddressRange(cur, bend-cur, 0);
                 mprotect((void*)cur, bend-cur, prot);
-            } else if(prot&PROT_DYNAREC_R)
+            } else if(prot&PROT_DYNAREC_R) {
+                if(mark)
+                    cleanDBFromAddressRange(cur, bend-cur, 0);
                 prot &= ~PROT_CUSTOM;
+            }
         }
         if (prot != oprot)
             rb_set(memprot, cur, bend, prot);
@@ -1514,8 +1517,9 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
                 dyn = PROT_DYNAREC_R;
             }
         }
-        if ((prot|dyn) != oprot)
-            rb_set(memprot, cur, bend, prot|dyn);
+        uint32_t new_prot = prot?(prot|dyn):prot;
+        if (new_prot != oprot)
+            rb_set(memprot, cur, bend, new_prot);
         cur = bend;
     }
     UNLOCK_PROT();
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 4c703167..bfe10758 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -19,6 +19,7 @@
 #include "dynarec_private.h"
 #include "elfloader.h"
 #include "bridge.h"
+#include "signals.h"
 
 #include "dynarec_native.h"
 #include "native_lock.h"
@@ -198,6 +199,8 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
 {
     if(hasAlternate((void*)addr))
         return NULL;
+    if((getProtection(addr)&(PROT_EXEC|PROT_READ))!=(PROT_EXEC|PROT_READ))  // cannot be run, get out of the Dynarec
+        return NULL;
     dynablock_t* block = getDB(addr);
     if(block || !create)
         return block;
diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c
index 5a086018..c6ea65b0 100644
--- a/src/dynarec/dynarec_native_functions.c
+++ b/src/dynarec/dynarec_native_functions.c
@@ -172,7 +172,7 @@ void native_ud(x64emu_t* emu)
 void native_priv(x64emu_t* emu)
 {
     emu->test.test = 0;
-    emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
+    emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);
 }
 
 void native_int(x64emu_t* emu, int num)
diff --git a/src/emu/modrm.h b/src/emu/modrm.h
index 2f2cd1fc..6b02e74a 100644
--- a/src/emu/modrm.h
+++ b/src/emu/modrm.h
@@ -11,9 +11,9 @@
 #define F64S    *(int64_t*)(addr+=8, addr-8)

 #define PK(a)   *(uint8_t*)(addr+a)

 #ifdef DYNAREC

-#define STEP if(step) return 0;

-#define STEP2 if(step) {R_RIP = addr; return 0;}

-#define STEP3 if(*step) (*step)++;

+#define STEP  check_exec(emu, addr); if(step) return 0;

+#define STEP2 check_exec(emu, addr); if(step) {R_RIP = addr; return 0;}

+#define STEP3 check_exec(emu, addr); if(*step) (*step)++;

 #else

 #define STEP

 #define STEP2

diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 27232c9e..5859ec34 100644
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -71,6 +71,7 @@ int Run(x64emu_t *emu, int step)
 #ifdef TEST_INTERPRETER
     test->memsize = 0;
 #else
+    check_exec(emu, R_RIP);
 x64emurun:
     while(1) 
 #endif
@@ -1813,7 +1814,7 @@ x64emurun:
             F8;
             if(rex.is32bits && box64_ignoreint3)
             {} else
-            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
+            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);
             STEP;
             #endif
             break;
@@ -1853,7 +1854,7 @@ x64emurun:
             #ifndef TEST_INTERPRETER
             if(rex.is32bits && box64_ignoreint3)
             {} else
-            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
+            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);
             STEP;
             #endif
             break;
@@ -1882,7 +1883,7 @@ x64emurun:
         case 0xF4:                      /* HLT */
             // this is a privilege opcode...
             #ifndef TEST_INTERPRETER
-            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
+            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);
             STEP;
             #endif
             break;
@@ -2016,14 +2017,14 @@ x64emurun:
             // this is a privilege opcode
             if(rex.is32bits && box64_ignoreint3)
             {} else
-            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
+            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);
             STEP;
             break;
         case 0xFB:                      /* STI */
             // this is a privilege opcode
             if(rex.is32bits && box64_ignoreint3)
             {} else
-            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
+            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);
             STEP;
             break;
         case 0xFC:                      /* CLD */
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index d1ae6ff8..0364f4e9 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -387,6 +387,19 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             R_RAX = tmp64u&0xFFFFFFFF;

             break;

 

+        case 0x34:                  /* SYSENTER */

+            #ifndef TEST_INTERPRETER

+            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);

+            STEP;

+            #endif

+            break;

+        case 0x35:                  /* SYSEXIT */

+            #ifndef TEST_INTERPRETER

+            emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);

+            STEP;

+            #endif

+            break;

+

         case 0x38:  // these are some SSE3 opcodes

             opcode = F8;

             switch(opcode) {

diff --git a/src/emu/x64runf20f.c b/src/emu/x64runf20f.c
index 5b28888f..097d0e32 100644
--- a/src/emu/x64runf20f.c
+++ b/src/emu/x64runf20f.c
@@ -20,6 +20,7 @@
 #include "x87emu_private.h"

 #include "box64context.h"

 #include "bridge.h"

+#include "signals.h"

 

 #include "modrm.h"

 

diff --git a/src/include/signals.h b/src/include/signals.h
index cf927503..ef72f401 100644
--- a/src/include/signals.h
+++ b/src/include/signals.h
@@ -62,5 +62,6 @@ void fini_signal_helper(void);
 void emit_signal(x64emu_t* emu, int sig, void* addr, int code);
 void emit_interruption(x64emu_t* emu, int num, void* addr);
 void emit_div0(x64emu_t* emu, void* addr, int code);
+void check_exec(x64emu_t* emu, uintptr_t addr);
 
 #endif //__SIGNALS_H__
diff --git a/src/libtools/signal32.c b/src/libtools/signal32.c
index 8a6a1613..064fd3a0 100644
--- a/src/libtools/signal32.c
+++ b/src/libtools/signal32.c
@@ -398,6 +398,7 @@ uint32_t RunFunctionHandler32(int* exit, int dynarec, i386_ucontext_t* sigcontex
 void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db)
 {
     int Locks = unlockMutex();
+    int log_minimum = (box64_showsegv)?LOG_NONE:((sig==SIGSEGV && my_context->is_sigaction[sig])?LOG_DEBUG:LOG_INFO);
 
     printf_log(LOG_DEBUG, "Sigactionhanlder for signal #%d called (jump to %p/%s)\n", sig, (void*)my_context->signals[sig], GetNativeName((void*)my_context->signals[sig]));
 
@@ -563,22 +564,42 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
     TRAP_x86_CACHEFLT   = 19   // SIMD exception (via SIGFPE) if CPU is SSE capable otherwise Cache flush exception (via SIGSEV)
     */
     uint32_t prot = getProtection((uintptr_t)info->si_addr);
+    uint32_t real_prot = 0;
+    if(prot&PROT_READ) real_prot|=PROT_READ;
+    if(prot&PROT_WRITE) real_prot|=PROT_WRITE;
+    if(prot&PROT_EXEC) real_prot|=PROT_WRITE;
+    if(prot&PROT_DYNAREC) real_prot|=PROT_WRITE;
+    sigcontext->uc_mcontext.gregs[I386_ERR] = 0;
+    sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 0;
     if(sig==SIGBUS)
         sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 17;
     else if(sig==SIGSEGV) {
         if((uintptr_t)info->si_addr == sigcontext->uc_mcontext.gregs[I386_EIP]) {
-            sigcontext->uc_mcontext.gregs[I386_ERR] = (info->si_errno==0x1234)?0:((info->si_errno==0xdead)?(0x2|(info->si_code<<3)):0x0010);    // execution flag issue (probably), unless it's a #GP(0)
-            sigcontext->uc_mcontext.gregs[I386_TRAPNO] = ((info->si_code==SEGV_ACCERR) || (info->si_errno==0x1234) || (info->si_errno==0xdead) || ((uintptr_t)info->si_addr==0))?13:14;
+            if(info->si_errno==0xbad0) {
+                //bad opcode
+                sigcontext->uc_mcontext.gregs[I386_ERR] = 0;
+                sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 13;
+                info2->si_errno = 0;
+            } else if (info->si_errno==0xecec) {
+                // no excute bit on segment
+                sigcontext->uc_mcontext.gregs[I386_ERR] = (real_prot&PROT_READ)?16:1; // EXECUTE_FAULT & READ_FAULT
+                sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 14;
+                info2->si_errno = 0;
+            }else {
+                sigcontext->uc_mcontext.gregs[I386_ERR] = (real_prot&PROT_READ)?16:1;//(info->si_errno==0x1234)?0:((info->si_errno==0xdead)?(0x2|(info->si_code<<3)):0x0010);    // execution flag issue (probably), unless it's a #GP(0)
+                sigcontext->uc_mcontext.gregs[I386_TRAPNO] = (getMmapped((uintptr_t)info->si_addr))?14:13;
+                //sigcontext->uc_mcontext.gregs[I386_TRAPNO] = ((info->si_code==SEGV_ACCERR) || (info->si_errno==0x1234) || (info->si_errno==0xdead) || ((uintptr_t)info->si_addr==0))?13:14;
+            }
         } else if(info->si_code==SEGV_ACCERR && !(prot&PROT_WRITE)) {
-            sigcontext->uc_mcontext.gregs[I386_ERR] = 0x0002;    // write flag issue
+            sigcontext->uc_mcontext.gregs[I386_ERR] = (real_prot&PROT_READ)?2:1;//0x0002;    // write flag issue
             sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 14;
         } else {
             if((info->si_code!=SEGV_ACCERR) && labs((intptr_t)info->si_addr-(intptr_t)sigcontext->uc_mcontext.gregs[I386_ESP])<16)
                 sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 12; // stack overflow probably
             else
-                sigcontext->uc_mcontext.gregs[I386_TRAPNO] = (info->si_code == SEGV_ACCERR)?13:14;
+                sigcontext->uc_mcontext.gregs[I386_TRAPNO] = (info->si_code == SEGV_ACCERR)?14:13;
             //I386_ERR seems to be INT:8 CODE:8. So for write access segfault it's 0x0002 For a read it's 0x0004 (and 8 for exec). For an int 2d it could be 0x2D01 for example
-            sigcontext->uc_mcontext.gregs[I386_ERR] = 0x0004;    // read error? there is no execute control in box64 anyway
+            sigcontext->uc_mcontext.gregs[I386_ERR] = 0x0001;    // read error?
         }
         if(info->si_code == SEGV_ACCERR && old_code)
             *old_code = -1;
@@ -586,7 +607,7 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
             info2->si_errno = 0;
         } else if(info->si_errno==0xdead) {
             // INT x
-            uint8_t int_n = info2->si_code;
+            uint8_t int_n = info->si_code;
             info2->si_errno = 0;
             info2->si_code = info->si_code;
             info2->si_addr = NULL;
@@ -621,7 +642,7 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
         sigcontext->uc_mcontext.gregs[I386_ERR] = 0;
     }
     //TODO: SIGABRT generate what?
-    printf_log(LOG_DEBUG, "Signal %d: si_addr=%p, TRAPNO=%d, ERR=%d, RIP=%p\n", sig, (void*)info2->si_addr, sigcontext->uc_mcontext.gregs[I386_TRAPNO], sigcontext->uc_mcontext.gregs[I386_ERR],from_ptrv(sigcontext->uc_mcontext.gregs[I386_EIP]));
+    printf_log((sig==10)?LOG_DEBUG:log_minimum, "Signal %d: si_addr=%p, TRAPNO=%d, ERR=%d, RIP=%p\n", sig, (void*)info2->si_addr, sigcontext->uc_mcontext.gregs[I386_TRAPNO], sigcontext->uc_mcontext.gregs[I386_ERR],from_ptrv(sigcontext->uc_mcontext.gregs[I386_EIP]));
     // call the signal handler
     i386_ucontext_t sigcontext_copy = *sigcontext;
     // save old value from emu
@@ -684,7 +705,7 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
             #undef GO
             for(int i=0; i<6; ++i)
                 emu->segs_serial[i] = 0;
-            printf_log(LOG_DEBUG, "Context has been changed in Sigactionhanlder, doing siglongjmp to resume emu at %p, RSP=%p\n", (void*)R_RIP, (void*)R_RSP);
+            printf_log((sig==10)?LOG_DEBUG:log_minimum, "Context has been changed in Sigactionhanlder, doing siglongjmp to resume emu at %p, RSP=%p\n", (void*)R_RIP, (void*)R_RSP);
             if(old_code)
                 *old_code = -1;    // re-init the value to allow another segfault at the same place
             //relockMutex(Locks);   // do not relock mutex, because of the siglongjmp, whatever was running is canceled
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index e7280663..eebae427 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -286,7 +286,7 @@ static __thread int signal_jmpbuf_active = 0;
 //1<<1 is mutex_prot, 1<<8 is mutex_dyndump
 #define is_memprot_locked (1<<1)
 #define is_dyndump_locked (1<<8)
-uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext, uintptr_t fnc, int nargs, ...)
+uint64_t RunFunctionHandler(x64emu_t* emu, int* exit, int dynarec, x64_ucontext_t* sigcontext, uintptr_t fnc, int nargs, ...)
 {
     if(fnc==0 || fnc==1) {
         va_list va;
@@ -311,8 +311,8 @@ uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext,
     // Dynarec cannot be used in signal handling unless custom malloc is used
     dynarec = 0;
 #endif
-
-    x64emu_t *emu = thread_get_emu();
+    if(!emu)
+        emu = thread_get_emu();
     #ifdef DYNAREC
     if(box64_dynarec_test)
         emu->test.test = 0;
@@ -927,7 +927,7 @@ int sigbus_specialcases(siginfo_t* info, void * ucntx, void* pc, void* _fpsimd)
 #ifdef BOX32
 void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db);
 #endif
-void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db)
+void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db)
 {
     #ifdef BOX32
     if(box64_is32bits) {
@@ -936,12 +936,14 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
     }
     #endif
     int Locks = unlockMutex();
+    int log_minimum = (box64_showsegv)?LOG_NONE:((sig==SIGSEGV && my_context->is_sigaction[sig])?LOG_DEBUG:LOG_INFO);
 
     printf_log(LOG_DEBUG, "Sigactionhanlder for signal #%d called (jump to %p/%s)\n", sig, (void*)my_context->signals[sig], GetNativeName((void*)my_context->signals[sig]));
 
     uintptr_t restorer = my_context->restorer[sig];
     // get that actual ESP first!
-    x64emu_t *emu = thread_get_emu();
+    if(!emu)
+        emu = thread_get_emu();
     uintptr_t frame = R_RSP;
 #if defined(DYNAREC)
 #if defined(ARM64)
@@ -1143,22 +1145,42 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
     TRAP_x86_CACHEFLT   = 19   // SIMD exception (via SIGFPE) if CPU is SSE capable otherwise Cache flush exception (via SIGSEV)
     */
     uint32_t prot = getProtection((uintptr_t)info->si_addr);
+    uint32_t real_prot = 0;
+    if(prot&PROT_READ) real_prot|=PROT_READ;
+    if(prot&PROT_WRITE) real_prot|=PROT_WRITE;
+    if(prot&PROT_EXEC) real_prot|=PROT_WRITE;
+    if(prot&PROT_DYNAREC) real_prot|=PROT_WRITE;
+    sigcontext->uc_mcontext.gregs[X64_ERR] = 0;
+    sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 0;
     if(sig==SIGBUS)
         sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 17;
     else if(sig==SIGSEGV) {
         if((uintptr_t)info->si_addr == sigcontext->uc_mcontext.gregs[X64_RIP]) {
-            sigcontext->uc_mcontext.gregs[X64_ERR] = (info->si_errno==0x1234)?0:((info->si_errno==0xdead)?(0x2|(info->si_code<<3)):0x0010);    // execution flag issue (probably), unless it's a #GP(0)
-            sigcontext->uc_mcontext.gregs[X64_TRAPNO] = ((info->si_code==SEGV_ACCERR) || (info->si_errno==0x1234) || (info->si_errno==0xdead) || ((uintptr_t)info->si_addr==0))?13:14;
+            if(info->si_errno==0xbad0) {
+                //bad opcode
+                sigcontext->uc_mcontext.gregs[X64_ERR] = 0;
+                sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 13;
+                info2->si_errno = 0;
+            } else if (info->si_errno==0xecec) {
+                // no excute bit on segment
+                sigcontext->uc_mcontext.gregs[X64_ERR] = (real_prot&PROT_READ)?16:1; // EXECUTE_FAULT & READ_FAULT
+                sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (getMmapped((uintptr_t)info->si_addr))?14:13;
+                info2->si_errno = 0;
+            }else {
+                sigcontext->uc_mcontext.gregs[X64_ERR] = (real_prot&PROT_READ)?16:1;//(info->si_errno==0x1234)?0:((info->si_errno==0xdead)?(0x2|(info->si_code<<3)):0x0010);    // execution flag issue (probably), unless it's a #GP(0)
+                sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (getMmapped((uintptr_t)info->si_addr))?14:13;
+                //sigcontext->uc_mcontext.gregs[X64_TRAPNO] = ((info->si_code==SEGV_ACCERR) || (info->si_errno==0x1234) || (info->si_errno==0xdead) || ((uintptr_t)info->si_addr==0))?13:14;
+            }
         } else if(info->si_code==SEGV_ACCERR && !(prot&PROT_WRITE)) {
-            sigcontext->uc_mcontext.gregs[X64_ERR] = 0x0002;    // write flag issue
+            sigcontext->uc_mcontext.gregs[X64_ERR] = (real_prot&PROT_READ)?2:1;//0x0002;    // write flag issue
             sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 14;
         } else {
             if((info->si_code!=SEGV_ACCERR) && labs((intptr_t)info->si_addr-(intptr_t)sigcontext->uc_mcontext.gregs[X64_RSP])<16)
                 sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 12; // stack overflow probably
             else
-                sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (info->si_code == SEGV_ACCERR)?13:14;
+                sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (info->si_code == SEGV_ACCERR)?14:13;
             //X64_ERR seems to be INT:8 CODE:8. So for write access segfault it's 0x0002 For a read it's 0x0004 (and 8 for exec). For an int 2d it could be 0x2D01 for example
-            sigcontext->uc_mcontext.gregs[X64_ERR] = 0x0004;    // read error? there is no execute control in box64 anyway
+            sigcontext->uc_mcontext.gregs[X64_ERR] = 0x0001;    // read error?
         }
         if(info->si_code == SEGV_ACCERR && old_code)
             *old_code = -1;
@@ -1166,7 +1188,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
             info2->si_errno = 0;
         } else if(info->si_errno==0xdead) {
             // INT x
-            uint8_t int_n = info2->si_code;
+            uint8_t int_n = info->si_code;
             info2->si_errno = 0;
             info2->si_code = info->si_code;
             info2->si_addr = NULL;
@@ -1201,7 +1223,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
         sigcontext->uc_mcontext.gregs[X64_ERR] = 0;
     }
     //TODO: SIGABRT generate what?
-    printf_log(LOG_DEBUG, "Signal %d: si_addr=%p, TRAPNO=%d, ERR=%d, RIP=%p\n", sig, (void*)info2->si_addr, sigcontext->uc_mcontext.gregs[X64_TRAPNO], sigcontext->uc_mcontext.gregs[X64_ERR],sigcontext->uc_mcontext.gregs[X64_RIP]);
+    printf_log((sig==10)?LOG_DEBUG:log_minimum, "Signal %d: si_addr=%p, TRAPNO=%d, ERR=%d, RIP=%p\n", sig, (void*)info2->si_addr, sigcontext->uc_mcontext.gregs[X64_TRAPNO], sigcontext->uc_mcontext.gregs[X64_ERR],sigcontext->uc_mcontext.gregs[X64_RIP]);
     // call the signal handler
     x64_ucontext_t sigcontext_copy = *sigcontext;
     // save old value from emu
@@ -1227,7 +1249,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
     if(sig!=SIGSEGV && !(Locks&is_dyndump_locked) && !(Locks&is_memprot_locked))
         dynarec = 1;
     #endif
-    ret = RunFunctionHandler(&exits, dynarec, sigcontext, my_context->signals[info2->si_signo], 3, info2->si_signo, info2, sigcontext);
+    ret = RunFunctionHandler(emu, &exits, dynarec, sigcontext, my_context->signals[info2->si_signo], 3, info2->si_signo, info2, sigcontext);
     // restore old value from emu
     if(used_stack)  // release stack
         new_ss->ss_flags = 0;
@@ -1279,7 +1301,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
             #undef GO
             for(int i=0; i<6; ++i)
                 emu->segs_serial[i] = 0;
-            printf_log(LOG_DEBUG, "Context has been changed in Sigactionhanlder, doing siglongjmp to resume emu at %p, RSP=%p\n", (void*)R_RIP, (void*)R_RSP);
+            printf_log((sig==10)?LOG_DEBUG:log_minimum, "Context has been changed in Sigactionhanlder, doing siglongjmp to resume emu at %p, RSP=%p\n", (void*)R_RIP, (void*)R_RSP);
             if(old_code)
                 *old_code = -1;    // re-init the value to allow another segfault at the same place
             //relockMutex(Locks);   // do not relock mutex, because of the siglongjmp, whatever was running is canceled
@@ -1339,7 +1361,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
         exit(ret);
     }
     if(restorer)
-        RunFunctionHandler(&exits, 0, NULL, restorer, 0);
+        RunFunctionHandler(emu, &exits, 0, NULL, restorer, 0);
     relockMutex(Locks);
 }
 
@@ -1854,7 +1876,7 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
     }
     relockMutex(Locks);
     if(my_context->signals[sig] && my_context->signals[sig]!=1) {
-        my_sigactionhandler_oldcode(sig, my_context->is_sigaction[sig]?0:1, info, ucntx, &old_code, db);
+        my_sigactionhandler_oldcode(emu, sig, my_context->is_sigaction[sig]?0:1, info, ucntx, &old_code, db);
         return;
     }
     // no handler (or double identical segfault)
@@ -1882,7 +1904,7 @@ void my_sigactionhandler(int32_t sig, siginfo_t* info, void * ucntx)
     void* db = NULL;
     #endif
 
-    my_sigactionhandler_oldcode(sig, 0, info, ucntx, NULL, db);
+    my_sigactionhandler_oldcode(NULL, sig, 0, info, ucntx, NULL, db);
 }
 
 #ifndef DYNAREC
@@ -1895,6 +1917,13 @@ void emit_signal(x64emu_t* emu, int sig, void* addr, int code)
     info.si_signo = sig;
     info.si_errno = (sig==SIGSEGV)?0x1234:0;    // Mark as a sign this is a #GP(0) (like privileged instruction)
     info.si_code = code;
+    if(sig==SIGSEGV && code==0xbad0) {
+        info.si_errno = 0xbad0;
+        info.si_code = 0;
+    } else if(sig==SIGSEGV && code==0xecec) {
+        info.si_errno = 0xecec;
+        info.si_code = SEGV_ACCERR;
+    }
     info.si_addr = addr;
     const char* x64name = NULL;
     const char* elfname = NULL;
@@ -1903,13 +1932,33 @@ void emit_signal(x64emu_t* emu, int sig, void* addr, int code)
         elfheader_t* elf = FindElfAddress(my_context, R_RIP);
         if(elf)
             elfname = ElfName(elf);
-        printf_log(LOG_NONE, "Emit Signal %d at IP=%p(%s / %s) / addr=%p, code=%d\n", sig, (void*)R_RIP, x64name?x64name:"???", elfname?elfname:"?", addr, code);
+        printf_log(LOG_NONE, "Emit Signal %d at IP=%p(%s / %s) / addr=%p, code=0x%x\n", sig, (void*)R_RIP, x64name?x64name:"???", elfname?elfname:"?", addr, code);
+printf_log(LOG_NONE, DumpCPURegs(emu, R_RIP, emu->segs[_CS]==0x23));
+        //if(!elf) {
+        //    FILE* f = fopen("/proc/self/maps", "r");
+        //    if(f) {
+        //        char line[1024];
+        //        while(!feof(f)) {
+        //            char* ret = fgets(line, sizeof(line), f);
+        //            printf_log(LOG_NONE, "\t%s", ret);
+        //        }
+        //        fclose(f);
+        //    }
+        //}
         if(sig==SIGILL) {
             uint8_t* mem = (uint8_t*)R_RIP;
             printf_log(LOG_NONE, "SIGILL: Opcode at ip is %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx\n", mem[0], mem[1], mem[2], mem[3], mem[4], mem[5]);
         }
     }
-    my_sigactionhandler_oldcode(sig, 0, &info, NULL, NULL, NULL);
+    my_sigactionhandler_oldcode(emu, sig, 0, &info, NULL, NULL, NULL);
+}
+
+void check_exec(x64emu_t* emu, uintptr_t addr)
+{
+    while((getProtection(addr)&(PROT_EXEC|PROT_READ))!=(PROT_EXEC|PROT_READ)) {
+        R_RIP = addr;   // incase there is a slight difference
+        emit_signal(emu, SIGSEGV, (void*)addr, 0xecec);
+    }
 }
 
 void emit_interruption(x64emu_t* emu, int num, void* addr)
@@ -1918,7 +1967,7 @@ void emit_interruption(x64emu_t* emu, int num, void* addr)
     info.si_signo = SIGSEGV;
     info.si_errno = 0xdead;
     info.si_code = num;
-    info.si_addr = addr;
+    info.si_addr = NULL;//addr;
     const char* x64name = NULL;
     const char* elfname = NULL;
     if(box64_log>LOG_INFO || box64_dynarec_dump || box64_showsegv) {
@@ -1928,7 +1977,7 @@ void emit_interruption(x64emu_t* emu, int num, void* addr)
             elfname = ElfName(elf);
         printf_log(LOG_NONE, "Emit Interruption 0x%x at IP=%p(%s / %s) / addr=%p\n", num, (void*)R_RIP, x64name?x64name:"???", elfname?elfname:"?", addr);
     }
-    my_sigactionhandler_oldcode(SIGSEGV, 0, &info, NULL, NULL, NULL);
+    my_sigactionhandler_oldcode(emu, SIGSEGV, 0, &info, NULL, NULL, NULL);
 }
 
 void emit_div0(x64emu_t* emu, void* addr, int code)
@@ -1947,7 +1996,7 @@ void emit_div0(x64emu_t* emu, void* addr, int code)
             elfname = ElfName(elf);
         printf_log(LOG_NONE, "Emit Divide by 0 at IP=%p(%s / %s) / addr=%p\n", (void*)R_RIP, x64name?x64name:"???", elfname?elfname:"?", addr);
     }
-    my_sigactionhandler_oldcode(SIGSEGV, 0, &info, NULL, NULL, NULL);
+    my_sigactionhandler_oldcode(emu, SIGSEGV, 0, &info, NULL, NULL, NULL);
 }
 
 EXPORT sighandler_t my_signal(x64emu_t* emu, int signum, sighandler_t handler)
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index 8ca4c5b9..d10289da 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -1703,6 +1703,14 @@ static int isSysCpuCache(const char *path, const char* w, int* _cpu, int* _index
     return 1;
 }
 
+static long isProcMem(const char* path)
+{
+    long pid;
+    if(sscanf(path, "/proc/%ld/mem", &pid)==1)
+        return pid;
+    return 0;
+}
+
 EXPORT ssize_t my_readlink(x64emu_t* emu, void* path, void* buf, size_t sz)
 {
     if(isProcSelf((const char*)path, "exe")) {
@@ -1919,6 +1927,10 @@ EXPORT int32_t my_open(x64emu_t* emu, void* pathname, int32_t flags, uint32_t mo
         lseek(tmp, 0, SEEK_SET);
         return tmp;
     }
+    if(box64_wine && isProcMem(pathname) && (mode&O_WRONLY)) {
+        // deny using proc/XX/mem as it messes up with dynarec memory protection & tracking
+        return -1;
+    }
     #endif
     int ret = open(pathname, flags, mode);
     return ret;
@@ -3411,24 +3423,33 @@ EXPORT long my_ptrace(x64emu_t* emu, int request, pid_t pid, void* addr, uint32_
 {
     if(request == PTRACE_POKEUSER) {
         if(ptrace(PTRACE_PEEKDATA, pid, &userdata_sign, NULL)==userdata_sign  && (uintptr_t)addr < sizeof(userdata)) {
-            ptrace(PTRACE_POKEDATA, pid, addr+(uintptr_t)userdata, data);
-            return 0;
+            long ret = ptrace(PTRACE_POKEDATA, pid, addr+(uintptr_t)userdata, data);
+            return ret;
         }
         // fallback to a generic local faking
-        if((uintptr_t)addr < sizeof(userdata))
+        if((uintptr_t)addr < sizeof(userdata)) {
             *(uintptr_t*)(addr+(uintptr_t)userdata) = (uintptr_t)data;
         // lets just ignore this for now!
-        return 0;
+            errno = 0;
+            return 0;
+        }
+        errno = EINVAL;
+        return -1;
     }
     if(request == PTRACE_PEEKUSER) {
         if(ptrace(PTRACE_PEEKDATA, pid, &userdata_sign, NULL)==userdata_sign  && (uintptr_t)addr < sizeof(userdata)) {
             return ptrace(PTRACE_PEEKDATA, pid, addr+(uintptr_t)userdata, data);
         }
         // fallback to a generic local faking
-        if((uintptr_t)addr < sizeof(userdata))
+        if((uintptr_t)addr < sizeof(userdata)) {
+            errno = 0;
             return *(uintptr_t*)(addr+(uintptr_t)userdata);
+        }
+        errno = EINVAL;
+        return -1;
     }
-    return ptrace(request, pid, addr, data);
+    long ret = ptrace(request, pid, addr, data);
+    return ret;
 }
 
 // Backtrace stuff