Author: martin
Date: 2007-10-31 09:50:02 -0500 (Wed, 31 Oct 2007)
New Revision: 88556

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/debug-debugger.c
   trunk/mono/mono/mini/debug-debugger.h
   trunk/mono/mono/mini/debug-mini.c
   trunk/mono/mono/mini/debug-mini.h
   trunk/mono/mono/mini/mini-amd64.c
   trunk/mono/mono/mini/mini-trampolines.c
   trunk/mono/mono/mini/mini-x86.c
   trunk/mono/mono/mini/mini.c
   trunk/mono/mono/mini/tramp-x86.c
Log:
2007-10-30  Martin Baulig  <[EMAIL PROTECTED]>

        * mini-trampolines.c
        (mono_magic_trampoline): Call mono_debugger_trampoline_compiled().

        * mini-amd64.c
        (_mono_debugger_breakpoint_info_area): New public variable.
        (mono_debugger_breakpoint_table): New public variable.
        (mono_debugger_remove_breakpoints_from_code): New method.
        (mono_arch_get_vcall_slot): Call it here to remove breakpoints.

        * mini-x86.c
        (_mono_debugger_breakpoint_info_area): New public variable.
        (mono_debugger_breakpoint_table): New public variable.
        (mono_debugger_remove_breakpoints_from_code): New method.
        (mono_arch_get_vcall_slot): Call it here to remove breakpoints.

        * debug-mini.h
        (mono_debugger_thread_created): Added `MonoThread *' argument.
        (mono_debugger_extended_notification): New public method.
        (mono_debugger_trampoline_compiled): New public method.

        * debug-mini.c
        (MonoDebuggerThreadInfo): Added `thread' and
        `extended_notifications' fields.

        * debug-debugger.c
        (debugger_executable_code_buffer): New static variable.

        * debug-debugger.h
        (MonoDebuggerInfo): Added `executable_code_buffer',
        `executable_code_buffer_size', `breakpoint_info_area',
        `breakpoint_table' and `breakpoint_table_size'.



Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2007-10-31 14:49:20 UTC (rev 88555)
+++ trunk/mono/mono/mini/ChangeLog      2007-10-31 14:50:02 UTC (rev 88556)
@@ -1,3 +1,37 @@
+2007-10-30  Martin Baulig  <[EMAIL PROTECTED]>
+
+       * mini-trampolines.c
+       (mono_magic_trampoline): Call mono_debugger_trampoline_compiled().
+
+       * mini-amd64.c
+       (_mono_debugger_breakpoint_info_area): New public variable.
+       (mono_debugger_breakpoint_table): New public variable.
+       (mono_debugger_remove_breakpoints_from_code): New method.
+       (mono_arch_get_vcall_slot): Call it here to remove breakpoints.
+
+       * mini-x86.c
+       (_mono_debugger_breakpoint_info_area): New public variable.
+       (mono_debugger_breakpoint_table): New public variable.
+       (mono_debugger_remove_breakpoints_from_code): New method.
+       (mono_arch_get_vcall_slot): Call it here to remove breakpoints.
+
+       * debug-mini.h
+       (mono_debugger_thread_created): Added `MonoThread *' argument.
+       (mono_debugger_extended_notification): New public method.
+       (mono_debugger_trampoline_compiled): New public method.
+
+       * debug-mini.c
+       (MonoDebuggerThreadInfo): Added `thread' and
+       `extended_notifications' fields.
+
+       * debug-debugger.c
+       (debugger_executable_code_buffer): New static variable.
+
+       * debug-debugger.h
+       (MonoDebuggerInfo): Added `executable_code_buffer',
+       `executable_code_buffer_size', `breakpoint_info_area',
+       `breakpoint_table' and `breakpoint_table_size'.
+
 2007-10-26  Rodrigo Kumpera  <[EMAIL PROTECTED]>
 
        * mini-arm.c (mono_arch_build_imt_thunk): Take the advantage

Modified: trunk/mono/mono/mini/debug-debugger.c
===================================================================
--- trunk/mono/mono/mini/debug-debugger.c       2007-10-31 14:49:20 UTC (rev 
88555)
+++ trunk/mono/mono/mini/debug-debugger.c       2007-10-31 14:50:02 UTC (rev 
88556)
@@ -46,6 +46,9 @@
 
 static void (*mono_debugger_notification_function) (guint64 command, guint64 
data, guint64 data2);
 
