From 24e06ce4f435e2d6ca44ee2452ab55a3cc7e1ba7 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Sat, 26 Nov 2011 23:52:45 +0100 Subject: [PATCH] Initial soft debugger support for MIPS. --- mono/mini/cpu-mips.md | 1 + mono/mini/mini-mips.c | 166 +++++++++++++++++++++++++++++++++++++- mono/mini/mini-mips.h | 1 + mono/utils/mono-context.h | 12 +-- 4 files changed, 171 insertions(+), 9 deletions(-) diff --git a/mono/mini/cpu-mips.md b/mono/mini/cpu-mips.md index 4b52d898b91..ef652ccda85 100644 --- a/mono/mini/cpu-mips.md +++ b/mono/mini/cpu-mips.md @@ -59,6 +59,7 @@ jmp: len:92 call: dest:v clob:c len:20 br: len:16 switch: src1:i len:40 +seq_point: len:24 callvirt: dest:v clob:c len:20 int_conv_to_r_un: dest:f src1:i len:32 diff --git a/mono/mini/mini-mips.c b/mono/mini/mini-mips.c index 0716591cd30..8df3887ff08 100644 --- a/mono/mini/mini-mips.c +++ b/mono/mini/mini-mips.c @@ -17,6 +17,7 @@ #include #include +#include #include @@ -74,6 +75,15 @@ static int ls_word_idx; /* Index of ls word/register */ static int ms_word_idx; +/* + * The code generated for sequence points reads from this location, which is + * made read-only when single stepping is enabled. + */ +static gpointer ss_trigger_page; + +/* Enabled breakpoints read from this trigger page */ +static gpointer bp_trigger_page; + #undef DEBUG #define DEBUG(a) if (cfg->verbose_level > 1) a #undef DEBUG @@ -556,7 +566,11 @@ mono_arch_cpu_init (void) void mono_arch_init (void) { - InitializeCriticalSection (&mini_arch_mutex); + InitializeCriticalSection (&mini_arch_mutex); + + ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT); + bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT); + mono_mprotect (bp_trigger_page, mono_pagesize (), 0); } /* @@ -3193,6 +3207,26 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_NOT_REACHED: case OP_NOT_NULL: break; + case OP_SEQ_POINT: { + if (ins->flags & MONO_INST_SINGLE_STEP_LOC) { + guint32 addr = (guint32)ss_trigger_page; + + mips_load_const (code, mips_t9, addr); + mips_lw (code, mips_t9, mips_t9, 0); + } + + mono_add_seq_point (cfg, bb, ins, code - cfg->native_code); + + /* + * A placeholder for a possible breakpoint inserted by + * mono_arch_set_breakpoint (). + */ + /* mips_load_const () + mips_lw */ + mips_nop (code); + mips_nop (code); + mips_nop (code); + break; + } case OP_TLS_GET: g_assert_not_reached(); #if 0 @@ -5594,8 +5628,7 @@ MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg) mgreg_t mono_arch_context_get_int_reg (MonoContext *ctx, int reg) { - /* FIXME: implement */ - g_assert_not_reached (); + return ctx->sc_regs [reg]; } #ifdef MONO_ARCH_HAVE_IMT @@ -5774,3 +5807,130 @@ mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code) NOT_IMPLEMENTED; return (MonoVTable*) regs [MONO_ARCH_RGCTX_REG]; } + +/* Soft Debug support */ +#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED + +/* + * mono_arch_set_breakpoint: + * + * See mini-amd64.c for docs. + */ +void +mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip) +{ + guint8 *code = ip; + guint32 addr = (guint32)bp_trigger_page; + + mips_load_const (code, mips_t9, addr); + mips_lw (code, mips_t9, mips_t9, 0); + + mono_arch_flush_icache (ip, code - ip); +} + +/* + * mono_arch_clear_breakpoint: + * + * See mini-amd64.c for docs. + */ +void +mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *ip) +{ + guint8 *code = ip; + + mips_nop (code); + mips_nop (code); + mips_nop (code); + + mono_arch_flush_icache (ip, code - ip); +} + +/* + * mono_arch_start_single_stepping: + * + * See mini-amd64.c for docs. + */ +void +mono_arch_start_single_stepping (void) +{ + mono_mprotect (ss_trigger_page, mono_pagesize (), 0); +} + +/* + * mono_arch_stop_single_stepping: + * + * See mini-amd64.c for docs. + */ +void +mono_arch_stop_single_stepping (void) +{ + mono_mprotect (ss_trigger_page, mono_pagesize (), MONO_MMAP_READ); +} + +/* + * mono_arch_is_single_step_event: + * + * See mini-amd64.c for docs. + */ +gboolean +mono_arch_is_single_step_event (void *info, void *sigctx) +{ + siginfo_t* sinfo = (siginfo_t*) info; + /* Sometimes the address is off by 4 */ + if (sinfo->si_addr >= ss_trigger_page && (guint8*)sinfo->si_addr <= (guint8*)ss_trigger_page + 128) + return TRUE; + else + return FALSE; +} + +/* + * mono_arch_is_breakpoint_event: + * + * See mini-amd64.c for docs. + */ +gboolean +mono_arch_is_breakpoint_event (void *info, void *sigctx) +{ + siginfo_t* sinfo = (siginfo_t*) info; + /* Sometimes the address is off by 4 */ + if (sinfo->si_addr >= bp_trigger_page && (guint8*)sinfo->si_addr <= (guint8*)bp_trigger_page + 128) + return TRUE; + else + return FALSE; +} + +/* + * mono_arch_skip_breakpoint: + * + * See mini-amd64.c for docs. + */ +void +mono_arch_skip_breakpoint (MonoContext *ctx) +{ + MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + 4); +} + +/* + * mono_arch_skip_single_step: + * + * See mini-amd64.c for docs. + */ +void +mono_arch_skip_single_step (MonoContext *ctx) +{ + MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + 4); +} + +/* + * mono_arch_get_seq_point_info: + * + * See mini-amd64.c for docs. + */ +gpointer +mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code) +{ + NOT_IMPLEMENTED; + return NULL; +} + +#endif /* MONO_ARCH_SOFT_DEBUG_SUPPORTED */ diff --git a/mono/mini/mini-mips.h b/mono/mini/mini-mips.h index b535ad436f4..fd05be0c4ce 100644 --- a/mono/mini/mini-mips.h +++ b/mono/mini/mini-mips.h @@ -272,6 +272,7 @@ typedef struct MonoCompileArch { #define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1 #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 +#define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1 /* XXX - a mystery, but it works */ #define MONO_GET_CONTEXT \ diff --git a/mono/utils/mono-context.h b/mono/utils/mono-context.h index b49347ae1e2..b456c8aa5b4 100644 --- a/mono/utils/mono-context.h +++ b/mono/utils/mono-context.h @@ -362,7 +362,7 @@ mono_ia64_context_get_fp (MonoContext *ctx) return fp; } -#elif defined(__mips__) && SIZEOF_REGISTER == 4 /* defined(__ia64__) */ +#elif ((defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))) && SIZEOF_REGISTER == 4 /* defined(__ia64__) */ /* we define our own structure and we'll copy the data * from sigcontext/ucontext/mach when we need it. @@ -371,15 +371,15 @@ mono_ia64_context_get_fp (MonoContext *ctx) * the original context from the signal handler. */ typedef struct { - gpointer sc_pc; - guint32 sc_regs [32]; + mgreg_t sc_pc; + mgreg_t sc_regs [32]; gfloat sc_fpregs [32]; } MonoContext; /* we have the stack pointer, not the base pointer in sigcontext */ -#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_pc = (int)(ip); } while (0); -#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_regs[mips_fp] = (int)(bp); } while (0); -#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->sc_regs[mips_sp] = (int)(sp); } while (0); +#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_pc = (mgreg_t)(ip); } while (0); +#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_regs[mips_fp] = (mgreg_t)(bp); } while (0); +#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->sc_regs[mips_sp] = (mgreg_t)(sp); } while (0); #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_pc)) #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->sc_regs[mips_fp])) -- 2.25.1