* test-9.il: New test, test instaniating a class
[mono.git] / mono / jit / debug.c
index 06642e1e21812d4665c29125eb6ceb10e82d6462..eeec3bd81ff530dd231bcea80e0c730b562a49e9 100644 (file)
@@ -1,3 +1,4 @@
+#include <config.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <mono/metadata/tokentype.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/debug-mono-symfile.h>
-#include <mono/jit/codegen.h>
-#include <mono/jit/debug.h>
 
 #include "debug-private.h"
-#include "helpers.h"
 
 /*
  * NOTE:  Functions and variables starting with `mono_debug_' and `debug_' are
 
 /* This is incremented each time the symbol table is modified.
  * The debugger looks at this variable and if it has a higher value than its current
- * copy of the symbol table, it must call debugger_update_symbol_file_table().
+ * copy of the symbol table, it must call mono_debug_update_symbol_file_table().
  */
-static guint32 debugger_symbol_file_table_generation = 0;
-static guint32 debugger_symbol_file_table_modified = 0;
+guint32 mono_debugger_symbol_file_table_generation = 0;
+guint32 mono_debugger_symbol_file_table_modified = 0;
 
 /* Caution: This variable may be accessed at any time from the debugger;
  *          it is very important not to modify the memory it is pointing to
  *          without previously setting this pointer back to NULL.
  */
-static MonoDebuggerSymbolFileTable *debugger_symbol_file_table = NULL;
+MonoDebuggerSymbolFileTable *mono_debugger_symbol_file_table = NULL;
 
 /* Caution: This function MUST be called before touching the symbol table! */
 static void release_symbol_file_table (void);
 
-static void initialize_debugger_support (void);
-
-static gboolean running_in_the_mono_debugger = FALSE;
-
-static MonoDebugHandle *mono_debug_handle = NULL;
-static gboolean mono_debug_initialized = FALSE;
-static gconstpointer debugger_notification_address = NULL;
+MonoDebugHandle *mono_debug_handle = NULL;
+gboolean mono_debug_initialized = FALSE;
 
 static CRITICAL_SECTION debugger_lock_mutex;
 
-static gpointer debugger_thread_cond;
-static gpointer debugger_start_cond;
-
-static gpointer debugger_finished_cond;
-static CRITICAL_SECTION debugger_finished_mutex;
-
-static gboolean debugger_signalled = FALSE;
-static gboolean must_send_finished = FALSE;
-
 extern void (*mono_debugger_class_init_func) (MonoClass *klass);
 
-static guint64 debugger_insert_breakpoint (guint64 method_argument, const gchar *string_argument);
-static guint64 debugger_remove_breakpoint (guint64 breakpoint);
-static int debugger_update_symbol_file_table (void);
-static int debugger_update_symbol_file_table_internal (void);
-static gpointer debugger_compile_method (MonoMethod *method);
-
 static void mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data);
 static void mono_debug_close_assembly (AssemblyDebugInfo* info);
 static AssemblyDebugInfo *mono_debug_open_image (MonoDebugHandle* debug, MonoImage *image);
 
