about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-11-18 17:18:41 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-11-18 17:18:41 +0100
commit8f08a141159ce432dc945062bc85213a0864104d (patch)
tree94c4e7380e52e0e6aa16fd17e96159745c37a173
parent4ac43047d0caf9e3765e8de1f57c534e5fec57f6 (diff)
downloadbox64-8f08a141159ce432dc945062bc85213a0864104d.tar.gz
box64-8f08a141159ce432dc945062bc85213a0864104d.zip
Improved Signal handling ([ARM4_DYNAREC] too)
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c9
-rw-r--r--src/dynarec/dynarec_native_functions.c2
-rw-r--r--src/emu/modrm.h5
-rw-r--r--src/emu/x64emu.c6
-rw-r--r--src/emu/x64run.c29
-rw-r--r--src/emu/x64run64.c4
-rw-r--r--src/emu/x64run67_32.c15
-rw-r--r--src/emu/x64run_private.c8
-rw-r--r--src/emu/x64run_private.h2
-rw-r--r--src/libtools/signal32.c90
-rw-r--r--src/libtools/signals.c25
11 files changed, 154 insertions, 41 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index c777ed3d..807c93cd 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1471,7 +1471,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             MOV32w(x1, 0x202);
             ORRw_REG(xFlags, xFlags, x1);
             SET_DFNONE(x1);
-            if(box64_wine) {    // should this be done all the time?
+            if(box64_wine || 1) {    // should this be done all the time?
                 TBZ_NEXT(xFlags, F_TF);
                 // go to epilog, TF should trigger at end of next opcode, so using Interpreter only
                 jump_to_epilog(dyn, addr, 0, ninst);
@@ -2443,7 +2443,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             } else {
                 INST_NAME("INT n");
                 SETFLAGS(X_ALL, SF_SET_NODF);    // Hack to set flags in "don't care" state
-                GETIP(ip);  // priviledged instruction, IP not updated
+                if(rex.is32bits && u8==0x04) {
+                    GETIP(addr);
+                } else {
+                    GETIP(ip);  // priviledged instruction, IP not updated
+                }
                 STORE_XEMU_CALL(xRIP);
                 MOV32w(x1,u8);
                 CALL(native_int, -1);
@@ -2462,6 +2466,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 GETIP(addr);
                 TBZ_NEXT(wFlags, F_OF);
                 STORE_XEMU_CALL(xRIP);
+                MOV32w(x1,4);
                 CALL(native_int, -1);
                 LOAD_XEMU_CALL(xRIP);
             }
diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c
index f0bf3d08..e2e149f2 100644
--- a/src/dynarec/dynarec_native_functions.c
+++ b/src/dynarec/dynarec_native_functions.c
@@ -194,7 +194,7 @@ void native_int3(x64emu_t* emu)
 void native_div0(x64emu_t* emu)
 {
     emu->test.test = 0;
-    emit_div0(emu,  (void*)R_RIP, 0);
+    emit_div0(emu,  (void*)R_RIP, 1);
 }
 
 void native_fsave(x64emu_t* emu, uint8_t* ed)
diff --git a/src/emu/modrm.h b/src/emu/modrm.h
index fcfc7dc6..d62d13c6 100644
--- a/src/emu/modrm.h
+++ b/src/emu/modrm.h
@@ -11,8 +11,8 @@
 #define F64S    *(int64_t*)(addr+=8, addr-8)

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

 #ifdef DYNAREC

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

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

+#define STEP  check_exec(emu, addr); if(step && !ACCESS_FLAG(F_TF)) return 0;

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

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

 #else

 #define STEP

@@ -110,6 +110,7 @@
 #define FAKEED32(D)         GetEd32O(emu, &addr, rex, nextop, D, 0)

 #define GETEA(D)            GetEA(emu, &addr, rex, nextop, D)

 #define GETEA32(D)          GetEA32(emu, &addr, rex, nextop, D)

+#define GETEA32_16(D)       GetEA32_16(emu, &addr, rex, nextop, D)

 #define _GETED(D)           oped=GetEd(emu, &addr, rex, nextop, D)

 #define _GETED_OFFS(D, O)   oped=GetEdO(emu, &addr, rex, nextop, D, O)

 #define _GETED32(D)         oped=GetEd32O(emu, &addr, rex, nextop, D, 0)

diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index 8eec238b..4441ba53 100644
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -578,15 +578,15 @@ void UnimpOpcode(x64emu_t* emu, int is32bits)
     R_RIP = emu->old_ip;
 
     int tid = syscall(SYS_gettid);
-    printf_log(LOG_NONE, "%04d|%p: Unimplemented %sOpcode (%02X %02X %02X %02X) %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", 
+    printf_log(LOG_INFO, "%04d|%p: Unimplemented %sOpcode (%02X %02X %02X %02X) %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", 
         tid, (void*)emu->old_ip, is32bits?"32bits ":"",
         Peek(emu, -4), Peek(emu, -3), Peek(emu, -2), Peek(emu, -1),
         Peek(emu, 0), Peek(emu, 1), Peek(emu, 2), Peek(emu, 3),
         Peek(emu, 4), Peek(emu, 5), Peek(emu, 6), Peek(emu, 7),
         Peek(emu, 8), Peek(emu, 9), Peek(emu,10), Peek(emu,11),
         Peek(emu,12), Peek(emu,13), Peek(emu,14));
-    emu->quit=1;
-    emu->error |= ERR_UNIMPL;
+    //emu->quit=1;
+    //emu->error |= ERR_UNIMPL;
 }
 
 void EmuCall(x64emu_t* emu, uintptr_t addr)
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 51380c8b..a0939a92 100644
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -245,6 +245,8 @@ x64emurun:
             }
             emu->segs[_SS] = Pop32(emu);    // no check, no use....
             emu->segs_serial[_SS] = 0;
