Author: lupus
Date: 2007-10-31 13:14:03 -0500 (Wed, 31 Oct 2007)
New Revision: 88596

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/mini-x86.c
   trunk/mono/mono/mini/mini-x86.h
   trunk/mono/mono/mini/mini.c
   trunk/mono/mono/mini/mini.h
   trunk/mono/mono/mini/tramp-x86.c
Log:


Wed Oct 31 19:29:30 CET 2007 Paolo Molaro <[EMAIL PROTECTED]>

        * mini.c, mini.h, mini-x86, tramp-x86.c, mini-x86.h: added API to
        let the debugger or other external agents to tell the JIT when
        a sw breakpoint has been inserted in the code that the JIT needs
        to be able to inspect.



Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2007-10-31 18:09:21 UTC (rev 88595)
+++ trunk/mono/mono/mini/ChangeLog      2007-10-31 18:14:03 UTC (rev 88596)
@@ -1,3 +1,11 @@
+
+Wed Oct 31 19:29:30 CET 2007 Paolo Molaro <[EMAIL PROTECTED]>
+
+       * mini.c, mini.h, mini-x86, tramp-x86.c, mini-x86.h: added API to
+       let the debugger or other external agents to tell the JIT when
+       a sw breakpoint has been inserted in the code that the JIT needs
+       to be able to inspect.
+
 2007-10-31  Martin Baulig  <[EMAIL PROTECTED]>
 
        * debug-debugger.h

Modified: trunk/mono/mono/mini/mini-x86.c
===================================================================
--- trunk/mono/mono/mini/mini-x86.c     2007-10-31 18:09:21 UTC (rev 88595)
+++ trunk/mono/mono/mini/mini-x86.c     2007-10-31 18:14:03 UTC (rev 88596)
@@ -62,6 +62,9 @@
 
 #define NOT_IMPLEMENTED g_assert_not_reached ()
 
+MonoBreakpointInfo
+mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
+
 const char*
 mono_arch_regname (int reg) {
        switch (reg) {
@@ -4445,12 +4448,38 @@
        }
 }
 