-/*
- * This is a global data symbol which is read by the debugger.
- */
-MonoDebuggerInfo MONO_DEBUGGER__debugger_info = {
-       MONO_SYMBOL_FILE_DYNAMIC_MAGIC,
-       MONO_SYMBOL_FILE_DYNAMIC_VERSION,
-       sizeof (MonoDebuggerInfo),
-       &mono_generic_trampoline_code,
-       &mono_breakpoint_trampoline_code,
-       &debugger_symbol_file_table_generation,
-       &debugger_symbol_file_table_modified,
-       &debugger_notification_address,
-       &debugger_symbol_file_table,
-       &debugger_compile_method,
-       &debugger_insert_breakpoint,
-       &debugger_remove_breakpoint,
-       &mono_runtime_invoke
+static int running_in_the_mono_debugger = FALSE;
+void (*mono_debugger_event_handler) (MonoDebuggerEvent event, gpointer data, gpointer data2) = NULL;
+
+#ifndef PLATFORM_WIN32
+
+MonoDebuggerIOLayer mono_debugger_io_layer = {
+       InitializeCriticalSection, DeleteCriticalSection, TryEnterCriticalSection,
+       EnterCriticalSection, LeaveCriticalSection, WaitForSingleObject, SignalObjectAndWait,
+       WaitForMultipleObjects, CreateSemaphore, ReleaseSemaphore, CreateThread
 };
 
-static void
-debugger_init_threads (void)
+#endif
+
+void
+mono_debugger_event (MonoDebuggerEvent event, gpointer data, gpointer data2)
 {
-       debugger_thread_cond = CreateSemaphore (NULL, 0, 1, NULL);
-       debugger_start_cond = CreateSemaphore (NULL, 0, 1, NULL);
+       if (mono_debugger_event_handler)
+               (* mono_debugger_event_handler) (event, data, data2);
+}
 
-       InitializeCriticalSection (&debugger_finished_mutex);
-       debugger_finished_cond = CreateSemaphore (NULL, 0, 1, NULL);
+void
+mono_debug_init (int in_the_debugger)
+{
+       if (mono_debug_initialized)
+               return;
+
+       InitializeCriticalSection (&debugger_lock_mutex);
+       mono_debug_initialized = TRUE;
+       running_in_the_mono_debugger = in_the_debugger;
 }
 
-static void
-mono_debug_init (void)
+gpointer
+mono_debug_create_notification_function (gpointer *notification_address)
 {
-       if (!mono_debug_initialized) {
-               InitializeCriticalSection (&debugger_lock_mutex);
-               mono_debug_initialized = TRUE;
-       }
+       guint8 *ptr, *buf;
+
+       ptr = buf = g_malloc0 (16);
+       mono_debug_codegen_breakpoint (&buf);
+       if (notification_address)
+               *notification_address = buf;
+       mono_debug_codegen_ret (&buf);
+
+       return ptr;
 }
 
-static void
+void
 mono_debug_lock (void)
 {
        if (mono_debug_initialized)
                EnterCriticalSection (&debugger_lock_mutex);
 }
 
-static void
+void
 mono_debug_unlock (void)
 {
        if (mono_debug_initialized)
                LeaveCriticalSection (&debugger_lock_mutex);
 }
 
-static void
-mono_debugger_signal (gboolean modified)
-{
-       g_assert (running_in_the_mono_debugger);
-       if (modified)
-               debugger_symbol_file_table_modified = TRUE;
-       mono_debug_lock ();
-       if (!debugger_signalled) {
-               debugger_signalled = TRUE;
-               ReleaseSemaphore (debugger_thread_cond, 1, NULL);
-       }
-       mono_debug_unlock ();
-}
-
-static void
-mono_debugger_wait (void)
-{
-       g_assert (running_in_the_mono_debugger);
-       LeaveCriticalSection (&debugger_finished_mutex);
-       g_assert (WaitForSingleObject (debugger_finished_cond, INFINITE) == WAIT_OBJECT_0);
-       EnterCriticalSection (&debugger_finished_mutex);
-}
-
 static void
 free_method_info (MonoDebugMethodInfo *minfo)
 {
@@ -171,26 +133,15 @@ free_method_info (MonoDebugMethodInfo *minfo)
 }
 
 static void
-debug_arg_warning (const char *message)
+free_wrapper_info (DebugWrapperInfo *winfo)
 {
-       g_warning ("Error while processing --debug-args arguments: %s", message);
+       g_free (winfo);
 }
 
-static gchar *
-replace_suffix (const char *filename, const char *new_suffix)
+static void
+debug_arg_warning (const char *message)
 {
-       const char *pos = strrchr (filename, '.');
-
-       if (!pos)
-               return g_strdup_printf ("%s.%s", filename, new_suffix);
-       else {
-               int len = pos - filename;
-               gchar *retval = g_malloc0 (len + strlen (new_suffix) + 2);
-               memcpy (retval, filename, len);
-               retval [len] = '.';
-               memcpy (retval + len + 1, new_suffix, strlen (new_suffix) + 1);
-               return retval;
-       }
+       g_warning ("Error while processing --debug-args arguments: %s", message);
 }
 
 MonoDebugHandle*
@@ -201,17 +152,15 @@ mono_debug_open (MonoAssembly *assembly, MonoDebugFormat format, const char **ar
 
        g_assert (!mono_debug_handle);
 
-       mono_debug_init ();
-
        debug = g_new0 (MonoDebugHandle, 1);
        debug->name = g_strdup (assembly->image->name);
        debug->format = format;
+       debug->source_files = g_ptr_array_new ();
        debug->producer_name = g_strdup_printf ("Mono JIT compiler version %s", VERSION);
        debug->next_idx = 100;
        debug->dirty = TRUE;
 
        debug->type_hash = g_hash_table_new (NULL, NULL);
-       debug->source_files = g_ptr_array_new ();
 
        debug->images = g_hash_table_new_full (NULL, NULL, NULL,
                                               (GDestroyNotify) mono_debug_close_assembly);
@@ -236,7 +185,6 @@ mono_debug_open (MonoAssembly *assembly, MonoDebugFormat format, const char **ar
                        }
                        break;
                case MONO_DEBUG_FORMAT_MONO:
-               case MONO_DEBUG_FORMAT_MONO_DEBUGGER:
                        debug->flags |= MONO_DEBUG_FLAGS_DONT_UPDATE_IL_FILES |
                                MONO_DEBUG_FLAGS_DONT_CREATE_IL_FILES;
                        break;
@@ -244,8 +192,7 @@ mono_debug_open (MonoAssembly *assembly, MonoDebugFormat format, const char **ar
                        break;
                }
 
-               if ((debug->format != MONO_DEBUG_FORMAT_MONO) &&
-                   (debug->format != MONO_DEBUG_FORMAT_MONO_DEBUGGER)) {
+               if (debug->format != MONO_DEBUG_FORMAT_MONO) {
                        if (!strcmp (arg, "dont_assemble")) {
                                debug->flags |= MONO_DEBUG_FLAGS_DONT_ASSEMBLE;
                                continue;
@@ -285,10 +232,6 @@ mono_debug_open (MonoAssembly *assembly, MonoDebugFormat format, const char **ar
        case MONO_DEBUG_FORMAT_MONO:
                mono_debugger_class_init_func = mono_debug_add_type;
                break;
-       case MONO_DEBUG_FORMAT_MONO_DEBUGGER:
-               mono_debugger_class_init_func = mono_debug_add_type;
-               initialize_debugger_support ();
-               break;
        default:
                g_assert_not_reached ();
        }
@@ -346,7 +289,7 @@ mono_debug_open (MonoAssembly *assembly, MonoDebugFormat format, const char **ar
        mono_debug_add_type (mono_defaults.serializationinfo_class);
        mono_debug_add_type (mono_defaults.streamingcontext_class);
 
-       debugger_update_symbol_file_table ();
+       mono_debug_update_symbol_file_table ();
 
        mono_debug_unlock ();
 
@@ -572,72 +515,8 @@ debug_load_method_lines (AssemblyDebugInfo* info)
        }
 }
 
-static void
-record_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offset, guint32 line)
-{
-       MonoDebugLineNumberEntry *lne = g_new0 (MonoDebugLineNumberEntry, 1);
-
-       lne->address = address;
-       lne->offset = offset;
-       lne->line = line;
-
-       g_array_append_val (minfo->jit->line_numbers, *lne);
-}
-
-static void
-debug_generate_method_lines (AssemblyDebugInfo *info, MonoDebugMethodInfo *minfo, MonoFlowGraph* cfg)
-{
-       guint32 st_address, st_line;
-       DebugMethodInfo *priv = minfo->user_data;
-       int i;
-
-       if (!priv || !info->moffsets)
-               return;
-
-       minfo->jit->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry));
-
-       st_line = priv->first_line;
-       st_address = minfo->jit->prologue_end;
-
-       /* This is the first actual code line of the method. */
-       record_line_number (minfo, st_address, 0, st_line);
-
-       /* start lines of basic blocks */
-       for (i = 0; i < cfg->block_count; ++i) {
-               int j;
-
-               for (j = 0; cfg->bblocks [i].forest && (j < cfg->bblocks [i].forest->len); ++j) {
-                       MBTree *t = (MBTree *) g_ptr_array_index (cfg->bblocks [i].forest, j);
-                       gint32 line_inc = 0, addr_inc;
-
-                       if (!i && !j) {
-                               st_line = priv->first_line;
-                               st_address = t->addr;
-                       }
-
-                       addr_inc = t->addr - st_address;
-                       st_address += addr_inc;
-
-                       if (t->cli_addr != -1) {
-                               int *lines = info->moffsets + st_line;
-                               int *k = lines;
-
-                               while ((*k != -1) && (*k < t->cli_addr))
-                                       k++;
-
-                               line_inc = k - lines;
-                       }
-
-                       st_line += line_inc;
-
-                       if (t->cli_addr != -1)
-                               record_line_number (minfo, st_address, t->cli_addr, st_line);
-               }
-       }
-}
-
-static void
-generate_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offset, int debug)
+void
+_mono_debug_generate_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offset, int debug)
 {
        int i;
 
@@ -686,74 +565,8 @@ generate_line_number (MonoDebugMethodInfo *minfo, guint32 address, guint32 offse
        }
 }
 
