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