+            if(ACCESS_FLAG(F_TF))
+                tf_next = 1;
             break;
 
         case 0x1E:                      /* PUSH DS */
@@ -590,10 +592,8 @@ x64emurun:
 #ifndef TEST_INTERPRETER
             if(rex.is32bits && box64_ignoreint3)
             {
-                F8;
             } else {
-                F8;
-                emit_signal(emu, SIGSEGV, (void*)R_RIP, 0);
+                emit_signal(emu, SIGSEGV, (void*)R_RIP, 0xbad0);
             }
             STEP;
             #endif
@@ -826,6 +826,8 @@ x64emurun:
             GETED(0);
             emu->segs[((nextop&0x38)>>3)] = ED->word[0];
             emu->segs_serial[((nextop&0x38)>>3)] = 0;
+            if(((nextop&0x38)>>3)==_SS && ACCESS_FLAG(F_TF))
+                tf_next = 1;
             break;
         case 0x8F:                      /* POP Ed */
             nextop = F8;
@@ -1544,6 +1546,8 @@ x64emurun:
                 emit_interruption(emu, 0x29, (void*)R_RIP);
             } else if (tmp8u==0x80) {
                 R_RIP = addr;
+                if(ACCESS_FLAG(F_TF))
+                    tf_next = 1;
                 // 32bits syscall
                 #ifndef TEST_INTERPRETER
                 x86Syscall(emu);
@@ -1556,6 +1560,9 @@ x64emurun:
                 STEP2;
                 #endif
             } else {
+                if(rex.is32bits && tmp8u==0x04) {
+                    R_RIP = addr;
+                }
                 #ifndef TEST_INTERPRETER
                 emit_interruption(emu, tmp8u, (void*)R_RIP);
                 STEP2;
@@ -1572,7 +1579,7 @@ x64emurun:
             #ifndef TEST_INTERPRETER
             CHECK_FLAGS(emu);
             if(ACCESS_FLAG(F_OF))
-                emit_signal(emu, SIGSEGV, (void*)R_RIP, 128);
+                emit_interruption(emu, 4, (void*)R_RIP);
             STEP2;
             #endif
             break;
@@ -1954,12 +1961,12 @@ x64emurun:
                     break;
                 case 6:                 /* DIV Eb */
                     if(!EB->byte[0])
-                        emit_div0(emu, (void*)R_RIP, 0);
+                        emit_div0(emu, (void*)R_RIP, 1);
                     div8(emu, EB->byte[0]);
                     break;
                 case 7:                 /* IDIV Eb */
                     if(!EB->byte[0])
-                        emit_div0(emu, (void*)R_RIP, 0);
+                        emit_div0(emu, (void*)R_RIP, 1);
                     idiv8(emu, EB->byte[0]);
                     break;
             }