-static void
-debug_update_il_offsets (AssemblyDebugInfo *info, MonoDebugMethodInfo *minfo, MonoFlowGraph* cfg)
-{
-       MonoMethodHeader *header;
-       guint32 address, offset;
-       int debug = 0;
-       int i;
-
-       g_assert (info->symfile);
-       if (info->symfile->is_dynamic)
-               return;
-
-       g_assert (!minfo->jit->line_numbers);
-       minfo->jit->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry));
-
-       address = minfo->jit->prologue_end;
-       offset = 0;
-
-       g_assert (((MonoMethodNormal*)minfo->method)->header);
-       header = ((MonoMethodNormal*)minfo->method)->header;
-
-#if 0
-       if (!strcmp (minfo->method->name, "Test") || !strcmp (minfo->method->name, "Main")) {
-               MonoMethodHeader *header = ((MonoMethodNormal*)minfo->method)->header;
-
-               debug = 1;
-               mono_disassemble_code (minfo->jit->code_start, minfo->jit->code_size,
-                                      minfo->method->name);
-
-               printf ("\nDisassembly:\n%s\n", mono_disasm_code (
-                       NULL, minfo->method, header->code, header->code + header->code_size));
-               g_message (G_STRLOC ": %x - %x", minfo->jit->prologue_end, minfo->jit->epilogue_begin);
-       }
-#endif
-
-       generate_line_number (minfo, address, offset, debug);
-
-       /* start lines of basic blocks */
-       for (i = 0; i < cfg->block_count; ++i) {
-               int j;
-
-               for (j = 0; cfg->bblocks [i].forest && (j < cfg->bblocks [i].forest->len); ++j) {
-                       MBTree *t = (MBTree *) g_ptr_array_index (cfg->bblocks [i].forest, j);
-
-                       if ((t->cli_addr == -1) || (t->cli_addr == offset) || (t->addr == address))
-                               continue;
-
-                       offset = t->cli_addr;
-                       address = t->addr;
-
-                       generate_line_number (minfo, address, offset, debug);
-               }
-       }
-
-       generate_line_number (minfo, minfo->jit->epilogue_begin, header->code_size, debug);
-
-       if (debug) {
-               for (i = 0; i < minfo->jit->line_numbers->len; i++) {
-                       MonoDebugLineNumberEntry lne = g_array_index (
-                               minfo->jit->line_numbers, MonoDebugLineNumberEntry, i);
-
-                       g_message (G_STRLOC ": %x,%x,%d", lne.address, lne.offset, lne.line);
-               }
-       }
-}
-
-static AssemblyDebugInfo *
-mono_debug_get_image (MonoDebugHandle* debug, MonoImage *image)
+AssemblyDebugInfo *
+_mono_debug_get_image (MonoDebugHandle* debug, MonoImage *image)
 {
        return g_hash_table_lookup (debug->images, image);
 }
