Finish sdb support on MIPS. Fix resume_context () to restore all registers. Fix UCONT...
authorZoltan Varga <vargaz@gmail.com>
Sat, 3 Dec 2011 06:52:29 +0000 (06:52 +0000)
committerZoltan Varga <vargaz@gmail.com>
Sun, 4 Dec 2011 04:49:22 +0000 (04:49 +0000)
mono/mini/debugger-agent.c
mono/mini/exceptions-mips.c
mono/mini/mini-mips.c
mono/mini/mini-mips.h
mono/utils/mono-sigcontext.h

index 3eca586f2df4fa2f351172aa02404ddcf2d0866e..50d374b05c98ffb487efa53cebe2ed5afc0f0ecd 100644 (file)
@@ -5667,6 +5667,11 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke)
                /* Mark that this is a MonoLMFExt */
                ext.lmf.previous_lmf = (gpointer)(((gssize)ext.lmf.previous_lmf) | 2);
                ext.lmf.ebp = (gssize)&ext;
+#elif defined(TARGET_MIPS)
+               ext.lmf.previous_lmf = *(lmf_addr);
+               /* Mark that this is a MonoLMFExt */
+               ext.lmf.previous_lmf = (gpointer)(((gssize)ext.lmf.previous_lmf) | 2);
+               ext.lmf.ebp = (gssize)&ext;
 #else
                g_assert_not_reached ();
 #endif
index da90482edbbf24fa2b03b5f3bb0619cac06da680..22b19e9ea38fd42aeac56af89d62287f3cc44338 100644 (file)
 
 #define GENERIC_EXCEPTION_SIZE 256
 
-/* XXX */
-#if 1
-#define restore_regs_from_context(ctx_reg,ip_reg,tmp_reg) do { \
-       } while (0)
-#else
-#define restore_regs_from_context(ctx_reg,pc,tmp_reg) do {     \
-               int reg;        \
-               ppc_lwz (code, pc, G_STRUCT_OFFSET (MonoContext, sc_pc), ctx_reg);      \
-               ppc_lmw (code, ppc_r13, ctx_reg, G_STRUCT_OFFSET (MonoContext, sc_regs));       \
-               for (reg = 0; reg < MONO_SAVED_FREGS; ++reg) {  \
-                       ppc_lfd (code, (14 + reg), G_STRUCT_OFFSET(MonoLMF, sc_fpregs) + reg * sizeof (gdouble), ctx_reg);      \
-               }       \
-       } while (0)
-#endif
-
-/* nothing to do */
-#define setup_context(ctx) do { \
-               memset ((ctx), 0, sizeof(*(ctx)));      \
-       } while (0);
-
 /*
  * mono_arch_get_restore_context:
  *
@@ -62,7 +42,7 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
 {
        int i;
        guint8 *code;
-       static guint8 start [128];
+       static guint8 start [512];
        static int inited = 0;
        guint32 iregs_to_restore;
 
@@ -75,16 +55,19 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
        inited = 1;
        code = start;
 
+       mips_move (code, mips_at, mips_a0);
+
        iregs_to_restore = (MONO_ARCH_CALLEE_SAVED_REGS \
                            | (1 << mips_sp) | (1 << mips_ra));
        for (i = 0; i < MONO_SAVED_GREGS; ++i) {
-               if (iregs_to_restore & (1 << i)) {
-                       MIPS_LW (code, i, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_regs[i]));
+               //if (iregs_to_restore & (1 << i)) {
+               if (i != mips_zero && i != mips_at) {
+                       MIPS_LW (code, i, mips_at, G_STRUCT_OFFSET (MonoContext, sc_regs[i]));
                }
        }
 
        /* Get the address to return to */
-       mips_lw (code, mips_t9, mips_a0, G_STRUCT_OFFSET (MonoContext, sc_pc));
+       mips_lw (code, mips_t9, mips_at, G_STRUCT_OFFSET (MonoContext, sc_pc));
 
        /* jump to the saved IP */
        mips_jr (code, mips_t9);