+#define EXECUTABLE_CODE_BUFFER_SIZE 4096
+static guint8 *debugger_executable_code_buffer = NULL;
+
 static MonoDebuggerMetadataInfo debugger_metadata_info = {
        sizeof (MonoDebuggerMetadataInfo),
        sizeof (MonoDefaults),
@@ -68,6 +71,7 @@
        G_STRUCT_OFFSET (MonoClass, byval_arg),
        G_STRUCT_OFFSET (MonoClass, generic_class),
        G_STRUCT_OFFSET (MonoClass, generic_container),
+       G_STRUCT_OFFSET (MonoClass, vtable),
        sizeof (MonoClassField),
        G_STRUCT_OFFSET (MonoClassField, type),
        G_STRUCT_OFFSET (MonoClassField, offset),
@@ -96,7 +100,9 @@
        G_STRUCT_OFFSET (MonoMethod, klass),
        G_STRUCT_OFFSET (MonoMethod, token),
        G_STRUCT_OFFSET (MonoMethod, name) + sizeof (void *),
-       G_STRUCT_OFFSET (MonoMethodInflated, declaring)
+       G_STRUCT_OFFSET (MonoMethodInflated, declaring),
+       G_STRUCT_OFFSET (MonoVTable, klass),
+       G_STRUCT_OFFSET (MonoVTable, vtable)
 };
 
 /*
@@ -130,7 +136,14 @@
        &debugger_runtime_class_init,
 
        &mono_debug_debugger_version,
-       &mono_debugger_thread_table
+       &mono_debugger_thread_table,
+
+       &debugger_executable_code_buffer,
+       &_mono_debugger_breakpoint_info_area,
+       &mono_debugger_breakpoint_table,
+
+       EXECUTABLE_CODE_BUFFER_SIZE,
+       MONO_DEBUGGER_BREAKPOINT_TABLE_SIZE,
 };
 
 static guint64
@@ -335,6 +348,7 @@
        mono_debugger_init ();
 
        mono_debugger_event_handler = debugger_event_handler;
+       debugger_executable_code_buffer = mono_global_codeman_reserve 
(EXECUTABLE_CODE_BUFFER_SIZE);
        debugger_init_threads ();
 }
 
@@ -357,6 +371,7 @@
 mono_debugger_init (void)
 {
        mono_debugger_notification_function = 
mono_debugger_create_notification_function ();
+       debugger_executable_code_buffer = mono_global_codeman_reserve 
(EXECUTABLE_CODE_BUFFER_SIZE);
        mono_debugger_event_handler = debugger_event_handler;
 
        /*

Modified: trunk/mono/mono/mini/debug-debugger.h
===================================================================
--- trunk/mono/mono/mini/debug-debugger.h       2007-10-31 14:49:20 UTC (rev 
88555)
+++ trunk/mono/mono/mini/debug-debugger.h       2007-10-31 14:50:02 UTC (rev 
88556)
@@ -58,6 +58,13 @@
 
        gint32 *debugger_version;
        MonoDebuggerThreadInfo **thread_table;
+
+       guint8 **executable_code_buffer;
+       volatile const MonoDebuggerBreakpointInfo **breakpoint_info_area;
+       volatile const MonoDebuggerBreakpointInfo ***breakpoint_table;
+
+       guint32 executable_code_buffer_size;
+       guint32 breakpoint_table_size;
 };
 
 struct _MonoDebuggerMetadataInfo {
@@ -82,6 +89,7 @@
        int klass_byval_arg_offset;
        int klass_generic_class_offset;
        int klass_generic_container_offset;
+       int klass_vtable_offset;
        int field_info_size;
        int field_info_type_offset;
        int field_info_offset_offset;
@@ -111,6 +119,8 @@
        int mono_method_token_offset;
        int mono_method_flags_offset;
        int mono_method_inflated_offset;
+       int mono_vtable_klass_offset;
+       int mono_vtable_vtable_offset;
 };
 
 #endif

Modified: trunk/mono/mono/mini/debug-mini.c
===================================================================
--- trunk/mono/mono/mini/debug-mini.c   2007-10-31 14:49:20 UTC (rev 88555)
+++ trunk/mono/mono/mini/debug-mini.c   2007-10-31 14:50:02 UTC (rev 88556)
@@ -53,6 +53,8 @@
        guint64 lmf_addr;
        guint64 end_stack;
 
+       guint64 extended_notifications;
+
        /* Next pointer. */
        MonoDebuggerThreadInfo *next;
 