@@ -764,7 +577,7 @@ mono_debug_open_image (MonoDebugHandle* debug, MonoImage *image)
        AssemblyDebugInfo *info;
        MonoAssembly **ptr;
 
-       info = mono_debug_get_image (debug, image);
+       info = _mono_debug_get_image (debug, image);
        if (info != NULL)
                return info;
 
@@ -778,9 +591,8 @@ mono_debug_open_image (MonoDebugHandle* debug, MonoImage *image)
        info->handle = debug;
        info->methods = g_hash_table_new_full (g_direct_hash, g_direct_equal,
                                               NULL, (GDestroyNotify) free_method_info);
-
-       info->source_file = debug->source_files->len;
-       g_ptr_array_add (debug->source_files, g_strdup_printf ("%s.il", image->assembly_name));
+       info->wrapper_methods = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+                                                      NULL, (GDestroyNotify) free_wrapper_info);
 
        g_hash_table_insert (debug->images, image, info);
 
@@ -790,6 +602,9 @@ mono_debug_open_image (MonoDebugHandle* debug, MonoImage *image)
        for (ptr = image->references; ptr && *ptr; ptr++)
                mono_debug_add_assembly (*ptr, NULL);
 
+       if (image->assembly->dynamic)
+               return info;
+
        switch (info->format) {
        case MONO_DEBUG_FORMAT_STABS:
        case MONO_DEBUG_FORMAT_DWARF2:
@@ -799,22 +614,19 @@ mono_debug_open_image (MonoDebugHandle* debug, MonoImage *image)
                        g_free (dirname);
                } else
                        info->ilfile = g_strdup_printf ("%s.il", info->name);
+               info->source_file = debug->source_files->len;
+               g_ptr_array_add (debug->source_files, info->ilfile);
                break;
        case MONO_DEBUG_FORMAT_MONO:
-       case MONO_DEBUG_FORMAT_MONO_DEBUGGER:
-               info->filename = replace_suffix (image->name, "dbg");
-               if (g_file_test (info->filename, G_FILE_TEST_EXISTS))
-                       info->symfile = mono_debug_open_mono_symbol_file (info->image, info->filename, TRUE);
-               else if (info->format == MONO_DEBUG_FORMAT_MONO_DEBUGGER)
-                       info->symfile = mono_debug_create_mono_symbol_file (info->image);
-               debugger_symbol_file_table_generation++;
+               info->symfile = mono_debug_open_mono_symbol_file (info->image, running_in_the_mono_debugger);
+               mono_debugger_symbol_file_table_generation++;
                break;
 
        default:
                break;
        }
 
-       if ((debug->format != MONO_DEBUG_FORMAT_MONO) && (debug->format != MONO_DEBUG_FORMAT_MONO_DEBUGGER))
+       if (debug->format != MONO_DEBUG_FORMAT_MONO)
                debug_load_method_lines (info);
 
        return info;
@@ -836,7 +648,6 @@ mono_debug_write_symbols (MonoDebugHandle *debug)
                mono_debug_write_dwarf2 (debug);
                break;
        case MONO_DEBUG_FORMAT_MONO:
-       case MONO_DEBUG_FORMAT_MONO_DEBUGGER:
                break;
        default:
                g_assert_not_reached ();
@@ -859,8 +670,7 @@ mono_debug_make_symbols (void)
                mono_debug_write_dwarf2 (mono_debug_handle);
                break;
        case MONO_DEBUG_FORMAT_MONO:
-       case MONO_DEBUG_FORMAT_MONO_DEBUGGER:
-               debugger_update_symbol_file_table ();
+               mono_debug_update_symbol_file_table ();
                break;
        default:
                g_assert_not_reached ();