@@ -206,7 +189,7 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean
        /* adjust eip so that it point into the call instruction */
        eip -= 8;
 
-       setup_context (&ctx);
+       memset (&ctx, 0, sizeof (MonoContext));
 
        /*g_print  ("stack in throw: %p\n", esp);*/
        memcpy (&ctx.sc_regs, (void *)(esp + MIPS_STACK_PARAM_OFFSET),
@@ -448,71 +431,35 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
                if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) {
                        /* remove any unused lmf */
-                       *lmf = (*lmf)->previous_lmf;
+                       *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3);
                }
 
                /* we substract 8, so that the IP points into the call instruction */
                MONO_CONTEXT_SET_IP (new_ctx, new_ctx->sc_pc - 8);
 
-#if 0
+               /* Sanity check -- we should have made progress here */
+               g_assert (MONO_CONTEXT_GET_BP (new_ctx) != MONO_CONTEXT_GET_BP (ctx));
+               return TRUE;
+       } else if (*lmf) {
+
+               if (((mgreg_t)(*lmf)->previous_lmf) & 2) {
+                       /* 
+                        * This LMF entry is created by the soft debug code to mark transitions to
+                        * managed code done during invokes.
+                        */
+                       MonoLMFExt *ext = (MonoLMFExt*)(*lmf);
 
-               address = (char *)ip - (char *)ji->code_start;
+                       g_assert (ext->debugger_invoke);
 
-               /* Compute the previous stack frame, assuming method
-                * starts with addiu sp, sp, <offset>. */
-               sp = (guint32)(fp) - (short)(*(guint32 *)(ji->code_start));
+                       memcpy (new_ctx, &ext->ctx, sizeof (MonoContext));
 
-               /* Sanity check the frame */
-               if (!sp || (sp == 0xffffffff)
-                   || (sp & 0x07) || (sp < 64*1024)) {
-#ifdef DEBUG_EXCEPTIONS
-                       g_print ("mono_arch_find_jit_info: bad stack sp=%p\n", (void *) sp);
-#endif
-                       return FALSE;
-               }
+                       *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3);
 
-               if (ji->method->save_lmf && 0) {
-                       /* only enable this when prologue stops emitting
-                        * normal save of s-regs when save_lmf is true.
-                        * Will have to sync with prologue code at that point.
-                        */
-                       memcpy (&new_ctx->sc_fpregs,
-                               (char*)sp - sizeof (float) * MONO_SAVED_FREGS,
-                               sizeof (float) * MONO_SAVED_FREGS);
-                       memcpy (&new_ctx->sc_regs,
-                               (char*)sp - sizeof (float) * MONO_SAVED_FREGS - sizeof (gulong) * MONO_SAVED_GREGS,
-                               sizeof (gulong) * MONO_SAVED_GREGS);
-               } else if (ji->used_regs) {
-                       guint32 *insn;
-                       guint32 mask = ji->used_regs;
-
-                       /* these all happen before adjustment of fp */
-                       /* Look for sw ??, ????(sp) */
-                       insn = ((guint32 *)ji->code_start) + 1;
-                       while (!*insn || ((*insn & 0xffe00000) == 0xafa00000) || ((*insn & 0xffe00000) == 0xffa00000)) {
-                               int reg = (*insn >> 16) & 0x1f;
-                               guint32 addr = (((guint32)fp) + (short)(*insn & 0x0000ffff));
-
-                               mask &= ~(1 << reg);
-                               if ((*insn & 0xffe00000) == 0xafa00000)
-                                       new_ctx->sc_regs [reg] = *(guint32 *)addr;
-                               else
-                                       new_ctx->sc_regs [reg] = *(guint64 *)addr;
-                               insn++;
-                       }
-                       MONO_CONTEXT_SET_SP (new_ctx, sp);
-                       MONO_CONTEXT_SET_BP (new_ctx, sp);
-                       /* assert that we found all registers we were supposed to */
-                       g_assert (!mask);
+                       frame->type = FRAME_TYPE_DEBUGGER_INVOKE;
+
+                       return TRUE;
                }
-               /* we substract 8, so that the IP points into the call instruction */
-               MONO_CONTEXT_SET_IP (new_ctx, new_ctx->sc_regs[mips_ra] - 8);
-#endif
 
-               /* Sanity check -- we should have made progress here */
-               g_assert (MONO_CONTEXT_GET_BP (new_ctx) != MONO_CONTEXT_GET_BP (ctx));
-               return TRUE;
-       } else if (*lmf) {
                if (!(*lmf)->method) {
 #ifdef DEBUG_EXCEPTIONS
                        g_print ("mono_arch_find_jit_info: bad lmf @ %p\n", (void *) *lmf);
@@ -535,7 +482,8 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                MONO_CONTEXT_SET_IP (new_ctx, (*lmf)->eip);
                /* ensure that we've made progress */
                g_assert (new_ctx->sc_pc != ctx->sc_pc);
-               *lmf = (*lmf)->previous_lmf;
+
+               *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3);
 
                return TRUE;
        }