+gboolean
+mono_breakpoint_clean_code (guint8 *code, guint8 *buf, int size)
+{
+       int i;
+       gboolean can_write = TRUE;
+       memcpy (buf, code, size);
+       for (i = 0; i < MONO_BREAKPOINT_ARRAY_SIZE; ++i) {
+               int idx = mono_breakpoint_info_index [i];
+               guint8 *ptr;
+               if (idx < 1)
+                       continue;
+               ptr = mono_breakpoint_info [idx].address;
+               if (ptr >= code && ptr < code + size) {
+                       guint8 saved_byte = mono_breakpoint_info 
[idx].saved_byte;
+                       can_write = FALSE;
+                       /*g_print ("patching %p with 0x%02x (was: 0x%02x)\n", 
ptr, saved_byte, buf [ptr - code]);*/
+                       buf [ptr - code] = saved_byte;
+               }
+       }
+       return can_write;
+}
+
 gpointer
 mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
 {
+       guint8 buf [8];
        guint8 reg = 0;
        gint32 disp = 0;
 
+       mono_breakpoint_clean_code (code - 8, buf, sizeof (buf));
+       code = buf + 8;
+
        *displacement = 0;
 
        /* go to the start of the call instruction

Modified: trunk/mono/mono/mini/mini-x86.h
===================================================================
--- trunk/mono/mono/mini/mini-x86.h     2007-10-31 18:09:21 UTC (rev 88595)
+++ trunk/mono/mono/mini/mini-x86.h     2007-10-31 18:14:03 UTC (rev 88596)
@@ -269,5 +269,12 @@
 
 #define MONO_ARCH_AOT_SUPPORTED 1
 
+typedef struct {
+       guint8 *address;
+       guint8 saved_byte;
+} MonoBreakpointInfo;
+
+extern MonoBreakpointInfo mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
+
 #endif /* __MONO_MINI_X86_H__ */  
 

Modified: trunk/mono/mono/mini/mini.c
===================================================================
--- trunk/mono/mono/mini/mini.c 2007-10-31 18:09:21 UTC (rev 88595)
+++ trunk/mono/mono/mini/mini.c 2007-10-31 18:14:03 UTC (rev 88596)
@@ -184,6 +184,14 @@
  */
 guint8* mono_trampoline_code [MONO_TRAMPOLINE_NUM];
 
+/*
+ * Table written to by the debugger with a 1-based index into the
+ * mono_breakpoint_info table, which contains changes made to
+ * the JIT instructions by the debugger.
+ */
+gssize
+mono_breakpoint_info_index [MONO_BREAKPOINT_ARRAY_SIZE];
+
 gboolean
 mono_running_on_valgrind (void)
 {

Modified: trunk/mono/mono/mini/mini.h
===================================================================
--- trunk/mono/mono/mini/mini.h 2007-10-31 18:09:21 UTC (rev 88595)
+++ trunk/mono/mono/mini/mini.h 2007-10-31 18:14:03 UTC (rev 88596)
@@ -18,6 +18,8 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-compiler.h>
 
+#define MONO_BREAKPOINT_ARRAY_SIZE 64
+
 #include "mini-arch.h"
 #include "regalloc.h"
 #include "declsec.h"
@@ -1100,6 +1102,10 @@
 void      mono_debug_print_vars                 (gpointer ip, gboolean 
only_arguments);
 void      mono_debugger_run_finally             (MonoContext *start_ctx);
 
+extern gssize mono_breakpoint_info_index [MONO_BREAKPOINT_ARRAY_SIZE];
+
+gboolean mono_breakpoint_clean_code (guint8 *code, guint8 *buf, int size);
+
 /* Mono Debugger support */
 void      mono_debugger_init                    (void);
 int       mono_debugger_main                    (MonoDomain *domain, 
MonoAssembly *assembly, int argc, char **argv);

Modified: trunk/mono/mono/mini/tramp-x86.c
===================================================================
--- trunk/mono/mono/mini/tramp-x86.c    2007-10-31 18:09:21 UTC (rev 88595)
+++ trunk/mono/mono/mini/tramp-x86.c    2007-10-31 18:14:03 UTC (rev 88596)
@@ -58,8 +58,16 @@
 }
 
 void
-mono_arch_patch_callsite (guint8 *code, guint8 *addr)
+mono_arch_patch_callsite (guint8 *orig_code, guint8 *addr)
 {
+       guint8 *code;
+       guint8 buf [8];
+       gboolean can_write = mono_breakpoint_clean_code (orig_code - 8, buf, 
sizeof (buf));
+
+       code = buf + 8;
+       if (mono_running_on_valgrind ())
+               can_write = FALSE;
+
        /* go to the start of the call instruction
         *
         * address_byte = (m << 6) | (o << 3) | reg
@@ -68,9 +76,10 @@
         * 0xff m=2,o=2 imm32
         */
        code -= 6;
+       orig_code -= 6;
        if ((code [1] == 0xe8)) {
-               if (!mono_running_on_valgrind ()) {
-                       InterlockedExchange ((gint32*)(code + 2), (guint)addr - 
((guint)code + 1) - 5);
+               if (can_write) {
+                       InterlockedExchange ((gint32*)(orig_code + 2), 
(guint)addr - ((guint)orig_code + 1) - 5);
 
 #ifdef HAVE_VALGRIND_MEMCHECK_H
                                /* Tell valgrind to recompile the patched code 
*/
@@ -79,8 +88,8 @@
                }
        } else if (code [1] == 0xe9) {
                /* A PLT entry: jmp <DISP> */
-               if (!mono_running_on_valgrind ())
-                       InterlockedExchange ((gint32*)(code + 2), (guint)addr - 
((guint)code + 1) - 5);
+               if (can_write)
+                       InterlockedExchange ((gint32*)(orig_code + 2), 
(guint)addr - ((guint)orig_code + 1) - 5);
        } else {
                printf ("Invalid trampoline sequence: %x %x %x %x %x %x %x\n", 
code [0], code [1], code [2], code [3],
                                code [4], code [5], code [6]);

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to