@@ -874,7 +684,6 @@ mono_debug_close_assembly (AssemblyDebugInfo* info)
 {
        switch (info->format) {
        case MONO_DEBUG_FORMAT_MONO:
-       case MONO_DEBUG_FORMAT_MONO_DEBUGGER:
                if (info->symfile != NULL)
                        mono_debug_close_mono_symbol_file (info->symfile);
                break;
@@ -882,6 +691,7 @@ mono_debug_close_assembly (AssemblyDebugInfo* info)
                break;
        }
        g_hash_table_destroy (info->methods);
+       g_hash_table_destroy (info->wrapper_methods);
        g_free (info->mlines);
        g_free (info->moffsets);
        g_free (info->name);
@@ -903,7 +713,7 @@ mono_debug_cleanup (void)
                mono_debug_write_symbols (mono_debug_handle);
 
        g_hash_table_destroy (mono_debug_handle->images);
-       g_ptr_array_free (mono_debug_handle->source_files, TRUE);
+       g_ptr_array_free (mono_debug_handle->source_files, FALSE);
        g_hash_table_destroy (mono_debug_handle->type_hash);
        g_free (mono_debug_handle->producer_name);
        g_free (mono_debug_handle->name);
@@ -992,25 +802,6 @@ il_offset_from_address (MonoDebugMethodInfo *minfo, guint32 address)
        return -1;
 }
 
-static gint32
-address_from_il_offset (MonoDebugMethodInfo *minfo, guint32 il_offset)
-{
-       int i;
-
-       if (!minfo->jit || !minfo->jit->line_numbers)
-               return -1;
-
-       for (i = minfo->jit->line_numbers->len - 1; i >= 0; i--) {
-               MonoDebugLineNumberEntry lne = g_array_index (
-                       minfo->jit->line_numbers, MonoDebugLineNumberEntry, i);
-
-               if (lne.offset <= il_offset)
-                       return lne.address;
-       }
-
-       return -1;
-}
-
 void
 mono_debug_add_type (MonoClass *klass)
 {
@@ -1019,43 +810,20 @@ mono_debug_add_type (MonoClass *klass)
        if (!mono_debug_handle)
                return;
 
-       info = mono_debug_get_image (mono_debug_handle, klass->image);
+       info = _mono_debug_get_image (mono_debug_handle, klass->image);
        g_assert (info);
 
-       if ((mono_debug_handle->format != MONO_DEBUG_FORMAT_MONO) &&
-           (mono_debug_handle->format != MONO_DEBUG_FORMAT_MONO_DEBUGGER))
+       if (mono_debug_handle->format != MONO_DEBUG_FORMAT_MONO)
                return;
 
        if (info->symfile) {
                mono_debug_lock ();
                mono_debug_symfile_add_type (info->symfile, klass);
-               if (running_in_the_mono_debugger)
-                       mono_debugger_signal (TRUE);
+               mono_debugger_event (MONO_DEBUGGER_EVENT_TYPE_ADDED, info->symfile, klass);
                mono_debug_unlock ();
        }
 }
 
-static gint32
-il_offset_from_position (MonoFlowGraph *cfg, MonoPosition *pos)
-{
-       MonoBBlock *bblock;
-       MBTree *tree;
-
-       if (pos->abs_pos == 0)
-               return -1;
-
-       if (pos->pos.bid >= cfg->block_count)
-               return -1;
-
-       bblock = &cfg->bblocks [pos->pos.bid];
-       if (pos->pos.tid >= bblock->forest->len)
-               return -1;
-
-       tree = (MBTree *) g_ptr_array_index (bblock->forest, pos->pos.tid);
-
-       return tree->cli_addr;
-}
-
 struct LookupMethodData
 {
        MonoDebugMethodInfo *minfo;
@@ -1077,8 +845,8 @@ lookup_method_func (gpointer key, gpointer value, gpointer user_data)
                data->minfo = g_hash_table_lookup (info->methods, data->method);
 }
 
-static MonoDebugMethodInfo *
-lookup_method (MonoMethod *method)
+MonoDebugMethodInfo *
+_mono_debug_lookup_method (MonoMethod *method)
 {
        struct LookupMethodData data = { NULL, method };
 
@@ -1090,118 +858,47 @@ lookup_method (MonoMethod *method)
 }
 
 void
