2005-03-31 Zoltan Varga <vargaz@freemail.hu>
authorZoltan Varga <vargaz@gmail.com>
Thu, 31 Mar 2005 13:21:26 +0000 (13:21 -0000)
committerZoltan Varga <vargaz@gmail.com>
Thu, 31 Mar 2005 13:21:26 +0000 (13:21 -0000)
* mini.h (mono_arch_sigctx_to_monoctx): New arch-specific function.

* mini.h (mono_arch_monoctx_to_sigctx): New arch-specific function.

* mini.c: sigaltstack support requires MONO_ARCH_USE_SIGACTION.

* mini-x86.h mini-x86.c exceptions-x86.c: Add support for
MONO_ARCH_USE_SIGACTION. Fixes #74252.

* mini-x86.h: Enable MONO_ARCH_USE_SIGACTION on linux.

* mini-x86.c: Fix up stack overflow handling.

* exceptions.cs: Add new regression test.

svn path=/trunk/mono/; revision=42421

mono/mini/ChangeLog
mono/mini/exceptions-x86.c
mono/mini/exceptions.cs
mono/mini/mini-x86.c
mono/mini/mini-x86.h
mono/mini/mini.c
mono/mini/mini.h

index 965d8aa98dc4ad9f082425fd5e22f0e72268df34..9877c69c8f89de454da7e6298c6c7fa8c4aa9690 100644 (file)
@@ -1,3 +1,20 @@
+2005-03-31  Zoltan Varga  <vargaz@freemail.hu>
+
+       * mini.h (mono_arch_sigctx_to_monoctx): New arch-specific function.
+
+       * mini.h (mono_arch_monoctx_to_sigctx): New arch-specific function.
+
+       * mini.c: sigaltstack support requires MONO_ARCH_USE_SIGACTION.
+
+       * mini-x86.h mini-x86.c exceptions-x86.c: Add support for 
+       MONO_ARCH_USE_SIGACTION. Fixes #74252.
+
+       * mini-x86.h: Enable MONO_ARCH_USE_SIGACTION on linux.
+
+       * mini-x86.c: Fix up stack overflow handling.   
+
+       * exceptions.cs: Add new regression test.
+
 2005-03-30  Zoltan Varga  <vargaz@freemail.hu>
 
        * mini-x86.c (mono_arch_emit_prolog): Adjust stack after calls to
index b10c9d80fe6c45775df5957fd69f79ae146837b6..845d57da0daf575e061c3b7bd0ca9f25a089ead8 100644 (file)
@@ -139,7 +139,7 @@ mono_arch_get_restore_context (void)
        if (start)
                return start;
 
-       /* restore_contect (struct sigcontext *ctx) */
+       /* restore_contect (MonoContext *ctx) */
        /* we do not restore X86_EAX, X86_EDX */
 
        start = code = mono_global_codeman_reserve (128);
@@ -148,17 +148,17 @@ mono_arch_get_restore_context (void)
        x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4);
 
        /* get return address, stored in EDX */
-       x86_mov_reg_membase (code, X86_EDX, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_EIP), 4);
+       x86_mov_reg_membase (code, X86_EDX, X86_EAX,  G_STRUCT_OFFSET (MonoContext, eip), 4);
        /* restore EBX */
-       x86_mov_reg_membase (code, X86_EBX, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_EBX), 4);
+       x86_mov_reg_membase (code, X86_EBX, X86_EAX,  G_STRUCT_OFFSET (MonoContext, ebx), 4);
        /* restore EDI */
-       x86_mov_reg_membase (code, X86_EDI, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_EDI), 4);
+       x86_mov_reg_membase (code, X86_EDI, X86_EAX,  G_STRUCT_OFFSET (MonoContext, edi), 4);
        /* restore ESI */
-       x86_mov_reg_membase (code, X86_ESI, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_ESI), 4);
+       x86_mov_reg_membase (code, X86_ESI, X86_EAX,  G_STRUCT_OFFSET (MonoContext, esi), 4);
        /* restore ESP */
-       x86_mov_reg_membase (code, X86_ESP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_ESP), 4);
+       x86_mov_reg_membase (code, X86_ESP, X86_EAX,  G_STRUCT_OFFSET (MonoContext, esp), 4);
        /* restore EBP */
-       x86_mov_reg_membase (code, X86_EBP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_EBP), 4);
+       x86_mov_reg_membase (code, X86_EBP, X86_EAX,  G_STRUCT_OFFSET (MonoContext, ebp), 4);
 
        /* jump to the saved IP */
        x86_jump_reg (code, X86_EDX);