@@ -68,6 +70,7 @@
         * The debugger doesn't access anything beyond this point.
         */
        MonoJitTlsData *jit_tls;
+       MonoThread *thread;
 };
 
 MonoDebuggerThreadInfo *mono_debugger_thread_table = NULL;
@@ -838,7 +841,7 @@
 }
 
 void
-mono_debugger_thread_created (gsize tid, MonoJitTlsData *jit_tls)
+mono_debugger_thread_created (gsize tid, MonoThread *thread, MonoJitTlsData 
*jit_tls)
 {
 #ifdef MONO_DEBUGGER_SUPPORTED
        size_t stsize = 0;
@@ -852,6 +855,7 @@
 
        info = g_new0 (MonoDebuggerThreadInfo, 1);
        info->tid = tid;
+       info->thread = thread;
        info->stack_start = (guint64) (gsize) staddr;
        info->signal_stack_start = (guint64) (gsize) jit_tls->signal_stack;
        info->stack_size = stsize;
@@ -892,3 +896,34 @@
        }
 #endif
 }
+
+void
+mono_debugger_extended_notification (MonoDebuggerEvent event, guint64 data, 
guint64 arg)
+{
+#ifdef MONO_DEBUGGER_SUPPORTED
+       MonoDebuggerThreadInfo **ptr;
+       MonoThread *thread = mono_thread_current ();
+
+       if (!mono_debug_using_mono_debugger ())
+               return;
+
+       for (ptr = &mono_debugger_thread_table; *ptr; ptr = &(*ptr)->next) {
+               MonoDebuggerThreadInfo *info = *ptr;
+
+               if (info->thread != thread)
+                       continue;
+
+               if ((info->extended_notifications & (int) event) == 0)
+                       continue;
+
+               mono_debugger_event (event, data, arg);
+       }
+#endif
+}
+
+void
+mono_debugger_trampoline_compiled (MonoMethod *method, const guint8 *code)
+{
+       mono_debugger_extended_notification (MONO_DEBUGGER_EVENT_TRAMPOLINE,
+                                            (guint64) (gsize) method, 
(guint64) (gsize) code);
+}

Modified: trunk/mono/mono/mini/debug-mini.h
===================================================================
--- trunk/mono/mono/mini/debug-mini.h   2007-10-31 14:49:20 UTC (rev 88555)
+++ trunk/mono/mono/mini/debug-mini.h   2007-10-31 14:50:02 UTC (rev 88556)
@@ -16,12 +16,31 @@
 extern MonoDebuggerThreadInfo *mono_debugger_thread_table;
 
 void
-mono_debugger_thread_created (gsize tid, MonoJitTlsData *jit_tls);
+mono_debugger_thread_created (gsize tid, MonoThread *thread, MonoJitTlsData 
*jit_tls);
 
 void
 mono_debugger_thread_cleanup (MonoJitTlsData *jit_tls);
 