@@ -576,29 +524,81 @@ mono_arch_ip_from_context (void *sigctx)
        return (gpointer)(guint32)ctx->sc_pc;
 }
 
+/*
+ * handle_exception:
+ *
+ *   Called by resuming from a signal handler.
+ */
+static void
+handle_signal_exception (gpointer obj)
+{
+       MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+       MonoContext ctx;
+       static void (*restore_context) (MonoContext *);
+
+       if (!restore_context)
+               restore_context = mono_get_restore_context ();
+
+       memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
+
+       mono_handle_exception (&ctx, obj);
+
+       restore_context (&ctx);
+}
+
 /*
  * This is the function called from the signal handler
  */
 gboolean
 mono_arch_handle_exception (void *ctx, gpointer obj)
 {
+#if defined(MONO_CROSS_COMPILE)
+       g_assert_not_reached ();
+#elif defined(MONO_ARCH_USE_SIGACTION)
+       void *sigctx = ctx;
+
+       /*
+        * Handling the exception in the signal handler is problematic, since the original
+        * signal is disabled, and we could run arbitrary code though the debugger. So
+        * resume into the normal stack and do most work there if possible.
+        */
+       MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+       guint64 sp = UCONTEXT_GREGS (sigctx) [mips_sp];
+
+       /* Pass the ctx parameter in TLS */
+       mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+       /* The others in registers */
+       UCONTEXT_GREGS (sigctx)[mips_a0] = (gsize)obj;
+
+       /* Allocate a stack frame */
+       sp -= 256;
+       UCONTEXT_GREGS (sigctx)[mips_sp] = sp;
+
+       UCONTEXT_REG_PC (sigctx) = (gsize)handle_signal_exception;
+
+       return TRUE;
+#else
        MonoContext mctx;
        gboolean result;
-       
+
        mono_arch_sigctx_to_monoctx (ctx, &mctx);
-#ifdef DEBUG_EXCEPTIONS
-       g_print ("mono_arch_handle_exception: pc=%p\n", (void *) mctx.sc_pc);
-#endif
-       mono_handle_exception (&mctx, obj);
-       result = TRUE;
 
-#ifdef DEBUG_EXCEPTIONS
-       g_print ("mono_arch_handle_exception: restore pc=%p\n", (void *)mctx.sc_pc);
-#endif
-       /* restore the context so that returning from the signal handler
-        * will invoke the catch clause 
+       result = mono_handle_exception (&mctx, obj);
+       /* restore the context so that returning from the signal handler will invoke
+        * the catch clause 
         */
        mono_arch_monoctx_to_sigctx (&mctx, ctx);
-
        return result;
+#endif
+}
+
+/*
+ * mono_arch_setup_resume_sighandler_ctx:
+ *
+ *   Setup CTX so execution continues at FUNC.
+ */
+void
+mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func)
+{
+       MONO_CONTEXT_SET_IP (ctx,func);
 }
index 5fe1a4a91b8278382c6970fbecfce254a3b296d9..f3b034de81fd01a5723a2fa7ba42393795fab728 100644 (file)
@@ -540,7 +540,8 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit
        return frame_size;
 }
 