@@ -184,7 +184,7 @@ mono_arch_get_call_filter (void)
                return start;
 
        inited = 1;
-       /* call_filter (struct sigcontext *ctx, unsigned long eip) */
+       /* call_filter (MonoContext *ctx, unsigned long eip) */
        start = code = mono_global_codeman_reserve (64);
 
        x86_push_reg (code, X86_EBP);
@@ -201,11 +201,11 @@ mono_arch_get_call_filter (void)
        x86_push_reg (code, X86_EBP);
 
        /* set new EBP */
-       x86_mov_reg_membase (code, X86_EBP, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_EBP), 4);
+       x86_mov_reg_membase (code, X86_EBP, X86_EAX,  G_STRUCT_OFFSET (MonoContext, ebp), 4);
        /* restore registers used by global register allocation (EBX & ESI) */
-       x86_mov_reg_membase (code, X86_EBX, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_EBX), 4);
-       x86_mov_reg_membase (code, X86_ESI, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_ESI), 4);
-       x86_mov_reg_membase (code, X86_EDI, X86_EAX,  G_STRUCT_OFFSET (struct sigcontext, SC_EDI), 4);
+       x86_mov_reg_membase (code, X86_EBX, X86_EAX,  G_STRUCT_OFFSET (MonoContext, ebx), 4);
+       x86_mov_reg_membase (code, X86_ESI, X86_EAX,  G_STRUCT_OFFSET (MonoContext, esi), 4);
+       x86_mov_reg_membase (code, X86_EDI, X86_EAX,  G_STRUCT_OFFSET (MonoContext, edi), 4);
 
        /* call the handler */
        x86_call_reg (code, X86_ECX);
@@ -229,22 +229,22 @@ throw_exception (unsigned long eax, unsigned long ecx, unsigned long edx, unsign
                 unsigned long esi, unsigned long edi, unsigned long ebp, MonoObject *exc,
                 unsigned long eip,  unsigned long esp, gboolean rethrow)
 {
-       static void (*restore_context) (struct sigcontext *);
-       struct sigcontext ctx;
+       static void (*restore_context) (MonoContext *);
+       MonoContext ctx;
 
        if (!restore_context)
                restore_context = mono_arch_get_restore_context ();
 
        /* Pop argument and return address */
-       ctx.SC_ESP = esp + (2 * sizeof (gpointer));
-       ctx.SC_EIP = eip;
-       ctx.SC_EBP = ebp;
-       ctx.SC_EDI = edi;
-       ctx.SC_ESI = esi;
-       ctx.SC_EBX = ebx;
-       ctx.SC_EDX = edx;
-       ctx.SC_ECX = ecx;
-       ctx.SC_EAX = eax;
+       ctx.esp = esp + (2 * sizeof (gpointer));
+       ctx.eip = eip;
+       ctx.ebp = ebp;
+       ctx.edi = edi;
+       ctx.esi = esi;
+       ctx.ebx = ebx;
+       ctx.edx = edx;
+       ctx.ecx = ecx;
+       ctx.eax = eax;
 
        if (mono_debugger_throw_exception ((gpointer)(eip - 5), (gpointer)esp, exc)) {
                /*
@@ -252,14 +252,14 @@ throw_exception (unsigned long eax, unsigned long ecx, unsigned long edx, unsign
                 * By the time we get here, it already inserted a breakpoint on
                 * eip - 5 (which is the address of the call).
                 */
-               ctx.SC_EIP = eip - 5;
-               ctx.SC_ESP = esp + sizeof (gpointer);
+               ctx.eip = eip - 5;
+               ctx.esp = esp + sizeof (gpointer);
                restore_context (&ctx);
                g_assert_not_reached ();
        }
 
        /* adjust eip so that it point into the call instruction */
-       ctx.SC_EIP -= 1;
+       ctx.eip -= 1;
 
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
@@ -472,24 +472,24 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                         * code, since otherwise the lmf was already popped of the stack.
                         */
                        if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) {
-                               new_ctx->SC_ESI = (*lmf)->esi;
-                               new_ctx->SC_EDI = (*lmf)->edi;
-                               new_ctx->SC_EBX = (*lmf)->ebx;
+                               new_ctx->esi = (*lmf)->esi;
+                               new_ctx->edi = (*lmf)->edi;
+                               new_ctx->ebx = (*lmf)->ebx;
                        }
                }
                else {
                        offset = -1;
                        /* restore caller saved registers */
                        if (ji->used_regs & X86_EBX_MASK) {
-                               new_ctx->SC_EBX = *((int *)ctx->SC_EBP + offset);
+                               new_ctx->ebx = *((int *)ctx->ebp + offset);
                                offset--;
                        }
                        if (ji->used_regs & X86_EDI_MASK) {
-                               new_ctx->SC_EDI = *((int *)ctx->SC_EBP + offset);
+                               new_ctx->edi = *((int *)ctx->ebp + offset);
                                offset--;
                        }
                        if (ji->used_regs & X86_ESI_MASK) {
-                               new_ctx->SC_ESI = *((int *)ctx->SC_EBP + offset);
+                               new_ctx->esi = *((int *)ctx->ebp + offset);
                        }
                }
 
