New test.
[mono.git] / mono / mini / exceptions-amd64.c
index b0db85e087dd74160f5843c28673c356cd0bbe61..7ab4d62976dfa514b8a3756e945be6b1127a62c1 100644 (file)
@@ -353,6 +353,7 @@ get_throw_trampoline (gboolean rethrow, guint32 *code_size, MonoJumpInfo **ji, g
 {
        guint8* start;
        guint8 *code;
+       GSList *unwind_ops;
 
        start = code = mono_global_codeman_reserve (64);
 
@@ -360,6 +361,8 @@ get_throw_trampoline (gboolean rethrow, guint32 *code_size, MonoJumpInfo **ji, g
 
        *ji = NULL;
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        amd64_mov_reg_reg (code, AMD64_R11, AMD64_RSP, 8);
 
        /* reverse order */
@@ -386,6 +389,8 @@ get_throw_trampoline (gboolean rethrow, guint32 *code_size, MonoJumpInfo **ji, g
        /* Exception */
        amd64_push_reg (code, AMD64_ARG_REG1);
 
+       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, (15 + 1) * sizeof (gpointer));
+
 #ifdef TARGET_WIN32
        /* align stack */
        amd64_push_imm (code, 0);
@@ -411,6 +416,8 @@ get_throw_trampoline (gboolean rethrow, guint32 *code_size, MonoJumpInfo **ji, g
 
        *code_size = code - start;
 
+       mono_save_trampoline_xdebug_info ("throw_exception_trampoline", start, code - start, unwind_ops);
+
        return start;
 }
 
@@ -691,7 +698,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
        return TRUE;
 }
 
-#ifdef MONO_ARCH_USE_SIGACTION
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
 static inline guint64*
 gregs_from_ucontext (ucontext_t *ctx)
 {
@@ -701,7 +708,7 @@ gregs_from_ucontext (ucontext_t *ctx)
 void
 mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
 {
-#ifdef MONO_ARCH_USE_SIGACTION
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
        ucontext_t *ctx = (ucontext_t*)sigctx;
 
     guint64 *gregs = gregs_from_ucontext (ctx);
@@ -719,6 +726,22 @@ mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
        mctx->r13 = gregs [REG_R13];
        mctx->r14 = gregs [REG_R14];
        mctx->r15 = gregs [REG_R15];
+#elif defined(MONO_ARCH_USE_SIGACTION)
+       ucontext_t *ctx = (ucontext_t*)sigctx;
+
+       mctx->rax = UCONTEXT_REG_RAX (ctx);
+       mctx->rbx = UCONTEXT_REG_RBX (ctx);
+       mctx->rcx = UCONTEXT_REG_RCX (ctx);
+       mctx->rdx = UCONTEXT_REG_RDX (ctx);
+       mctx->rbp = UCONTEXT_REG_RBP (ctx);
+       mctx->rsp = UCONTEXT_REG_RSP (ctx);
+       mctx->rsi = UCONTEXT_REG_RSI (ctx);
+       mctx->rdi = UCONTEXT_REG_RDI (ctx);
+       mctx->rip = UCONTEXT_REG_RIP (ctx);
+       mctx->r12 = UCONTEXT_REG_R12 (ctx);
+       mctx->r13 = UCONTEXT_REG_R13 (ctx);
+       mctx->r14 = UCONTEXT_REG_R14 (ctx);
+       mctx->r15 = UCONTEXT_REG_R15 (ctx);
 #else
        MonoContext *ctx = (MonoContext *)sigctx;
 
@@ -741,7 +764,7 @@ mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
 void
 mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
 {
-#ifdef MONO_ARCH_USE_SIGACTION
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
        ucontext_t *ctx = (ucontext_t*)sigctx;
 
     guint64 *gregs = gregs_from_ucontext (ctx);
@@ -759,6 +782,22 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
        gregs [REG_R13] = mctx->r13;
        gregs [REG_R14] = mctx->r14;
        gregs [REG_R15] = mctx->r15;
+#elif defined(MONO_ARCH_USE_SIGACTION)
+       ucontext_t *ctx = (ucontext_t*)sigctx;
+
+       UCONTEXT_REG_RAX (ctx) = mctx->rax;
+       UCONTEXT_REG_RBX (ctx) = mctx->rbx;
+       UCONTEXT_REG_RCX (ctx) = mctx->rcx;
+       UCONTEXT_REG_RDX (ctx) = mctx->rdx;
+       UCONTEXT_REG_RBP (ctx) = mctx->rbp;
+       UCONTEXT_REG_RSP (ctx) = mctx->rsp;
+       UCONTEXT_REG_RSI (ctx) = mctx->rsi;
+       UCONTEXT_REG_RDI (ctx) = mctx->rdi;
+       UCONTEXT_REG_RIP (ctx) = mctx->rip;
+       UCONTEXT_REG_R12 (ctx) = mctx->r12;
+       UCONTEXT_REG_R13 (ctx) = mctx->r13;
+       UCONTEXT_REG_R14 (ctx) = mctx->r14;
+       UCONTEXT_REG_R15 (ctx) = mctx->r15;
 #else
        MonoContext *ctx = (MonoContext *)sigctx;
 
@@ -781,14 +820,16 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
 gpointer
 mono_arch_ip_from_context (void *sigctx)
 {
-       
-#ifdef MONO_ARCH_USE_SIGACTION
-
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
        ucontext_t *ctx = (ucontext_t*)sigctx;
 
     guint64 *gregs = gregs_from_ucontext (ctx);
 
        return (gpointer)gregs [REG_RIP];
+#elif defined(MONO_ARCH_USE_SIGACTION)
+       ucontext_t *ctx = (ucontext_t*)sigctx;
+
+       return (gpointer)UCONTEXT_REG_RIP (ctx);
 #else
        MonoContext *ctx = sigctx;
        return (gpointer)ctx->rip;
@@ -845,7 +886,7 @@ altstack_handle_and_restore (void *sigctx, gpointer obj, gboolean stack_ovf)
 void
 mono_arch_handle_altstack_exception (void *sigctx, gpointer fault_addr, gboolean stack_ovf)
 {
-#ifdef MONO_ARCH_USE_SIGACTION
+#if defined(MONO_ARCH_USE_SIGACTION) && defined(UCONTEXT_GREGS)
        MonoException *exc = NULL;
        ucontext_t *ctx = (ucontext_t*)sigctx;
        guint64 *gregs = gregs_from_ucontext (ctx);