-mono_debug_add_method (MonoFlowGraph *cfg)
+mono_debug_add_wrapper (MonoMethod *method, MonoMethod *wrapper_method)
 {
-       MonoMethod *method = cfg->method;
        MonoClass *klass = method->klass;
        AssemblyDebugInfo* info;
-       MonoDebugMethodJitInfo *jit;
        MonoDebugMethodInfo *minfo;
-       int i;
+       DebugWrapperInfo *winfo;
+       MonoDebugMethodJitInfo *jit;
 
        if (!mono_debug_handle)
                return;
 
-       mono_class_init (klass);
-
-       if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
-           (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
-           (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
-           (method->flags & METHOD_ATTRIBUTE_ABSTRACT))
+       if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
                return;
 
-       if (method->wrapper_type != MONO_WRAPPER_NONE)
-               return;
+       mono_class_init (klass);
 
-       info = mono_debug_get_image (mono_debug_handle, klass->image);
+       info = _mono_debug_get_image (mono_debug_handle, klass->image);
        g_assert (info);
 
-       minfo = lookup_method (method);
+       minfo = _mono_debug_lookup_method (method);
        if (!minfo || minfo->jit)
                return;
 
+       winfo = g_hash_table_lookup (info->wrapper_methods, wrapper_method);
+       g_assert (winfo);
+
        mono_debug_lock ();
 
        mono_debug_handle->dirty = TRUE;
 
        minfo->jit = jit = g_new0 (MonoDebugMethodJitInfo, 1);
-       jit->code_start = cfg->start;
-       jit->code_size = cfg->epilogue_end;
-       jit->prologue_end = cfg->prologue_end;
-       jit->epilogue_begin = cfg->epilog;
-       jit->num_params = method->signature->param_count;
-       jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
-
-       if (method->signature->hasthis) {
-               MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index;
-
-               jit->this_var = g_new0 (MonoDebugVarInfo, 1);
-               jit->this_var->offset = ptr->offset;
-               jit->this_var->size = ptr->size;
-       }
-
-       for (i = 0; i < jit->num_params; i++) {
-               MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index +
-                       method->signature->hasthis;
-
-               jit->params [i].offset = ptr [i].offset;
-               jit->params [i].size = ptr [i].size;
-       }
-
-       debug_generate_method_lines (info, minfo, cfg);
-       if ((info->format == MONO_DEBUG_FORMAT_MONO) || (info->format == MONO_DEBUG_FORMAT_MONO_DEBUGGER))
-               debug_update_il_offsets (info, minfo, cfg);
-
-       if (!method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
-               MonoMethodHeader *header = ((MonoMethodNormal*)method)->header;
-               MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->locals_start_index;
-               MonoDebugVarInfo *locals;
-
-               locals = g_new0 (MonoDebugVarInfo, header->num_locals);
-               for (i = 0; i < header->num_locals; i++) {
-                       gint32 begin_offset, end_offset;
-                       gint32 begin_scope, end_scope;
-
-                       if (ptr [i].reg >= 0) {
-                               locals [i].index = ptr [i].reg | MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER;
-                               locals [i].offset = 0;
-                       } else
-                               locals [i].offset = ptr [i].offset;
-
-                       locals [i].size = ptr [i].size;
-
-                       begin_offset = il_offset_from_position (cfg, &ptr [i].range.first_use);
-                       end_offset = il_offset_from_position (cfg, &ptr [i].range.last_use);
-                       if (end_offset >= 0)
-                               end_offset++;
-
-                       if (begin_offset >= 0)
-                               begin_scope = address_from_il_offset (minfo, begin_offset);
-                       else
-                               begin_scope = -1;
-                       if (end_offset >= 0)
-                               end_scope = address_from_il_offset (minfo, end_offset);
-                       else
-                               end_scope = -1;
-
-                       if (begin_scope > 0)
-                               locals [i].begin_scope = begin_scope;
-                       else
-                               locals [i].begin_scope = jit->prologue_end;
-                       if (end_scope > 0)
-                               locals [i].end_scope = end_scope;
-                       else
-                               locals [i].end_scope = jit->epilogue_begin;
-               }
-
-               jit->num_locals = header->num_locals;
-               jit->locals = locals;
-       }
+       jit->code_start = winfo->code_start;
+       jit->code_size = winfo->code_size;
+       jit->prologue_end = 0;
+       jit->epilogue_begin = winfo->code_size;
+       jit->num_params = 0;
+       jit->wrapper_addr = method->addr;
 
        if (info->symfile) {
                mono_debug_symfile_add_method (info->symfile, method);
-               if (running_in_the_mono_debugger)
-                       mono_debugger_signal (TRUE);
+               mono_debugger_event (MONO_DEBUGGER_EVENT_METHOD_ADDED, info->symfile, method);
        }
 
        mono_debug_unlock ();
@@ -1210,7 +907,7 @@ mono_debug_add_method (MonoFlowGraph *cfg)
 gchar *
 mono_debug_source_location_from_address (MonoMethod *method, guint32 address, guint32 *line_number)
 {
-       MonoDebugMethodInfo *minfo = lookup_method (method);
+       MonoDebugMethodInfo *minfo = _mono_debug_lookup_method (method);
 
        if (!minfo)
                return NULL;
@@ -1235,7 +932,7 @@ mono_debug_il_offset_from_address (MonoMethod *method, gint32 address)
        if (address < 0)
                return -1;
 
-       minfo = lookup_method (method);
+       minfo = _mono_debug_lookup_method (method);
        if (!minfo || !minfo->il_offsets)
                return -1;
 
@@ -1250,11 +947,11 @@ mono_debug_address_from_il_offset (MonoMethod *method, gint32 il_offset)
        if (il_offset < 0)
                return -1;
 
-       minfo = lookup_method (method);
+       minfo = _mono_debug_lookup_method (method);
        if (!minfo || !minfo->il_offsets)
                return -1;
 
-       return address_from_il_offset (minfo, il_offset);
+       return _mono_debug_address_from_il_offset (minfo, il_offset);
 }
 
 static void
@@ -1262,7 +959,7 @@ release_symbol_file_table ()
 {
        MonoDebuggerSymbolFileTable *temp;
 
-       if (!debugger_symbol_file_table)
+       if (!mono_debugger_symbol_file_table)
                return;
 
        /*
@@ -1271,9 +968,9 @@ release_symbol_file_table ()
         *          before freeing the area.
         */
 
-       temp = debugger_symbol_file_table;
-       debugger_symbol_file_table = NULL;
-       g_free (debugger_symbol_file_table);
+       temp = mono_debugger_symbol_file_table;
+       mono_debugger_symbol_file_table = NULL;
+       g_free (mono_debugger_symbol_file_table);
 }
 
 static void
@@ -1283,7 +980,7 @@ update_symbol_file_table_count_func (gpointer key, gpointer value, gpointer user
 
        if (!info->symfile)
                return;
-       if ((info->format != MONO_DEBUG_FORMAT_MONO) && (info->format != MONO_DEBUG_FORMAT_MONO_DEBUGGER))
+       if (info->format != MONO_DEBUG_FORMAT_MONO)
                return;
 
        ++ (* (int *) user_data);
@@ -1303,14 +1000,14 @@ update_symbol_file_table_func (gpointer key, gpointer value, gpointer user_data)
 
        if (!info->symfile)
                return;
-       if ((info->format != MONO_DEBUG_FORMAT_MONO) && (info->format != MONO_DEBUG_FORMAT_MONO_DEBUGGER))
+       if (info->format != MONO_DEBUG_FORMAT_MONO)
                return;
 
        data->symfile_table->symfiles [data->index++] = info->symfile;
 }
 
-static int
-debugger_update_symbol_file_table_internal (void)
+int
+mono_debug_update_symbol_file_table (void)
 {
        int count = 0;
        MonoDebuggerSymbolFileTable *symfile_table;
@@ -1332,7 +1029,7 @@ debugger_update_symbol_file_table_internal (void)
        symfile_table->version = MONO_SYMBOL_FILE_DYNAMIC_VERSION;
        symfile_table->total_size = size;
        symfile_table->count = count;
-       symfile_table->generation = debugger_symbol_file_table_generation;
+       symfile_table->generation = mono_debugger_symbol_file_table_generation;
        symfile_table->global_symfile = mono_debugger_global_symbol_file;
 
        data.symfile_table = symfile_table;
@@ -1340,132 +1037,13 @@ debugger_update_symbol_file_table_internal (void)
 
        g_hash_table_foreach (mono_debug_handle->images, update_symbol_file_table_func, &data);
 
-       debugger_symbol_file_table = symfile_table;
+       mono_debugger_symbol_file_table = symfile_table;
 
        mono_debug_unlock ();
 
        return TRUE;
 }
 
-static int
-debugger_update_symbol_file_table (void)
-{
-       int retval;
-
-       if (!mono_debug_handle)
-               return FALSE;
-
-       mono_debug_lock ();
-       retval = debugger_update_symbol_file_table_internal ();
-       mono_debug_unlock ();
-
-       return retval;
-}
-
-static pid_t debugger_background_thread;
-extern void mono_debugger_init_thread_debug (pid_t);
-
-/*
- * NOTE: We must not call any functions here which we ever may want to debug !
- */
-static guint32
-debugger_thread_func (gpointer ptr)
-{
-       void (*notification_code) (void) = ptr;
-       int last_generation = 0;
-
-       mono_new_thread_init (NULL, &last_generation);
-       debugger_background_thread = getpid ();
-
-       /*
-        * The parent thread waits on this condition because it needs our pid.
-        */
-       ReleaseSemaphore (debugger_start_cond, 1, NULL);
-
-       /*
-        * This mutex is locked by the parent thread until the debugger actually
-        * attached to us, so we don't need a SIGSTOP here anymore.
-        */
-       mono_debug_lock ();
-
-       while (TRUE) {
-               /* Wait for an event. */
-               mono_debug_unlock ();
-               g_assert (WaitForSingleObject (debugger_thread_cond, INFINITE) == WAIT_OBJECT_0);
-               mono_debug_lock ();
-
-               /* Reload the symbol file table if necessary. */
-               if (debugger_symbol_file_table_generation > last_generation) {
-                       debugger_update_symbol_file_table_internal ();
-                       last_generation = debugger_symbol_file_table_generation;
-               }
-
-               /*
-                * Send notification - we'll stop on a breakpoint instruction at a special
-                * address.  The debugger will reload the symbol tables while we're stopped -
-                * and owning the `debugger_thread_mutex' so that no other thread can touch
-                * them in the meantime.
-                */
-               notification_code ();
-
-               /* Clear modified and signalled flag. */
-               debugger_symbol_file_table_modified = FALSE;
-               debugger_signalled = FALSE;
-
-               if (must_send_finished) {
-                       EnterCriticalSection (&debugger_finished_mutex);
-                       ReleaseSemaphore (debugger_finished_cond, 1, NULL);
-                       must_send_finished = FALSE;
-                       LeaveCriticalSection (&debugger_finished_mutex);
-               }
-       }
-
-       return 0;
-}
-
-static void
-initialize_debugger_support ()
-{
-       guint8 *buf, *ptr;
-       HANDLE thread;
-
-       if (running_in_the_mono_debugger)
-               return;
-       debugger_init_threads ();
-       running_in_the_mono_debugger = TRUE;
-
-       ptr = buf = g_malloc0 (16);
-       x86_breakpoint (buf);
-       debugger_notification_address = buf;
-       x86_ret (buf);
-
-       /*
-        * We keep this mutex until mono_debugger_jit_exec().
-        */
-       mono_debug_lock ();
-
-       /*
-        * This mutex is only unlocked in mono_debugger_wait().
-        */
-       EnterCriticalSection (&debugger_finished_mutex);
-
-       thread = CreateThread (NULL, 0, debugger_thread_func, ptr, FALSE, NULL);
-       g_assert (thread);
-
-       /*
-        * Wait until the background thread set its pid.
-        */
-       g_assert (WaitForSingleObject (debugger_start_cond, INFINITE) == WAIT_OBJECT_0);
-
-       /*
-        * Wait until the debugger thread has actually been started and we
-        * have its pid, then actually start the background thread.
-        */
-#ifndef PLATFORM_WIN32
-       mono_debugger_init_thread_debug (debugger_background_thread);
-#endif
-}
-
 static GPtrArray *breakpoints = NULL;
 
 int
@@ -1487,20 +1065,8 @@ mono_insert_breakpoint_full (MonoMethodDesc *desc, gboolean use_trampoline)
        return info->index;
 }
 
-static guint64
-debugger_insert_breakpoint (guint64 method_argument, const gchar *string_argument)
-{
-       MonoMethodDesc *desc;
-
-       desc = mono_method_desc_new (string_argument, FALSE);
-       if (!desc)
-               return 0;
-
-       return mono_insert_breakpoint_full (desc, TRUE);
-}
-
-static guint64
-debugger_remove_breakpoint (guint64 breakpoint)
+int
+mono_remove_breakpoint (int breakpoint_id)
 {
        int i;
 
@@ -1510,7 +1076,7 @@ debugger_remove_breakpoint (guint64 breakpoint)
        for (i = 0; i < breakpoints->len; i++) {
                MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i);
 
-               if (info->index != breakpoint)
+               if (info->index != breakpoint_id)
                        continue;
 
                mono_method_desc_free (info->desc);
@@ -1522,24 +1088,6 @@ debugger_remove_breakpoint (guint64 breakpoint)
        return 0;
 }
 
-static gpointer
-debugger_compile_method (MonoMethod *method)
-{
-       gpointer retval;
-
-       mono_debug_lock ();
-       retval = mono_compile_method (method);
-       mono_debugger_signal (FALSE);
-       mono_debug_unlock ();
-       return retval;
-}
-
-int
-mono_remove_breakpoint (int breakpoint_id)
-{
-       return debugger_remove_breakpoint (breakpoint_id);
-}
-
 int
 mono_insert_breakpoint (const gchar *method_name, gboolean include_namespace)
 {
@@ -1578,49 +1126,5 @@ mono_method_has_breakpoint (MonoMethod* method, gboolean use_trampoline)
 void
 mono_debugger_trampoline_breakpoint_callback (void)
 {
-       mono_debug_lock ();
-       must_send_finished = TRUE;
-       mono_debugger_signal (FALSE);
-       mono_debug_unlock ();
-
-       mono_debugger_wait ();
-}
-
-/*
- * This is a custom version of mono_jit_exec() which is used when we're being run inside
- * the Mono Debugger.
- */
-int 
-mono_debugger_jit_exec (MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[])
-{
-       MonoImage *image = assembly->image;
-       MonoMethod *method;
-       gpointer addr;
-       int retval;
-
-       method = mono_get_method (image, mono_image_get_entry_point (image), NULL);
-
-       addr = mono_compile_method (method);
-
-       /*
-        * The mutex has been locked in initialize_debugger_support(); we keep it locked
-        * until we compiled the main method and signalled the debugger.
-        */
-       must_send_finished = TRUE;
-       mono_debugger_signal (TRUE);
-       mono_debug_unlock ();
-
-       /*
-        * Wait until the debugger has loaded the initial symbol tables.
-        */
-       mono_debugger_wait ();
-
-       retval = mono_runtime_run_main (method, argc, argv, NULL);
-
-       /*
-        * Kill the background thread.
-        */
-       kill (debugger_background_thread, SIGKILL);
-
-       return retval;
+       mono_debugger_event (MONO_DEBUGGER_EVENT_BREAKPOINT_TRAMPOLINE, NULL, NULL);
 }