@@ -499,17 +499,17 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                }
 
                /* Pop EBP and the return address */
-               new_ctx->SC_ESP = ctx->SC_EBP + (2 * sizeof (gpointer));
+               new_ctx->esp = ctx->SC_EBP + (2 * sizeof (gpointer));
                /* we substract 1, so that the IP points into the call instruction */
-               new_ctx->SC_EIP = *((int *)ctx->SC_EBP + 1) - 1;
-               new_ctx->SC_EBP = *((int *)ctx->SC_EBP);
+               new_ctx->eip = *((int *)ctx->ebp + 1) - 1;
+               new_ctx->ebp = *((int *)ctx->ebp);
 
                /* Pop arguments off the stack */
                {
                        MonoJitArgumentInfo *arg_info = g_newa (MonoJitArgumentInfo, mono_method_signature (ji->method)->param_count + 1);
 
                        guint32 stack_to_pop = mono_arch_get_argument_info (mono_method_signature (ji->method), mono_method_signature (ji->method)->param_count, arg_info);
-                       new_ctx->SC_ESP += stack_to_pop;
+                       new_ctx->esp += stack_to_pop;
                }
 
                return ji;
@@ -526,14 +526,14 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                        res->method = (*lmf)->method;
                }
 
-               new_ctx->SC_ESI = (*lmf)->esi;
-               new_ctx->SC_EDI = (*lmf)->edi;
-               new_ctx->SC_EBX = (*lmf)->ebx;
-               new_ctx->SC_EBP = (*lmf)->ebp;
-               new_ctx->SC_EIP = (*lmf)->eip;
+               new_ctx->esi = (*lmf)->esi;
+               new_ctx->edi = (*lmf)->edi;
+               new_ctx->ebx = (*lmf)->ebx;
+               new_ctx->ebp = (*lmf)->ebp;
+               new_ctx->eip = (*lmf)->eip;
                /* the lmf is always stored on the stack, so the following
                 * expression points to a stack location which can be used as ESP */
-               new_ctx->SC_ESP = (unsigned long)&((*lmf)->eip);
+               new_ctx->esp = (unsigned long)&((*lmf)->eip);
 
                *lmf = (*lmf)->previous_lmf;
 
@@ -543,22 +543,68 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
        return NULL;
 }
 
-/**
- * mono_arch_handle_exception:
- *
- * @ctx: saved processor state
- * @obj: the exception object
- */
-gboolean
-mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
+void
+mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
 {
-       return mono_handle_exception (sigctx, obj, mono_arch_ip_from_context (sigctx), test_only);
+       ucontext_t *ctx = (ucontext_t*)sigctx;
+       
+#ifdef MONO_ARCH_USE_SIGACTION
+       mctx->eax = ctx->uc_mcontext.gregs [REG_EAX];
+       mctx->ebx = ctx->uc_mcontext.gregs [REG_EBX];
+       mctx->ecx = ctx->uc_mcontext.gregs [REG_ECX];
+       mctx->edx = ctx->uc_mcontext.gregs [REG_EDX];
+       mctx->ebp = ctx->uc_mcontext.gregs [REG_EBP];
+       mctx->esp = ctx->uc_mcontext.gregs [REG_ESP];
+       mctx->esi = ctx->uc_mcontext.gregs [REG_ESI];
+       mctx->edi = ctx->uc_mcontext.gregs [REG_EDI];
+       mctx->eip = ctx->uc_mcontext.gregs [REG_EIP];
+#else
+       memcpy (mctx, sigctx, sizeof (MonoContext));
+#endif
 }
 