@@ -1989,12 +1996,12 @@ x64emurun:
                         break;
                     case 6:                 /* DIV Ed */
                         if(!ED->q[0])
-                            emit_div0(emu, (void*)R_RIP, 0);
+                            emit_div0(emu, (void*)R_RIP, 1);
                         div64(emu, ED->q[0]);
                         break;
                     case 7:                 /* IDIV Ed */
                         if(!ED->q[0])
-                            emit_div0(emu, (void*)R_RIP, 0);
+                            emit_div0(emu, (void*)R_RIP, 1);
                         idiv64(emu, ED->q[0]);
                         break;
                 }
@@ -2029,14 +2036,14 @@ x64emurun:
                         break;
                     case 6:                 /* DIV Ed */
                         if(!ED->dword[0])
-                            emit_div0(emu, (void*)R_RIP, 0);
+                            emit_div0(emu, (void*)R_RIP, 1);
                         div32(emu, ED->dword[0]);
                         //emu->regs[_AX].dword[1] = 0;  // already put high regs to 0
                         //emu->regs[_DX].dword[1] = 0;
                         break;
                     case 7:                 /* IDIV Ed */
                         if(!ED->dword[0])
-                            emit_div0(emu, (void*)R_RIP, 0);
+                            emit_div0(emu, (void*)R_RIP, 1);
                         idiv32(emu, ED->dword[0]);
                         //emu->regs[_AX].dword[1] = 0;
                         //emu->regs[_DX].dword[1] = 0;
@@ -2256,7 +2263,7 @@ if(emu->segs[_CS]!=0x33 && emu->segs[_CS]!=0x23) printf_log(LOG_NONE, "Warning,
 #ifndef TEST_INTERPRETER
     printf_log(LOG_DEBUG, "End of X86 run (%p), RIP=%p, Stack=%p, unimp=%d, emu->fork=%d, emu->uc_link=%p, emu->quit=%d\n", emu, (void*)R_RIP, (void*)R_RSP, unimp, emu->fork, emu->uc_link, emu->quit);
     if(unimp) {
-        emu->quit = 1;
+        //emu->quit = 1;
         UnimpOpcode(emu, is32bits);
         emit_signal(emu, SIGILL, (void*)R_RIP, 0);
     }
diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c
index 5433319d..00278e3b 100644
--- a/src/emu/x64run64.c
+++ b/src/emu/x64run64.c
@@ -792,12 +792,12 @@ uintptr_t Run64(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr)
                     break;

                 case 6:                 /* DIV Eb */

                     if(!EB->byte[0])

-                        emit_div0(emu, (void*)R_RIP, 0);

+                        emit_div0(emu, (void*)R_RIP, 1);

                     div8(emu, EB->byte[0]);

                     break;

                 case 7:                 /* IDIV Eb */

                     if(!EB->byte[0])

-                        emit_div0(emu, (void*)R_RIP, 0);

+                        emit_div0(emu, (void*)R_RIP, 1);

                     idiv8(emu, EB->byte[0]);

                     break;

             }

