about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c2
-rw-r--r--src/dynarec/dynarec_native_functions.c6
-rw-r--r--src/dynarec/dynarec_native_functions.h1
-rw-r--r--src/emu/x87emu_private.c6
-rw-r--r--src/emu/x87emu_private.h1
-rw-r--r--src/include/emit_signals.h1
-rw-r--r--src/libtools/signal_private.h231
-rw-r--r--src/libtools/signals.c228
-rw-r--r--src/os/emit_signals_linux.c147
9 files changed, 395 insertions, 228 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 7b227e24..84f134fc 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -2672,13 +2672,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 MOV32w(x1, u8);
                 CALL(native_int, -1);
                 LOAD_XEMU_CALL(xRIP);
+                LOAD_XEMU_REM();
                 TABLE64(x3, addr); // expected return address
                 CMPSx_REG(xRIP, x3);
                 B_MARK(cNE);
                 LDRw_U12(w1, xEmu, offsetof(x64emu_t, quit));
                 CBZw_NEXT(w1);
                 MARK;
-                LOAD_XEMU_REM();
                 jump_to_epilog(dyn, 0, xRIP, ninst);
             } else if (u8==0x80) {
                 INST_NAME("32bits SYSCALL");
diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c
index a97e22c4..555b2eba 100644
--- a/src/dynarec/dynarec_native_functions.c
+++ b/src/dynarec/dynarec_native_functions.c
@@ -208,6 +208,12 @@ void native_int(x64emu_t* emu, int num)
     EmitInterruption(emu, num, (void*)R_RIP);
 }
 