+void
+mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
+{
+       ucontext_t *ctx = (ucontext_t*)sigctx;
+
+#ifdef MONO_ARCH_USE_SIGACTION
+       ctx->uc_mcontext.gregs [REG_EAX] = mctx->eax;
+       ctx->uc_mcontext.gregs [REG_EBX] = mctx->ebx;
+       ctx->uc_mcontext.gregs [REG_ECX] = mctx->ecx;
+       ctx->uc_mcontext.gregs [REG_EDX] = mctx->edx;
+       ctx->uc_mcontext.gregs [REG_EBP] = mctx->ebp;
+       ctx->uc_mcontext.gregs [REG_ESP] = mctx->esp;
+       ctx->uc_mcontext.gregs [REG_ESI] = mctx->esi;
+       ctx->uc_mcontext.gregs [REG_EDI] = mctx->edi;
+       ctx->uc_mcontext.gregs [REG_EIP] = mctx->eip;
+#else
+       memcpy (ctx, mctx, sizeof (MonoContext));
+#endif
+}      
+
 gpointer
 mono_arch_ip_from_context (void *sigctx)
 {
+#ifdef MONO_ARCH_USE_SIGACTION
+       ucontext_t *ctx = (ucontext_t*)sigctx;
+       return (gpointer)ctx->uc_mcontext.gregs [REG_EIP];
+#else
        struct sigcontext *ctx = sigctx;
        return (gpointer)ctx->SC_EIP;
+#endif 
 }
 
+gboolean
+mono_arch_handle_exception (void *sigctx, gpointer obj, gboolean test_only)
+{
+       MonoContext mctx;
+
+       mono_arch_sigctx_to_monoctx (sigctx, &mctx);
+
+       mono_handle_exception (&mctx, obj, (gpointer)mctx.eip, test_only);
+
+       mono_arch_monoctx_to_sigctx (&mctx, sigctx);
+
+       return TRUE;
+}
index 0f42f004fc6058c884855dabf1c79f533164300a..dd9dbb07df37dc1f5df65724fef453a61c9e0a13 100644 (file)
@@ -2197,6 +2197,28 @@ class Tests {
                        }
                }
                return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
-       }               
+       }
+
+       static int test_0_regress_73242 () {
+               int [] arr = new int [10];
+               for (int i = 0; i < 10; ++i)
+                       arr [i] = 0;
+               try {
+                       throw new Exception ();
+               }
+               catch {
+               }
+               return 0;
+    }
+
+       static int test_0_nullref () {
+               try {
+                       Array foo = null;
+                       foo.Clone();
+               } catch (NullReferenceException e) {
+                       return 0;
+               }
+               return 1;
+       }
 }
 
index 116c8765f89d2217a36fe0f3c63f5cc50a7e454c..6a7a178c71228aee5e6835d1d468380e9c9d7090 100644 (file)
 #include <string.h>
 #include <math.h>
 