-#define MAX_ARCH_DELEGATE_PARAMS 4
+/* The delegate object plus 3 params */
+#define MAX_ARCH_DELEGATE_PARAMS (4 - 1)
 
 static gpointer
 get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size)
@@ -1400,9 +1401,6 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        if (mono_jit_trace_calls != NULL && mono_trace_eval (cfg->method))
                offset += 8;
 
-       if (sig->call_convention == MONO_CALL_VARARG)
-               cfg->sig_cookie = MIPS_STACK_PARAM_OFFSET;
-
        /* Now handle the local variables */
 
        curinst = cfg->locals_start;
index 47ef4b8e38f6e8996cdda57efdff4a9f1f319dbc..f8ac1552eb58118887ff2046aaa913c2fa5e18c4 100644 (file)
 
 #if SIZEOF_REGISTER == 4
 #define IREG_SIZE      4
-typedef guint32                mips_ireg;
 #define FREG_SIZE      4
 typedef gfloat         mips_freg;
 
 #elif SIZEOF_REGISTER == 8
 
 #define IREG_SIZE      8
-typedef guint64                mips_ireg;
 #define FREG_SIZE      8
 typedef gdouble                mips_freg;
 
@@ -43,14 +41,6 @@ typedef gdouble              mips_freg;
 #error Unknown REGISTER_SIZE
 #endif
 
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-#define MSW_OFFSET     sizeof(mips_ireg)
-#define LSW_OFFSET     0
-#else
-#define MSW_OFFSET     0
-#define LSW_OFFSET     sizeof(mips_ireg)
-#endif
-
 /*
  * at and t0 used internally
  * v0, v1 aren't here for clarity reasons
@@ -213,9 +203,9 @@ struct MonoLMF {
        gpointer        previous_lmf;
        gpointer        lmf_addr;
        MonoMethod      *method;
-       mips_ireg       ebp;
+       mgreg_t ebp;
        gpointer        eip;
-       mips_ireg       iregs [MONO_SAVED_GREGS];
+       mgreg_t iregs [MONO_SAVED_GREGS];
        mips_freg       fregs [MONO_SAVED_FREGS];
        gulong          magic;
 };
@@ -248,7 +238,7 @@ typedef struct MonoCompileArch {
 #define MIPS_FP_ADDR_OFFSET    (-8)
 #define MIPS_STACK_ALIGNMENT   16
 #define MIPS_STACK_PARAM_OFFSET 16             /* from sp to first parameter */
-#define MIPS_MINIMAL_STACK_SIZE (4*sizeof(mips_ireg) + 4*sizeof(mips_ireg))
+#define MIPS_MINIMAL_STACK_SIZE (4*sizeof(mgreg_t) + 4*sizeof(mgreg_t))
 #define MIPS_EXTRA_STACK_SIZE  16              /* from last parameter to top of frame */
 
 #if _MIPS_SIM == _ABIO32
@@ -277,6 +267,7 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
 #define MONO_ARCH_HAVE_XP_UNWIND 1
 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1
+#define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1
 
 /* XXX - a mystery, but it works */
 #define MONO_GET_CONTEXT \
index bde60d12970759e956cdb4c6da86874d906e220e..7d0e2bcdecdd10e51a1eb7caf3bd9a060755f9b3 100644 (file)
@@ -360,8 +360,8 @@ typedef struct ucontext {
 #  include <ucontext.h>
 # endif
 
-# define UCONTEXT_GREGS(ctx)   (((ucontext_t *)(ctx))->uc_mcontext.gregs)
-# define UCONTEXT_REG_PC(ctx)  (((ucontext_t *)(ctx))->uc_mcontext.pc)
+# define UCONTEXT_GREGS(ctx)   (((struct sigcontext *)(ctx))->sc_regs)
+# define UCONTEXT_REG_PC(ctx)  (((struct sigcontext *)(ctx))->sc_pc)
 
 #elif defined(__s390x__)