diff --git a/src/emu/x64run67_32.c b/src/emu/x64run67_32.c
index a1df3ba0..4b7afbea 100644
--- a/src/emu/x64run67_32.c
+++ b/src/emu/x64run67_32.c
@@ -66,6 +66,21 @@ uintptr_t Run67_32(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr)
         return Run6764_32(emu, rex, rep, _GS, addr);

         #endif

         break;

+    case 0x66:

+        opcode = F8;

+        switch(opcode) {

+

+            case 0x8D:                              /* LEA Gw,M */

+                nextop = F8;

+                GETGW;

+                tmp32u = GETEA32_16(0);

+                GW->word[0] = (uint16_t)tmp32u;

+                break;

+

+            default:

+                return 0;

+        }

+        break;

 

     case 0xE0:                      /* LOOPNZ */

         CHECK_FLAGS(emu);

diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index a2bc6020..1d80e76a 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -1701,6 +1701,14 @@ uintptr_t GetEA32(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t
     } else return (uintptr_t)GetECommon32O(emu, addr, rex, m, delta, 0);
 }
 
+uintptr_t GetEA32_16(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta)
+{
+    uint8_t m = v&0xC7;    // filter Ed
+    if(m>=0xC0) {
+         return (uintptr_t)&emu->regs[(m&0x07)+(rex.b<<3)];
+    } else return (uintptr_t)GetEw16off(emu, addr, rex, m, delta);
+}
+
 reg64_t* GetEdO(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
 {
     uint8_t m = v&0xC7;    // filter Ed
diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index e7416b19..35fa99bb 100644
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -115,6 +115,7 @@ static inline void PushExit_32(x64emu_t* emu)
 reg64_t* GetECommon(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta);
 reg64_t* GetECommonO(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t offset);
 reg64_t* GetECommon32O(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t offset);
+reg64_t* GetECommon32O_16(x64emu_t* emu, uintptr_t* addr, rex_t rex, uint8_t m, uint8_t delta, uintptr_t offset);
 reg64_t* GetEb(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
 reg64_t* TestEb(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
 reg64_t* GetEbO(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
@@ -129,6 +130,7 @@ reg64_t* TestEd8xw(x64test_t *test, int w, uintptr_t* addr, rex_t rex, uint8_t v
 reg64_t* TestEdt(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
 uintptr_t GetEA(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
 uintptr_t GetEA32(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
+uintptr_t GetEA32_16(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta);
 reg64_t* GetEdO(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
 reg64_t* TestEdO(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
 reg64_t* GetEd32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
diff --git a/src/libtools/signal32.c b/src/libtools/signal32.c
index 1ce4f822..3f6483fa 100644
--- a/src/libtools/signal32.c
+++ b/src/libtools/signal32.c
@@ -250,6 +250,61 @@ struct kernel_sigaction {
         unsigned long sa_mask;
         unsigned long sa_mask2;
 };
+
+typedef struct __attribute__((packed, aligned(4))) my_siginfo32_s
+{
+    int si_signo;
+    int si_errno;
+    int si_code;
+    union {
+	    int _pad[128/sizeof(int)-3];
+	struct {
+	    __pid_t __si_pid;
+	    __uid_t __si_uid;
+    } _kill;
+	struct {
+	    int si_tid;
+	    int __si_overrun;
+	    __sigval_t si_sigval;
+    } _timer;
+	struct {
+	    __pid_t __si_pid;
+	    __uid_t __si_uid;
+	    __sigval_t si_sigval;
+    } _rt;
+	struct {
+	    __pid_t __si_pid;
+	    __uid_t __si_uid;
+	    int __si_status;
+	    __clock_t __si_utime;
+	    __clock_t __si_stime;
+    } _sigchld;
+	struct {
+	    ptr_t __si_addr;
+	    __SI_SIGFAULT_ADDL
+	    short int __si_addr_lsb;
+	    union {
+            struct {
+                ptr_t _lower;
+                ptr_t _upper;
+            } _addr_bnd;
+            __uint32_t _pkey;
+        } _bounds;
+    } _sigfault;
+	struct
+	  {
+	    long int __si_band;
+	    int __si_fd;
+	  } _sigpoll;
+	struct
+	  {
+	    ptr_t _call_addr;
+	    int _syscall;
+	    unsigned int _arch;
+	  } _sigsys;
+    } _sifields;
+} my_siginfo32_t;
+
 #ifdef DYNAREC
 uintptr_t getX64Address(dynablock_t* db, uintptr_t arm_addr);
 #endif
@@ -400,7 +455,7 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
     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]));
+    printf_log(LOG_INFO/*LOG_DEBUG*/, "Sigactionhanlder32 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!
@@ -462,9 +517,11 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
     // setup stack frame
     frame -= 512+64+16*16;
     void* xstate = (void*)frame;
-    frame -= sizeof(siginfo_t);
-    siginfo_t* info2 = (siginfo_t*)frame;
-    memcpy(info2, info, sizeof(siginfo_t));
+    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);
     // try to fill some sigcontext....
     frame -= sizeof(i386_ucontext_t);
     i386_ucontext_t   *sigcontext = (i386_ucontext_t*)frame;
@@ -580,7 +637,9 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
                 //bad opcode
                 sigcontext->uc_mcontext.gregs[I386_ERR] = 0;
                 sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 13;
+                info2->si_code = 128;
                 info2->si_errno = 0;
+                info2->_sifields._sigfault.__si_addr = 0;
             } else if (info->si_errno==0xecec) {
                 // no excute bit on segment
                 sigcontext->uc_mcontext.gregs[I386_ERR] = 16;//(real_prot&PROT_READ)?16:1; // EXECUTE_FAULT & READ_FAULT
@@ -598,7 +657,7 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
             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)?14:13;
+                sigcontext->uc_mcontext.gregs[I386_TRAPNO] = (mmapped || ((uintptr_t)info->si_addr<0x10000))?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] = 0x0001;    // read error?
         }
@@ -610,8 +669,8 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
             // INT x
             uint8_t int_n = info->si_code;
             info2->si_errno = 0;
-            info2->si_code = info->si_code;
-            info2->si_addr = NULL;
+            info2->si_code = 128;
+            info2->_sifields._sigfault.__si_addr = 0;
             // some special cases...
             if(int_n==3) {
                 info2->si_signo = SIGTRAP;
@@ -624,9 +683,11 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
                 sigcontext->uc_mcontext.gregs[I386_ERR] = 0x02|(int_n<<3);
             } else {
                 sigcontext->uc_mcontext.gregs[I386_ERR] = 0x0a|(int_n<<3);
+                sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 13;
             }
-        } else if(info->si_errno==0xcafe) {
+        } else if(info->si_errno==0xcafe) { //divide by 0
             info2->si_errno = 0;
+            sigcontext->uc_mcontext.gregs[I386_ERR] = 0;
             sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 0;
             info2->si_signo = SIGFPE;
         }
@@ -635,15 +696,20 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
             sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 4;
         else
             sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 19;
-    } else if(sig==SIGILL)
+    } else if(sig==SIGILL) {
+        info2->si_code = 2;
         sigcontext->uc_mcontext.gregs[I386_TRAPNO] = 6;
-    else if(sig==SIGTRAP) {
-        info2->si_code = 128;
+    } else if(sig==SIGTRAP) {
+        if(info->si_code==1) {  //single step
+            info2->si_code = 2;
+            info2->_sifields._sigfault.__si_addr = sigcontext->uc_mcontext.gregs[I386_EIP];
+        } else
+            info2->si_code = 128;
         sigcontext->uc_mcontext.gregs[I386_TRAPNO] = info->si_code;
         sigcontext->uc_mcontext.gregs[I386_ERR] = 0;
     }
     //TODO: SIGABRT generate what?
-    printf_log((sig==10)?LOG_DEBUG:log_minimum, "Signal %d: si_addr=%p, TRAPNO=%d, ERR=%d, RIP=%p, prot:%x, mmaped:%d\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]), prot, mmapped);
+    printf_log((sig==10)?LOG_DEBUG:log_minimum, "Signal32 %d: si_addr=%p, TRAPNO=%d, ERR=%d, RIP=%p, prot:%x, mmaped:%d\n", sig, from_ptrv(info2->_sifields._sigfault.__si_addr), sigcontext->uc_mcontext.gregs[I386_TRAPNO], sigcontext->uc_mcontext.gregs[I386_ERR],from_ptrv(sigcontext->uc_mcontext.gregs[I386_EIP]), prot, mmapped);
     // call the signal handler
     i386_ucontext_t sigcontext_copy = *sigcontext;
     // save old value from emu
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index 4dcabee3..820ed1d3 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -1161,14 +1161,16 @@ void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo
                 //bad opcode
                 sigcontext->uc_mcontext.gregs[X64_ERR] = 0;
                 sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 13;
+                info2->si_code = 128;
                 info2->si_errno = 0;
+                info2->si_addr = NULL;
             } else if (info->si_errno==0xecec) {
                 // no excute bit on segment
-                sigcontext->uc_mcontext.gregs[X64_ERR] = 16;//(real_prot&PROT_READ)?16:1; // EXECUTE_FAULT & READ_FAULT
+                sigcontext->uc_mcontext.gregs[X64_ERR] = (real_prot&PROT_READ)?16:1; // EXECUTE_FAULT & READ_FAULT
                 sigcontext->uc_mcontext.gregs[X64_TRAPNO] = mmapped?14:13;
                 info2->si_errno = 0;
             }else {
-                sigcontext->uc_mcontext.gregs[X64_ERR] = mmapped?16:1;//(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_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] = mmapped?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;
             }
@@ -1179,7 +1181,7 @@ void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo
             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)?14:13;
+                sigcontext->uc_mcontext.gregs[X64_TRAPNO] = mmapped?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] = 0x0001;    // read error?
         }