+void
+mono_debugger_extended_notification (MonoDebuggerEvent event, guint64 data, 
guint64 arg);
+
+void
+mono_debugger_trampoline_compiled (MonoMethod *method, const guint8 *code);
+
 /*
+ * Debugger breakpoint interface.
+ */
+
+typedef struct _MonoDebuggerBreakpointInfo MonoDebuggerBreakpointInfo;
+
+#define MONO_DEBUGGER_BREAKPOINT_TABLE_SIZE    256
+extern volatile const MonoDebuggerBreakpointInfo 
*_mono_debugger_breakpoint_info_area;
+extern volatile const MonoDebuggerBreakpointInfo 
**mono_debugger_breakpoint_table;
+
+gboolean
+mono_debugger_remove_breakpoints_from_code (const guint8 *orig_address, guint8 
*code, int size);
+
+/*
  * This is the old breakpoint interface.
  * It isn't used by the debugger anymore, but still when using the `--break' 
command
  * line argument.

Modified: trunk/mono/mono/mini/mini-amd64.c
===================================================================
--- trunk/mono/mono/mini/mini-amd64.c   2007-10-31 14:49:20 UTC (rev 88555)
+++ trunk/mono/mono/mini/mini-amd64.c   2007-10-31 14:50:02 UTC (rev 88556)
@@ -26,6 +26,7 @@
 
 #include "trace.h"
 #include "mini-amd64.h"
+#include "debug-mini.h"
 #include "inssel.h"
 #include "cpu-amd64.h"
 
@@ -5238,13 +5239,68 @@
        return 3;
 }
 
+struct _MonoDebuggerBreakpointInfo {
+       const guint8 *address;
+       guint8 saved_byte;
+};
+
+static MonoDebuggerBreakpointInfo breakpoint_info_area 
[MONO_DEBUGGER_BREAKPOINT_TABLE_SIZE];
+static volatile const MonoDebuggerBreakpointInfo *breakpoint_table 
[MONO_DEBUGGER_BREAKPOINT_TABLE_SIZE];
+
+volatile const MonoDebuggerBreakpointInfo *_mono_debugger_breakpoint_info_area 
= breakpoint_info_area;
+volatile const MonoDebuggerBreakpointInfo **mono_debugger_breakpoint_table = 
breakpoint_table;
+
+/*
+ * Removes breakpoints from target memory.
+ *
+ * @orig_address:
+ * The original memory address.
+ *
+ * @code:
+ * A copy of @size bytes from that memory area, which we can modify.
+ *
+ * Returns:
+ * TRUE if there were any breakpoints in that area, FALSE if not.
+ */
+gboolean
+mono_debugger_remove_breakpoints_from_code (const guint8 *orig_address, guint8 
*code, int size)
+{
+       gboolean found_breakpoint = FALSE;
+       int i;
+
+       for (i = 0; i < MONO_DEBUGGER_BREAKPOINT_TABLE_SIZE; i++) {
+               volatile const MonoDebuggerBreakpointInfo *info = 
mono_debugger_breakpoint_table [i];
+               int offset;
+
+               if (!info)
+                       continue;
+
+               if ((info->address < orig_address) || (info->address > 
orig_address + size))
+                       continue;
+
+               if (!found_breakpoint) {
+                       memcpy (code, orig_address, size);
+                       found_breakpoint = TRUE;
+               }
+
+               offset = info->address - orig_address;
+               code [offset] = info->saved_byte;
+       }
+
+       return found_breakpoint;
+}
+
 gpointer
 mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
 {
+       guint8 buf [16];
        guint32 reg;
        gint32 disp;
        guint8 rex = 0;
 
+       if (mono_debugger_remove_breakpoints_from_code (code - 9, buf, sizeof 
(buf)))
+               code = buf + 9;
+
        *displacement = 0;
 
        /* go to the start of the call instruction

Modified: trunk/mono/mono/mini/mini-trampolines.c
===================================================================
--- trunk/mono/mono/mini/mini-trampolines.c     2007-10-31 14:49:20 UTC (rev 
88555)
+++ trunk/mono/mono/mini/mini-trampolines.c     2007-10-31 14:50:02 UTC (rev 
88556)
@@ -121,6 +121,8 @@
        addr = mono_compile_method (m);
        g_assert (addr);
 
+       mono_debugger_trampoline_compiled (m, addr);
+
        /* the method was jumped to */
        if (!code)
                return addr;

Modified: trunk/mono/mono/mini/mini-x86.c
===================================================================
--- trunk/mono/mono/mini/mini-x86.c     2007-10-31 14:49:20 UTC (rev 88555)
+++ trunk/mono/mono/mini/mini-x86.c     2007-10-31 14:50:02 UTC (rev 88556)
@@ -23,6 +23,7 @@
 
 #include "trace.h"
 #include "mini-x86.h"
+#include "debug-mini.h"
 #include "inssel.h"
 #include "cpu-x86.h"
 
@@ -4445,12 +4446,67 @@
        }
 }
 