+#ifndef PLATFORM_WIN32
+#include <unistd.h>
+#include <sys/mman.h>
+#endif
+
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/threads.h>
@@ -576,10 +581,12 @@ mono_arch_cpu_optimizazions (guint32 *exclude_mask)
 gboolean
 mono_arch_is_int_overflow (void *sigctx, void *info)
 {
-       struct sigcontext *ctx = (struct sigcontext*)sigctx;
+       MonoContext ctx;
        guint8* ip;
 
-       ip = (guint8*)ctx->SC_EIP;
+       mono_arch_sigctx_to_monoctx (sigctx, &ctx);
+
+       ip = (guint8*)ctx.eip;
 
        if ((ip [0] == 0xf7) && (x86_modrm_mod (ip [1]) == 0x3) && (x86_modrm_reg (ip [1]) == 0x7)) {
                gint32 reg;
@@ -587,10 +594,10 @@ mono_arch_is_int_overflow (void *sigctx, void *info)
                /* idiv REG */
                switch (x86_modrm_rm (ip [1])) {
                case X86_ECX:
-                       reg = ctx->SC_ECX;
+                       reg = ctx.ecx;
                        break;
                case X86_EBX:
-                       reg = ctx->SC_EBX;
+                       reg = ctx.ebx;
                        break;
                default:
                        g_assert_not_reached ();
@@ -4657,6 +4664,66 @@ mono_arch_flush_register_windows (void)
 {
 }
 
+#ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
+
+static void
+setup_stack (MonoJitTlsData *tls)
+{
+       pthread_t self = pthread_self();
+       pthread_attr_t attr;
+       size_t stsize = 0;
+       struct sigaltstack sa;
+       guint8 *staddr = NULL;
+       guint8 *current = (guint8*)&staddr;
+
+       if (mono_running_on_valgrind ())
+               return;
+
+       /* Determine stack boundaries */
+#ifdef HAVE_PTHREAD_GETATTR_NP
+       pthread_getattr_np( self, &attr );
+#else
+#ifdef HAVE_PTHREAD_ATTR_GET_NP
+       pthread_attr_get_np( self, &attr );
+#elif defined(sun)
+       pthread_attr_init( &attr );
+       pthread_attr_getstacksize( &attr, &stsize );
+#else
+#error "Not implemented"
+#endif
+#endif
+#ifndef sun
+       pthread_attr_getstack( &attr, (void**)&staddr, &stsize );
+#endif
+
+       g_assert (staddr);
+
+       g_assert ((current > staddr) && (current < staddr + stsize));
+
+       tls->end_of_stack = staddr + stsize;
+
+       /*
+        * threads created by nptl does not seem to have a guard page, and
+        * since the main thread is not created by us, we can't even set one.
+        * Increasing stsize fools the SIGSEGV signal handler into thinking this
+        * is a stack overflow exception.
+        */
+       tls->stack_size = stsize + getpagesize ();
+
+       /* Setup an alternate signal stack */
+       tls->signal_stack = mmap (0, SIGNAL_STACK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+       tls->signal_stack_size = SIGNAL_STACK_SIZE;
+
+       g_assert (tls->signal_stack);
+
+       sa.ss_sp = tls->signal_stack;
+       sa.ss_size = SIGNAL_STACK_SIZE;
+       sa.ss_flags = SS_ONSTACK;
+       sigaltstack (&sa, NULL);
+}
+
+#endif
+
 /*
  * Support for fast access to the thread-local lmf structure using the GS
  * segment register on NPTL + kernel 2.6.x.
@@ -4667,14 +4734,6 @@ static gboolean tls_offset_inited = FALSE;
 void
 mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
 {
-#ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
-       pthread_t self = pthread_self();
-       pthread_attr_t attr;
-       void *staddr = NULL;
-       size_t stsize = 0;
-       struct sigaltstack sa;
-#endif
-
        if (!tls_offset_inited) {
                if (!getenv ("MONO_NO_TLS")) {
 #ifdef PLATFORM_WIN32
@@ -4703,40 +4762,7 @@ mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
        }               
 
 #ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
-
-       /* Determine stack boundaries */
-       if (!mono_running_on_valgrind ()) {
-#ifdef HAVE_PTHREAD_GETATTR_NP
-               pthread_getattr_np( self, &attr );
-#else
-#ifdef HAVE_PTHREAD_ATTR_GET_NP
-               pthread_attr_get_np( self, &attr );
-#elif defined(sun)
-               pthread_attr_init( &attr );
-               pthread_attr_getstacksize( &attr, &stsize );
-#else
-#error "Not implemented"
-#endif
-#endif
-#ifndef sun
-               pthread_attr_getstack( &attr, &staddr, &stsize );
-#endif
-       }
-
-       /* 
-        * staddr seems to be wrong for the main thread, so we keep the value in
-        * tls->end_of_stack
-        */
-       tls->stack_size = stsize;
-
-       /* Setup an alternate signal stack */
-       tls->signal_stack = g_malloc (SIGNAL_STACK_SIZE);
-       tls->signal_stack_size = SIGNAL_STACK_SIZE;
-
-       sa.ss_sp = tls->signal_stack;
-       sa.ss_size = SIGNAL_STACK_SIZE;
-       sa.ss_flags = SS_ONSTACK;
-       sigaltstack (&sa, NULL);
+       setup_stack (tls);
 #endif
 }
 
@@ -4752,7 +4778,7 @@ mono_arch_free_jit_tls_data (MonoJitTlsData *tls)
        sigaltstack  (&sa, NULL);
 
        if (tls->signal_stack)
-               g_free (tls->signal_stack);
+               munmap (tls->signal_stack, SIGNAL_STACK_SIZE);
 #endif
 }
 
index 667bc70ab360823a325cc5818aad0c1f4c490072..2b5d671c45c0cdc0bb00102eb77e508f0bcbc103 100644 (file)
@@ -44,7 +44,6 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep);
 #endif /* PLATFORM_WIN32 */
 
 #ifdef sun    // Solaris x86
-#  undef SIGSEGV_ON_ALTSTACK
 #  define MONO_ARCH_USE_SIGACTION 1
 struct sigcontext {
         unsigned short gs, __gsh;
@@ -71,6 +70,25 @@ struct sigcontext {
 };
 #endif  // sun, Solaris x86
 
+#ifdef __linux__
+#define MONO_ARCH_USE_SIGACTION
+#endif
+
+#ifndef PLATFORM_WIN32
+
+#ifdef HAVE_WORKING_SIGALTSTACK
+
+#define MONO_ARCH_SIGSEGV_ON_ALTSTACK
+#define MONO_ARCH_USE_SIGACTION
+
+/* NetBSD doesn't define SA_STACK */
+#ifndef SA_STACK
+#define SA_STACK SA_ONSTACK
+#endif
+#endif
+
+#endif
+
 /* Enables OP_LSHL, OP_LSHL_IMM, OP_LSHR, OP_LSHR_IMM, OP_LSHR_UN, OP_LSHR_UN_IMM */
 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
 
@@ -131,15 +149,33 @@ typedef void* MonoCompileArch;
 # define SC_ESI esi
 #endif
 
+#ifdef MONO_ARCH_USE_SIGACTION
+
+typedef struct {
+       guint32 eax;
+       guint32 ebx;
+       guint32 ecx;
+       guint32 edx;
+       guint32 ebp;
+       guint32 esp;
+    guint32 esi;
+       guint32 edi;
+       guint32 eip;
+} MonoContext;
+
+#else
+
 typedef struct sigcontext MonoContext;
 
-#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->SC_EIP = (long)(ip); } while (0); 
-#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->SC_EBP = (long)(bp); } while (0); 
-#define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->SC_ESP = (long)(esp); } while (0); 
+#endif
+
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->eip = (long)(ip); } while (0); 
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->ebp = (long)(bp); } while (0); 
+#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->esp = (long)(sp); } while (0); 
 