+void native_wineint(x64emu_t* emu, int num)
+{
+    emu->test.test = 0;
+    EmitWineInt(emu, num, (void*)R_RIP);
+}
+
 void native_int3(x64emu_t* emu)
 {
     EmitSignal(emu, SIGTRAP, NULL, 3);
diff --git a/src/dynarec/dynarec_native_functions.h b/src/dynarec/dynarec_native_functions.h
index 0df058f2..eca8568f 100644
--- a/src/dynarec/dynarec_native_functions.h
+++ b/src/dynarec/dynarec_native_functions.h
@@ -57,6 +57,7 @@ void native_br(x64emu_t* emu);
 void native_priv(x64emu_t* emu);
 void native_int3(x64emu_t* emu);
 void native_int(x64emu_t* emu, int num);
+void native_wineint(x64emu_t* emu, int num);
 void native_div0(x64emu_t* emu);
 
 // Caches transformation (for loops) // Specific, need to be written par backend
diff --git a/src/emu/x87emu_private.c b/src/emu/x87emu_private.c
index 5d95a8e5..4936bf6c 100644
--- a/src/emu/x87emu_private.c
+++ b/src/emu/x87emu_private.c
@@ -476,10 +476,14 @@ void fpu_xsave(x64emu_t* emu, void* ed, int is32bits)
 
 void fpu_xrstor(x64emu_t* emu, void* ed, int is32bits)
 {
+    uint64_t mask = R_EAX | (((uint64_t)R_EDX)<<32);
+    return fpu_xrstor_mask(emu, ed, is32bits, mask);
+}
+
+void fpu_xrstor_mask(x64emu_t* emu, void* ed, int is32bits, uint64_t mask) {
     xsave64_t *p = (xsave64_t*)ed;
     xsaveheader_t *h = (xsaveheader_t*)(p+1);
     int compressed = (h->xcomp_bv>>63);
-    uint64_t mask = R_EAX | (((uint64_t)R_EDX)<<32);
     uint32_t rfbm = (0b111&mask);
     uint32_t to_restore = rfbm & h->xstate_bv;
     uint32_t to_init = rfbm & ~h->xstate_bv;
diff --git a/src/emu/x87emu_private.h b/src/emu/x87emu_private.h
index 74758acf..ff42d440 100644
--- a/src/emu/x87emu_private.h
+++ b/src/emu/x87emu_private.h
@@ -219,6 +219,7 @@ void fpu_fxrstor64(x64emu_t* emu, void* ed);
 void fpu_xsave(x64emu_t* emu, void* ed, int is32bits);
 void fpu_xsave_mask(x64emu_t* emu, void* ed, int is32bits, uint64_t mask);
 void fpu_xrstor(x64emu_t* emu, void* ed, int is32bits);
+void fpu_xrstor_mask(x64emu_t* emu, void* ed, int is32bits, uint64_t mask);
 
 uint32_t cvtf16_32(uint16_t v);
 uint16_t cvtf32_16(uint32_t v, uint8_t rounding);
diff --git a/src/include/emit_signals.h b/src/include/emit_signals.h
index 7bc4aa42..ed211fda 100644
--- a/src/include/emit_signals.h
+++ b/src/include/emit_signals.h
@@ -7,6 +7,7 @@ typedef struct x64emu_s x64emu_t;
 
 void EmitSignal(x64emu_t* emu, int sig, void* addr, int code);
 void EmitInterruption(x64emu_t* emu, int num, void* addr);
+void EmitWineInt(x64emu_t* emu, int num, void* addr);
 void EmitDiv0(x64emu_t* emu, void* addr, int code);
 void CheckExec(x64emu_t* emu, uintptr_t addr);
 
diff --git a/src/libtools/signal_private.h b/src/libtools/signal_private.h
new file mode 100644
index 00000000..6d261c39
--- /dev/null
+++ b/src/libtools/signal_private.h
@@ -0,0 +1,231 @@
+#ifndef __SIGNAL_PRIVATE_H__
+#define __SIGNAL_PRIVATE_H__
+
+typedef uint64_t x64_gregset_t[23];
+enum
+{
+  X64_R8 = 0,
+# define X64_R8         X64_R8
+  X64_R9,
+# define X64_R9         X64_R9
+  X64_R10,
+# define X64_R10        X64_R10
+  X64_R11,
+# define X64_R11        X64_R11
+  X64_R12,
+# define X64_R12        X64_R12
+  X64_R13,
+# define X64_R13        X64_R13
+  X64_R14,
+# define X64_R14        X64_R14
+  X64_R15,
+# define X64_R15        X64_R15
+  X64_RDI,
+# define X64_RDI        X64_RDI
+  X64_RSI,
+# define X64_RSI        X64_RSI
+  X64_RBP,
+# define X64_RBP        X64_RBP
+  X64_RBX,
+# define X64_RBX        X64_RBX
+  X64_RDX,
+# define X64_RDX        X64_RDX
+  X64_RAX,
+# define X64_RAX        X64_RAX
+  X64_RCX,
+# define X64_RCX        X64_RCX
+  X64_RSP,
+# define X64_RSP        X64_RSP
+  X64_RIP,
+# define X64_RIP        X64_RIP
+  X64_EFL,
+# define X64_EFL        X64_EFL
+  X64_CSGSFS,           /* Actually short cs, gs, fs, __pad0.  */
+# define X64_CSGSFS     X64_CSGSFS
+  X64_ERR,
+# define X64_ERR        X64_ERR
+  X64_TRAPNO,
+# define X64_TRAPNO     X64_TRAPNO
+  X64_OLDMASK,
+# define X64_OLDMASK    X64_OLDMASK
+  X64_CR2
+# define X64_CR2        X64_CR2
+};
+
+struct x64_fpreg
+{
+  uint64_t value;
+}__attribute__((packed));
+
+struct x64_fpxreg
+{
+  unsigned short significand[4];
+  unsigned short exponent;
+  unsigned short padding[3];
+}__attribute__((packed));
+
+struct x64_xmmreg
+{
+  uint32_t          element[4];
+}__attribute__((packed));
+
+struct x64_fpstate
+{
+  /* Regular FPU environment.  */
+  uint16_t          cw;
+  uint16_t          sw;
+  uint16_t          tw;
+  uint16_t          fop;
+  uint64_t          rip;
+  uint64_t          rdp;
+  uint32_t          mxcsr;
+  uint32_t          mxcsr_mask;
+  struct x64_fpreg  _st[8];
+  struct x64_xmmreg _xmm[16];
+  uint32_t          res[24];
+}__attribute__((packed));
+
+typedef struct x64_fpstate *x64_fpregset_t;
+
+typedef struct x64_stack_s
+{
+    void *ss_sp;
+    int ss_flags;
+    size_t ss_size;
+} x64_stack_t;
+
+struct sigcontext_x64
+{
+    uint64_t    r8;
+    uint64_t    r9;
+    uint64_t    r10;
+    uint64_t    r11;
+    uint64_t    r12;
+    uint64_t    r13;
+    uint64_t    r14;
+    uint64_t    r15;
+    uint64_t    di;
+    uint64_t    si;
+    uint64_t    bp;
+    uint64_t    bx;
+    uint64_t    dx;
+    uint64_t    ax;
+    uint64_t    cx;
+    uint64_t    sp;
+    uint64_t    ip;
+    uint64_t    flags;
+    uint64_t    cs;
+    uint64_t    gs;
+    uint64_t    fs;
+    uint64_t    ss;
+    uint64_t    err;
+    uint64_t    trapno;
+    uint64_t    oldmask;
+    uint64_t    cr2;
+    uint64_t    fpstate; /* Zero when no FPU/extended context */
+    uint64_t    reserved1[8];
+};
+
+struct x64_sigcontext
+{
+    uint64_t    r8;
+    uint64_t    r9;
+    uint64_t    r10;
+    uint64_t    r11;
+    uint64_t    r12;
+    uint64_t    r13;
+    uint64_t    r14;
+    uint64_t    r15;
+    uint64_t    rdi;
+    uint64_t    rsi;
+    uint64_t    rbp;
+    uint64_t    rbx;
+    uint64_t    rdx;
+    uint64_t    rax;
+    uint64_t    rcx;
+    uint64_t    rsp;
+    uint64_t    rip;
+    uint64_t    eflags;         /* RFLAGS */
+    uint16_t    cs;
+    uint16_t    gs;
+    uint16_t    fs;
+    union {
+        uint16_t    ss;     /* If UC_SIGCONTEXT_SS */
+        uint16_t    __pad0; /* Alias name for old (!UC_SIGCONTEXT_SS) user-space */
+    };
+    uint64_t    err;
+    uint64_t    trapno;
+    uint64_t    oldmask;
+    uint64_t    cr2;
+    struct x64_fpstate  *fpstate;       /* Zero when no FPU context */
+    uint64_t    reserved1[8];
+};
+
+struct x64_libc_fpstate
+{
+  /* 64-bit FXSAVE format.  */
+  uint16_t              cwd;
+  uint16_t              swd;
+  uint16_t              ftw;
+  uint16_t              fop;
+  uint64_t              rip;
+  uint64_t              rdp;
+  uint32_t              mxcsr;
+  uint32_t              mxcr_mask;
+  struct x64_fpxreg     st[8];
+  struct x64_xmmreg     xmm[16];
+  uint32_t              res1[24];
+};
+
+typedef struct x64_mcontext_s
+{
+    x64_gregset_t gregs;
+    struct x64_libc_fpstate *fpregs;
+    uint64_t    res[8];
+} x64_mcontext_t;
+
+// /!\ signal sig_set is different than glibc __sig_set
+#ifdef ANDROID
+#define _NSIG_WORDS (64 / (sizeof(unsigned long int)*8))
+#else
+#define _NSIG_WORDS (1024 / (sizeof(unsigned long int)*8))
+#endif
+
+typedef struct {
+    unsigned long int sig[_NSIG_WORDS];
+} x64_sigset_t;
+
+typedef struct x64_ucontext_s
+{
+    uint64_t                uc_flags;
+    struct x64_ucontext_s*  uc_link;
+    x64_stack_t             uc_stack;
+    x64_mcontext_t          uc_mcontext;
+    x64_sigset_t            uc_sigmask;
+    struct x64_libc_fpstate xstate;
+    #ifndef ANDROID
+    uint64_t                ssp[4];
+    #endif
+} x64_ucontext_t;
+
+typedef struct x64_sigframe_s {
+    uintptr_t       pretcode;   // pointer to retcode
+    int             sig;
+    x64_mcontext_t cpustate;
+    struct x64_libc_fpstate xstate;
+    uintptr_t       extramask[64-1];
+    char            retcode[8];
+} x64_sigframe_t;
+
+struct kernel_sigaction {
+        void (*k_sa_handler) (int);
+        unsigned long sa_flags;
+        void (*sa_restorer) (void);
+        unsigned long sa_mask;
+        unsigned long sa_mask2;
+};
+
+x64_stack_t* sigstack_getstack();
+uint64_t RunFunctionHandler(x64emu_t* emu, int* exit, int dynarec, x64_ucontext_t* sigcontext, uintptr_t fnc, int nargs, ...);
+
+#endif //__SIGNAL_PRIVATE_H__
\ No newline at end of file
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index a24a1c51..a2e56cf9 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -43,230 +43,7 @@
 #include "gdbjit.h"
 #endif
 
-
-typedef uint64_t x64_gregset_t[23];
-enum
-{
-  X64_R8 = 0,
-# define X64_R8         X64_R8
-  X64_R9,
-# define X64_R9         X64_R9
-  X64_R10,
-# define X64_R10        X64_R10
-  X64_R11,
-# define X64_R11        X64_R11
-  X64_R12,
-# define X64_R12        X64_R12
-  X64_R13,
-# define X64_R13        X64_R13
-  X64_R14,
-# define X64_R14        X64_R14
-  X64_R15,
-# define X64_R15        X64_R15
-  X64_RDI,
-# define X64_RDI        X64_RDI
-  X64_RSI,
-# define X64_RSI        X64_RSI
-  X64_RBP,
-# define X64_RBP        X64_RBP
-  X64_RBX,
-# define X64_RBX        X64_RBX
-  X64_RDX,
-# define X64_RDX        X64_RDX
-  X64_RAX,
-# define X64_RAX        X64_RAX
-  X64_RCX,
-# define X64_RCX        X64_RCX
-  X64_RSP,
-# define X64_RSP        X64_RSP
-  X64_RIP,
-# define X64_RIP        X64_RIP
-  X64_EFL,
-# define X64_EFL        X64_EFL
-  X64_CSGSFS,           /* Actually short cs, gs, fs, __pad0.  */
-# define X64_CSGSFS     X64_CSGSFS
-  X64_ERR,
-# define X64_ERR        X64_ERR
-  X64_TRAPNO,
-# define X64_TRAPNO     X64_TRAPNO
-  X64_OLDMASK,
-# define X64_OLDMASK    X64_OLDMASK
-  X64_CR2
-# define X64_CR2        X64_CR2
-};
-
-struct x64_fpreg
-{
-  uint64_t value;
-}__attribute__((packed));
-
-struct x64_fpxreg
-{
-  unsigned short significand[4];
-  unsigned short exponent;
-  unsigned short padding[3];
-}__attribute__((packed));
-
-struct x64_xmmreg
-{
-  uint32_t          element[4];
-}__attribute__((packed));
-
-struct x64_fpstate
-{
-  /* Regular FPU environment.  */
-  uint16_t          cw;
-  uint16_t          sw;
-  uint16_t          tw;
-  uint16_t          fop;
-  uint64_t          rip;
-  uint64_t          rdp;
-  uint32_t          mxcsr;
-  uint32_t          mxcsr_mask;
-  struct x64_fpreg  _st[8];
-  struct x64_xmmreg _xmm[16];
-  uint32_t          res[24];
-}__attribute__((packed));
-
-typedef struct x64_fpstate *x64_fpregset_t;
-
-typedef struct x64_stack_s
-{
-    void *ss_sp;
-    int ss_flags;
-    size_t ss_size;
-} x64_stack_t;
-
-struct sigcontext_x64
-{
-    uint64_t    r8;
-    uint64_t    r9;
-    uint64_t    r10;
-    uint64_t    r11;
-    uint64_t    r12;
-    uint64_t    r13;
-    uint64_t    r14;
-    uint64_t    r15;
-    uint64_t    di;
-    uint64_t    si;
-    uint64_t    bp;
-    uint64_t    bx;
-    uint64_t    dx;
-    uint64_t    ax;
-    uint64_t    cx;
-    uint64_t    sp;
-    uint64_t    ip;
-    uint64_t    flags;
-    uint64_t    cs;
-    uint64_t    gs;
-    uint64_t    fs;
-    uint64_t    ss;
-    uint64_t    err;
-    uint64_t    trapno;
-    uint64_t    oldmask;
-    uint64_t    cr2;
-    uint64_t    fpstate; /* Zero when no FPU/extended context */
-    uint64_t    reserved1[8];
-};
-
-struct x64_sigcontext
-{
-    uint64_t    r8;
-    uint64_t    r9;
-    uint64_t    r10;
-    uint64_t    r11;
-    uint64_t    r12;
-    uint64_t    r13;
-    uint64_t    r14;
-    uint64_t    r15;
-    uint64_t    rdi;
-    uint64_t    rsi;
-    uint64_t    rbp;
-    uint64_t    rbx;
-    uint64_t    rdx;
-    uint64_t    rax;
-    uint64_t    rcx;
-    uint64_t    rsp;
-    uint64_t    rip;
-    uint64_t    eflags;         /* RFLAGS */
-    uint16_t    cs;
-    uint16_t    gs;
-    uint16_t    fs;
-    union {
-        uint16_t    ss;     /* If UC_SIGCONTEXT_SS */
-        uint16_t    __pad0; /* Alias name for old (!UC_SIGCONTEXT_SS) user-space */
-    };
-    uint64_t    err;
-    uint64_t    trapno;
-    uint64_t    oldmask;
-    uint64_t    cr2;
-    struct x64_fpstate  *fpstate;       /* Zero when no FPU context */
-    uint64_t    reserved1[8];
-};
-
-struct x64_libc_fpstate
-{
-  /* 64-bit FXSAVE format.  */
-  uint16_t              cwd;
-  uint16_t              swd;
-  uint16_t              ftw;
-  uint16_t              fop;
-  uint64_t              rip;
-  uint64_t              rdp;
-  uint32_t              mxcsr;
-  uint32_t              mxcr_mask;
-  struct x64_fpxreg     st[8];
-  struct x64_xmmreg     xmm[16];
-  uint32_t              res1[24];
-};
-
-typedef struct x64_mcontext_s
-{
-    x64_gregset_t gregs;
-    struct x64_libc_fpstate *fpregs;
-    uint64_t    res[8];
-} x64_mcontext_t;
-
-// /!\ signal sig_set is different than glibc __sig_set
-#ifdef ANDROID
-#define _NSIG_WORDS (64 / (sizeof(unsigned long int)*8))
-#else
-#define _NSIG_WORDS (1024 / (sizeof(unsigned long int)*8))
-#endif
-
-typedef struct {
-    unsigned long int sig[_NSIG_WORDS];
-} x64_sigset_t;
-
-typedef struct x64_ucontext_s
-{
-    uint64_t                uc_flags;
-    struct x64_ucontext_s*  uc_link;
-    x64_stack_t             uc_stack;
-    x64_mcontext_t          uc_mcontext;
-    x64_sigset_t            uc_sigmask;
-    struct x64_libc_fpstate xstate;
-    #ifndef ANDROID
-    uint64_t                ssp[4];
-    #endif
-} x64_ucontext_t;
-
-typedef struct x64_sigframe_s {
-    uintptr_t       pretcode;   // pointer to retcode
-    int             sig;
-    x64_mcontext_t cpustate;
-    struct x64_libc_fpstate xstate;
-    uintptr_t       extramask[64-1];
-    char            retcode[8];
-} x64_sigframe_t;
-
-struct kernel_sigaction {
-        void (*k_sa_handler) (int);
-        unsigned long sa_flags;
-        void (*sa_restorer) (void);
-        unsigned long sa_mask;
-        unsigned long sa_mask2;
-};
+#include "signal_private.h"
 
 static void sigstack_destroy(void* p)
 {
@@ -327,7 +104,8 @@ uint64_t RunFunctionHandler(x64emu_t* emu, int* exit, int dynarec, x64_ucontext_
 #ifndef USE_CUSTOM_MEM
     // because a signal can interupt a malloc-like function
     // Dynarec cannot be used in signal handling unless custom malloc is used
-    dynarec = 0;
+    if(dynarec==1)
+        dynarec = 0;
 #endif
     if(!emu)
         emu = thread_get_emu();
diff --git a/src/os/emit_signals_linux.c b/src/os/emit_signals_linux.c
index e5cc6b14..39d209f7 100644
--- a/src/os/emit_signals_linux.c
+++ b/src/os/emit_signals_linux.c
@@ -1,21 +1,28 @@
 #include <errno.h>
 #include <signal.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
 #include <sys/mman.h>
+#include <ucontext.h>
+#include <setjmp.h>
+#include <signal.h>
 #ifndef ANDROID
 #include <execinfo.h>
 #endif
 
+
 #include "box64context.h"
 #include "custommem.h"
 #include "debug.h"
 #include "elfloader.h"
 #include "emit_signals.h"
 #include "emu/x64emu_private.h"
+#include "emu/x87emu_private.h"
 #include "regs.h"
-#include "signals.h"
 #include "x64emu.h"
+#include "signals.h"
+#include "libtools/signal_private.h"
 
 void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db, uintptr_t x64pc);
 void EmitSignal(x64emu_t* emu, int sig, void* addr, int code)
@@ -142,3 +149,141 @@ void EmitDiv0(x64emu_t* emu, void* addr, int code)
     }
     my_sigactionhandler_oldcode(emu, SIGSEGV, 0, &info, NULL, NULL, NULL, R_RIP);
 }
+
+void EmitWineInt(x64emu_t* emu, int num, void* addr)
+{
+    siginfo_t info = { 0 };
+    info.si_signo = SIGSEGV;
+    info.si_errno = 0xdead;
+    info.si_code = num;
+    info.si_addr = NULL; // addr;
+    const char* x64name = NULL;
+    const char* elfname = NULL;
+    if (BOX64ENV(log) > LOG_INFO || BOX64ENV(dynarec_dump) || BOX64ENV(showsegv)) {
+        x64name = getAddrFunctionName(R_RIP);
+        elfheader_t* elf = FindElfAddress(my_context, R_RIP);
+        if (elf)
+            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);
+    }
+    if(box64_is32bits)
+        my_sigactionhandler_oldcode(emu, SIGSEGV, 0, &info, NULL, NULL, NULL, R_RIP);
+    else {
+        uintptr_t frame = R_RSP;
+        int sig = SIGSEGV;
+        // stack tracking
+        x64_stack_t *new_ss = my_context->onstack[sig]?sigstack_getstack():NULL;
+        int used_stack = 0;
+        if(new_ss) {
+            if(new_ss->ss_flags == SS_ONSTACK) { // already using it!
+                frame = ((uintptr_t)emu->regs[_SP].q[0] - 128) & ~0x0f;
+            } else {
+                frame = (uintptr_t)(((uintptr_t)new_ss->ss_sp + new_ss->ss_size - 16) & ~0x0f);
+                used_stack = 1;
+                new_ss->ss_flags = SS_ONSTACK;
+            }
+        } else {
+            frame -= 0x200; // redzone
+        }
+
+        // TODO: do I need to really setup 2 stack frame? That doesn't seems right!
+        // 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));
+        // try to fill some sigcontext....
+        frame -= sizeof(x64_ucontext_t);
+        x64_ucontext_t   *sigcontext = (x64_ucontext_t*)frame;
+        // get general register
+        sigcontext->uc_mcontext.gregs[X64_R8] = R_R8;
+        sigcontext->uc_mcontext.gregs[X64_R9] = R_R9;
+        sigcontext->uc_mcontext.gregs[X64_R10] = R_R10;
+        sigcontext->uc_mcontext.gregs[X64_R11] = R_R11;
+        sigcontext->uc_mcontext.gregs[X64_R12] = R_R12;
+        sigcontext->uc_mcontext.gregs[X64_R13] = R_R13;
+        sigcontext->uc_mcontext.gregs[X64_R14] = R_R14;
+        sigcontext->uc_mcontext.gregs[X64_R15] = R_R15;
+        sigcontext->uc_mcontext.gregs[X64_RAX] = R_RAX;
+        sigcontext->uc_mcontext.gregs[X64_RCX] = R_RCX;
+        sigcontext->uc_mcontext.gregs[X64_RDX] = R_RDX;
+        sigcontext->uc_mcontext.gregs[X64_RDI] = R_RDI;
+        sigcontext->uc_mcontext.gregs[X64_RSI] = R_RSI;
+        sigcontext->uc_mcontext.gregs[X64_RBP] = R_RBP;
+        sigcontext->uc_mcontext.gregs[X64_RSP] = R_RSP;
+        sigcontext->uc_mcontext.gregs[X64_RBX] = R_RBX;
+        sigcontext->uc_mcontext.gregs[X64_RIP] = R_RIP;
+        // flags
+        ResetFlags(emu);
+        sigcontext->uc_mcontext.gregs[X64_EFL] = emu->eflags.x64;
+        // get segments
+        sigcontext->uc_mcontext.gregs[X64_CSGSFS] = ((uint64_t)(R_CS)) | (((uint64_t)(R_GS))<<16) | (((uint64_t)(R_FS))<<32);
+        if(R_CS==0x23) {
+            // trucate regs to 32bits, just in case
+            #define GO(R)   sigcontext->uc_mcontext.gregs[X64_R##R]&=0xFFFFFFFF
+            GO(AX);
+            GO(CX);
+            GO(DX);
+            GO(DI);
+            GO(SI);
+            GO(BP);
+            GO(SP);
+            GO(BX);
+            GO(IP);
+            #undef GO
+        }
+        // get FloatPoint status
+        sigcontext->uc_mcontext.fpregs = xstate;//(struct x64_libc_fpstate*)&sigcontext->xstate;
+        fpu_xsave_mask(emu, xstate, 0, 0b111);
+        memcpy(&sigcontext->xstate, xstate, sizeof(sigcontext->xstate));
+        ((struct x64_fpstate*)xstate)->res[12] = 0x46505853;   // magic number to signal an XSTATE type of fpregs
+        ((struct x64_fpstate*)xstate)->res[13] = 0; // offset to xstate after this?
+        // get signal mask
+        if(new_ss) {
+            sigcontext->uc_stack.ss_sp = new_ss->ss_sp;
+            sigcontext->uc_stack.ss_size = new_ss->ss_size;
+            sigcontext->uc_stack.ss_flags = new_ss->ss_flags;
+        } else
+            sigcontext->uc_stack.ss_flags = SS_DISABLE;        
+        // prepare info2
+        info2->si_errno = 0;
+        info2->si_code = 128;
+        info2->si_addr = NULL;
+        sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 13;
+        sigcontext->uc_mcontext.gregs[X64_ERR] = 0x02|(num<<3);
+        int exits = 0;
+        int ret;
+        ret = RunFunctionHandler(emu, &exits, 2, sigcontext, my_context->signals[info2->si_signo], 3, info2->si_signo, info2, sigcontext);
+        if(used_stack)  // release stack
+            new_ss->ss_flags = 0;
+        // restore values
+        // general regs
+        R_R8 = sigcontext->uc_mcontext.gregs[X64_R8];
+        R_R9 = sigcontext->uc_mcontext.gregs[X64_R9];
+        R_R10 = sigcontext->uc_mcontext.gregs[X64_R10];
+        R_R11 = sigcontext->uc_mcontext.gregs[X64_R11];
+        R_R12 = sigcontext->uc_mcontext.gregs[X64_R12];
+        R_R13 = sigcontext->uc_mcontext.gregs[X64_R13];
+        R_R14 = sigcontext->uc_mcontext.gregs[X64_R14];
+        R_R15 = sigcontext->uc_mcontext.gregs[X64_R15];
+        R_RAX = sigcontext->uc_mcontext.gregs[X64_RAX];
+        R_RCX = sigcontext->uc_mcontext.gregs[X64_RCX];
+        R_RDX = sigcontext->uc_mcontext.gregs[X64_RDX];
+        R_RDI = sigcontext->uc_mcontext.gregs[X64_RDI];
+        R_RSI = sigcontext->uc_mcontext.gregs[X64_RSI];
+        R_RBP = sigcontext->uc_mcontext.gregs[X64_RBP];
+        R_RSP = sigcontext->uc_mcontext.gregs[X64_RSP];
+        R_RBX = sigcontext->uc_mcontext.gregs[X64_RBX];
+        R_RIP = sigcontext->uc_mcontext.gregs[X64_RIP];
+        // flags
+        emu->eflags.x64 = sigcontext->uc_mcontext.gregs[X64_EFL];
+        // get segments
+        R_CS = sigcontext->uc_mcontext.gregs[X64_CSGSFS]&0xffff;
+        R_GS = (sigcontext->uc_mcontext.gregs[X64_CSGSFS]>>16)&0xffff;
+        R_FS = (sigcontext->uc_mcontext.gregs[X64_CSGSFS]>>32)&0xffff;
+        // fpu
+        fpu_xrstor_mask(emu, xstate, 0, 0b111);
+    }
+}
+