+struct _MonoDebuggerBreakpointInfo {
+       const guint8 *address;
+       guint8 saved_byte;
+};
+
+static MonoDebuggerBreakpointInfo breakpoint_info_area 
[MONO_DEBUGGER_BREAKPOINT_TABLE_SIZE];
+static volatile const MonoDebuggerBreakpointInfo *breakpoint_table 
[MONO_DEBUGGER_BREAKPOINT_TABLE_SIZE];
+
+volatile const MonoDebuggerBreakpointInfo *_mono_debugger_breakpoint_info_area 
= breakpoint_info_area;
+volatile const MonoDebuggerBreakpointInfo **mono_debugger_breakpoint_table = 
breakpoint_table;
+
+/*
+ * Removes breakpoints from target memory.
+ *
+ * @orig_address:
+ * The original memory address.
+ *
+ * @code:
+ * A copy of @size bytes from that memory area, which we can modify.
+ *
+ * Returns:
+ * TRUE if there were any breakpoints in that area, FALSE if not.
+ */
+gboolean
+mono_debugger_remove_breakpoints_from_code (const guint8 *orig_address, guint8 
*code, int size)
+{
+       gboolean found_breakpoint = FALSE;
+       int i;
+
+       for (i = 0; i < MONO_DEBUGGER_BREAKPOINT_TABLE_SIZE; i++) {
+               volatile const MonoDebuggerBreakpointInfo *info = 
mono_debugger_breakpoint_table [i];
+               int offset;
+
+               if (!info)
+                       continue;
+
+               if ((info->address < orig_address) || (info->address > 
orig_address + size))
+                       continue;
+
+               if (!found_breakpoint) {
+                       memcpy (code, orig_address, size);
+                       found_breakpoint = TRUE;
+               }
+
+               offset = info->address - orig_address;
+               code [offset] = info->saved_byte;
+       }
+
+       return found_breakpoint;
+}
+
 gpointer
 mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement)
 {
+       guint8 buf [16];
        guint8 reg = 0;
        gint32 disp = 0;
 
+       mono_debugger_remove_breakpoints_from_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.c
===================================================================
--- trunk/mono/mono/mini/mini.c 2007-10-31 14:49:20 UTC (rev 88555)
+++ trunk/mono/mono/mini/mini.c 2007-10-31 14:50:02 UTC (rev 88556)
@@ -9071,8 +9071,8 @@
 {
        MonoThread *thread;
        void *jit_tls = setup_jit_tls_data (stack_start, mono_thread_abort);
-       mono_debugger_thread_created (tid, jit_tls);
        thread = mono_thread_current ();
+       mono_debugger_thread_created (tid, thread, jit_tls);
        if (thread)
                thread->jit_data = jit_tls;
 }
@@ -9093,8 +9093,8 @@
 {
        MonoThread *thread;
        void *jit_tls = setup_jit_tls_data (stack_start, 
mono_thread_abort_dummy);
-       mono_debugger_thread_created (tid, (MonoJitTlsData *) jit_tls);
        thread = mono_thread_current ();
+       mono_debugger_thread_created (tid, thread, (MonoJitTlsData *) jit_tls);
        if (thread)
                thread->jit_data = jit_tls;
        if (mono_profiler_get_events () & MONO_PROFILE_STATISTICAL)

Modified: trunk/mono/mono/mini/tramp-x86.c
===================================================================
--- trunk/mono/mono/mini/tramp-x86.c    2007-10-31 14:49:20 UTC (rev 88555)
+++ trunk/mono/mono/mini/tramp-x86.c    2007-10-31 14:50:02 UTC (rev 88556)
@@ -58,8 +58,17 @@
 }
 
 void
-mono_arch_patch_callsite (guint8 *code, guint8 *addr)
+mono_arch_patch_callsite (guint8 *orig_code, guint8 *addr)
 {
+       guint8 *code;
+       guint8 buf [16];
+       gboolean can_write = mono_debugger_remove_breakpoints_from_code 
(orig_code - 8, buf, sizeof (buf));
+
+       code = buf + 8;
+       code = orig_code;
+       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 +77,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 +89,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