-#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->SC_EIP))
-#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->SC_EBP))
-#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->SC_ESP))
+#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->eip))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->ebp))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->esp))
 
 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do {       \
                mono_arch_flush_register_windows ();    \
@@ -147,17 +183,6 @@ typedef struct sigcontext MonoContext;
                MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0));       \
        } while (0)
 
-#ifndef PLATFORM_WIN32
-#ifdef HAVE_WORKING_SIGALTSTACK
-#define MONO_ARCH_SIGSEGV_ON_ALTSTACK
-/* NetBSD doesn't define SA_STACK */
-#ifndef SA_STACK
-#define SA_STACK SA_ONSTACK
-#endif
-#endif
-
-#endif
-
 #define MONO_ARCH_BIGMUL_INTRINS 1
 #define MONO_ARCH_NEED_DIV_CHECK 1
 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1
index b57ef7235c07401faffde1b5d4eed95c09f0dea9..2adf047f5b9f581139fc1c335174026c672d3914 100644 (file)
@@ -9588,8 +9588,12 @@ SIG_HANDLER_SIGNATURE (sigill_signal_handler)
 
 #ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
 
+#ifndef MONO_ARCH_USE_SIGACTION
+#error "Can't use sigaltstack without sigaction"
+#endif
+
 static void
-sigsegv_signal_handler (int _dummy, siginfo_t *info, void *context)
+SIG_HANDLER_SIGNATURE (sigsegv_signal_handler)
 {
        MonoException *exc;
        MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
index 5c1c914a966870ac71100b8f0d2639a858c0fcb6..1cd680fa6c7ac431081bd19faad6d047053684b3 100644 (file)
@@ -878,6 +878,8 @@ gpointer mono_arch_get_call_filter              (void);
 gpointer mono_arch_get_restore_context          (void);
 gboolean mono_arch_handle_exception             (void *sigctx, gpointer obj, gboolean test_only);
 gpointer mono_arch_ip_from_context              (void *sigctx);
+void     mono_arch_sigctx_to_monoctx            (void *sigctx, MonoContext *ctx);
+void     mono_arch_monoctx_to_sigctx            (MonoContext *mctx, void *ctx);
 void     mono_arch_flush_register_windows       (void);
 gboolean mono_arch_is_inst_imm                  (gint64 imm);
 MonoInst* mono_arch_get_domain_intrinsic        (MonoCompile* cfg);