@@ -1191,7 +1193,7 @@ void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo
             // INT x
             uint8_t int_n = info->si_code;
             info2->si_errno = 0;
-            info2->si_code = info->si_code;
+            info2->si_code = 128;
             info2->si_addr = NULL;
             // some special cases...
             if(int_n==3) {
@@ -1205,9 +1207,11 @@ void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo
                 sigcontext->uc_mcontext.gregs[X64_ERR] = 0x02|(int_n<<3);
             } else {
                 sigcontext->uc_mcontext.gregs[X64_ERR] = 0x0a|(int_n<<3);
+                sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 13;
             }
-        } else if(info->si_errno==0xcafe) {
+        } else if(info->si_errno==0xcafe) { // divide by 0
             info2->si_errno = 0;
+            sigcontext->uc_mcontext.gregs[X64_ERR] = 0;
             sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 0;
             info2->si_signo = SIGFPE;
         }
@@ -1216,10 +1220,15 @@ void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo
             sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 4;
         else
             sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 19;
-    } else if(sig==SIGILL)
+    } else if(sig==SIGILL) {
+        info2->si_code = 2;
         sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 6;
-    else if(sig==SIGTRAP) {
-        info2->si_code = 128;
+    } else if(sig==SIGTRAP) {
+        if(info->si_code==1) {  //single step
+            info2->si_code = 2;
+            info2->si_addr = (void*)sigcontext->uc_mcontext.gregs[X64_RIP];
+        } else
+            info2->si_code = 128;
         sigcontext->uc_mcontext.gregs[X64_TRAPNO] = info->si_code;
         sigcontext->uc_mcontext.gregs[X64_ERR] = 0;
     }