2009-01-13 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / metadata / mono-debug.c
index 0aa0ad4b49ec8ca89c4cd375fef95a90ba3d22ce..71db1c4fb192c50e2b42a6ff534a859c11e4753a 100644 (file)
        }
 #define WRITE_UNALIGNED(type, addr, val) \
        memcpy(addr, &val, sizeof(type))
+#define READ_UNALIGNED(type, addr, val) \
+       memcpy(&val, addr, sizeof(type))
 #else
 #define RETURN_UNALIGNED(type, addr) \
        return *(type*)(p + offset);
 #define WRITE_UNALIGNED(type, addr, val) \
        (*(type *)(addr) = (val))
+#define READ_UNALIGNED(type, addr, val) \
+       val = (*(type *)(addr))
 #endif
 
 typedef enum {
        MONO_DEBUG_DATA_ITEM_UNKNOWN            = 0,
        MONO_DEBUG_DATA_ITEM_CLASS,
-       MONO_DEBUG_DATA_ITEM_METHOD
+       MONO_DEBUG_DATA_ITEM_METHOD,
+       MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE
 } MonoDebugDataItemType;
 
 typedef struct _MonoDebugDataChunk MonoDebugDataChunk;
@@ -79,11 +84,21 @@ struct _MonoDebugMethodAddress {
        guint8 data [MONO_ZERO_LEN_ARRAY];
 };
 
+struct _MonoDebugClassEntry {
+       guint32 size;
+       guint8 data [MONO_ZERO_LEN_ARRAY];
+};
+
+typedef struct {
+       gpointer code;
+       guint32 size;
+} MonoDebugDelegateTrampolineEntry;
+
 MonoSymbolTable *mono_symbol_table = NULL;
 MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
-gint32 mono_debug_debugger_version = 2;
+gint32 mono_debug_debugger_version = 4;
+gint32 _mono_debug_using_mono_debugger = 0;
 
-static gboolean in_the_mono_debugger = FALSE;
 static gboolean mono_debug_initialized = FALSE;
 GHashTable *mono_debug_handles = NULL;
 
@@ -95,13 +110,12 @@ static MonoDebugHandle     *mono_debug_open_image      (MonoImage *image, const
 static MonoDebugHandle     *_mono_debug_get_image      (MonoImage *image);
 static void                 mono_debug_add_assembly    (MonoAssembly *assembly,
                                                        gpointer user_data);
-static void                 mono_debug_start_add_type  (MonoClass *klass);
 static void                 mono_debug_add_type        (MonoClass *klass);
 
 void _mono_debug_init_corlib (MonoDomain *domain);
 
 extern void (*mono_debugger_class_init_func) (MonoClass *klass);
-extern void (*mono_debugger_start_class_init_func) (MonoClass *klass);
+extern void (*mono_debugger_class_loaded_methods_func) (MonoClass *klass);
 
 static MonoDebugDataTable *
 create_data_table (MonoDomain *domain)
@@ -120,8 +134,10 @@ create_data_table (MonoDomain *domain)
 
        table->first_chunk = table->current_chunk = chunk;
 
-       mono_debug_list_add (&mono_symbol_table->data_tables, table);
-       g_hash_table_insert (data_table_hash, domain, table);
+       if (domain) {
+               mono_debug_list_add (&mono_symbol_table->data_tables, table);
+               g_hash_table_insert (data_table_hash, domain, table);
+       }
 
        return table;
 }
@@ -134,6 +150,7 @@ free_header_data (gpointer key, gpointer value, gpointer user_data)
        if (header->wrapper_data) {
                g_free ((gpointer)header->wrapper_data->method_name);
                g_free ((gpointer)header->wrapper_data->cil_code);
+               g_slist_free (header->address_list);
                g_free (header->wrapper_data);
        }
 }
@@ -178,9 +195,9 @@ free_debug_handle (MonoDebugHandle *handle)
        if (handle->symfile)
                mono_debug_close_mono_symbol_file (handle->symfile);
        /* decrease the refcount added with mono_image_addref () */
+       free_data_table (handle->type_table);
        mono_image_close (handle->image);
        g_free (handle->image_file);
-       g_free (handle->_priv);
        g_free (handle);
 }
 
@@ -198,15 +215,14 @@ mono_debug_init (MonoDebugFormat format)
 
        mono_debug_initialized = TRUE;
        mono_debug_format = format;
-       in_the_mono_debugger = format == MONO_DEBUG_FORMAT_DEBUGGER;
 
-       mono_debugger_initialize (in_the_mono_debugger);
+       mono_debugger_initialize (_mono_debug_using_mono_debugger);
 
        mono_debugger_lock ();
 
        mono_symbol_table = g_new0 (MonoSymbolTable, 1);
        mono_symbol_table->magic = MONO_DEBUGGER_MAGIC;
-       mono_symbol_table->version = MONO_DEBUGGER_VERSION;
+       mono_symbol_table->version = MONO_DEBUGGER_MAJOR_VERSION;
        mono_symbol_table->total_size = sizeof (MonoSymbolTable);
 
        mono_debug_handles = g_hash_table_new_full
@@ -215,12 +231,12 @@ mono_debug_init (MonoDebugFormat format)
        data_table_hash = g_hash_table_new_full (
                NULL, NULL, NULL, (GDestroyNotify) free_data_table);
 
-       mono_symbol_table->type_table = create_data_table (NULL);
-
-       mono_debugger_start_class_init_func = mono_debug_start_add_type;
        mono_debugger_class_init_func = mono_debug_add_type;
+       mono_debugger_class_loaded_methods_func = mono_debugger_class_initialized;
        mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
 
+       mono_symbol_table->global_data_table = create_data_table (NULL);
+
        mono_debugger_unlock ();
 }
 
@@ -248,14 +264,12 @@ mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents,
 gboolean
 mono_debug_using_mono_debugger (void)
 {
-       return in_the_mono_debugger;
+       return _mono_debug_using_mono_debugger;
 }
 
 void
 mono_debug_cleanup (void)
 {
-       mono_debugger_cleanup ();
-
        if (mono_debug_handles)
                g_hash_table_destroy (mono_debug_handles);
        mono_debug_handles = NULL;
@@ -363,7 +377,10 @@ mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
        mono_image_addref (image);
        handle->image_file = g_strdup (mono_image_get_filename (image));
 
-       handle->symfile = mono_debug_open_mono_symbols (handle, raw_contents, size, in_the_mono_debugger);
+       handle->type_table = create_data_table (NULL);
+
+       handle->symfile = mono_debug_open_mono_symbols (
+               handle, raw_contents, size, _mono_debug_using_mono_debugger);
 
        mono_debug_list_add (&mono_symbol_table->symbol_files, handle);
 
@@ -524,6 +541,8 @@ write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
        write_leb128 (var->size, ptr, &ptr);
        write_leb128 (var->begin_scope, ptr, &ptr);
        write_leb128 (var->end_scope, ptr, &ptr);
+       WRITE_UNALIGNED (gpointer, ptr, var->type);
+       ptr += sizeof (gpointer);
        *rptr = ptr;
 }
 
@@ -539,7 +558,6 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
        guint8 buffer [BUFSIZ];
        guint8 *ptr, *oldptr;
        guint32 i, size, total_size, max_size;
-       gint32 last_il_offset = 0, last_native_offset = 0;
        gboolean is_wrapper = FALSE;
 
        mono_debugger_lock ();
@@ -557,10 +575,8 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
                is_wrapper = TRUE;
        }
 
-       jit->num_lexical_blocks = minfo ? minfo->num_lexical_blocks : 0;
-
-       max_size = 24 + 8 * jit->num_line_numbers + 16 * jit->num_lexical_blocks +
-               20 * (1 + jit->num_params + jit->num_locals);
+       max_size = 24 + 8 * jit->num_line_numbers +
+               (20 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals);
 
        if (max_size > BUFSIZ)
                ptr = oldptr = g_malloc (max_size);
@@ -574,41 +590,8 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
        for (i = 0; i < jit->num_line_numbers; i++) {
                MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
 
-               write_sleb128 (lne->il_offset - last_il_offset, ptr, &ptr);
-               write_sleb128 (lne->native_offset - last_native_offset, ptr, &ptr);
-
-               last_il_offset = lne->il_offset;
-               last_native_offset = lne->native_offset;
-       }
-
-       jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks);
-       for (i = 0; i < jit->num_lexical_blocks; i ++) {
-               MonoDebugLexicalBlockEntry *jit_lbe = &jit->lexical_blocks [i];
-               MonoSymbolFileLexicalBlockEntry *minfo_lbe = &minfo->lexical_blocks [i];
-               jit_lbe->il_start_offset = read32 (&(minfo_lbe->_start_offset));
-               jit_lbe->native_start_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_start_offset);
-
-               jit_lbe->il_end_offset = read32 (&(minfo_lbe->_end_offset));
-               jit_lbe->native_end_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_end_offset);
-       }
-
-       last_il_offset = 0;
-       last_native_offset = 0;
-       write_leb128 (jit->num_lexical_blocks, ptr, &ptr);
-       for (i = 0; i < jit->num_lexical_blocks; i++) {
-               MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i];
-
-               write_sleb128 (lbe->il_start_offset - last_il_offset, ptr, &ptr);
-               write_sleb128 (lbe->native_start_offset - last_native_offset, ptr, &ptr);
-
-               last_il_offset = lbe->il_start_offset;
-               last_native_offset = lbe->native_start_offset;
-
-               write_sleb128 (lbe->il_end_offset - last_il_offset, ptr, &ptr);
-               write_sleb128 (lbe->native_end_offset - last_native_offset, ptr, &ptr);
-
-               last_il_offset = lbe->il_end_offset;
-               last_native_offset = lbe->native_end_offset;
+               write_sleb128 (lne->il_offset, ptr, &ptr);
+               write_sleb128 (lne->native_offset, ptr, &ptr);
        }
 
        *ptr++ = jit->this_var ? 1 : 0;
@@ -679,6 +662,27 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
        return address;
 }
 
+void
+mono_debug_add_delegate_trampoline (gpointer code, int size)
+{
+       MonoDebugDelegateTrampolineEntry *entry;
+
+       if (!mono_debug_initialized)
+               return;
+
+       mono_debugger_lock ();
+
+       entry = (MonoDebugDelegateTrampolineEntry *) allocate_data_item (
+               mono_symbol_table->global_data_table, MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE,
+               sizeof (MonoDebugDelegateTrampolineEntry));
+       entry->code = code;
+       entry->size = size;
+
+       write_data_item (mono_symbol_table->global_data_table, (guint8 *) entry);
+
+       mono_debugger_unlock ();
+}
+
 static inline guint32
 read_leb128 (guint8 *ptr, guint8 **rptr)
 {
@@ -729,14 +733,28 @@ read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
        var->size = read_leb128 (ptr, &ptr);
        var->begin_scope = read_leb128 (ptr, &ptr);
        var->end_scope = read_leb128 (ptr, &ptr);
+       READ_UNALIGNED (gpointer, ptr, var->type);
+       ptr += sizeof (gpointer);
        *rptr = ptr;
 }
 
+void
+mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
+{
+       if (!jit)
+               return;
+       g_free (jit->line_numbers);
+       g_free (jit->this_var);
+       g_free (jit->params);
+       g_free (jit->locals);
+       g_free (jit);
+}
+
 static MonoDebugMethodJitInfo *
 mono_debug_read_method (MonoDebugMethodAddress *address)
 {
        MonoDebugMethodJitInfo *jit;
-       guint32 i, il_offset = 0, native_offset = 0;
+       guint32 i;
        guint8 *ptr;
 
        jit = g_new0 (MonoDebugMethodJitInfo, 1);
@@ -754,31 +772,8 @@ mono_debug_read_method (MonoDebugMethodAddress *address)
        for (i = 0; i < jit->num_line_numbers; i++) {
                MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
 
-               il_offset += read_sleb128 (ptr, &ptr);
-               native_offset += read_sleb128 (ptr, &ptr);
-
-               lne->il_offset = il_offset;
-               lne->native_offset = native_offset;
-       }
-
-       il_offset = 0;
-       native_offset = 0;
-       jit->num_lexical_blocks = read_leb128 (ptr, &ptr);
-       jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks);
-       for (i = 0; i < jit->num_lexical_blocks; i ++) {
-               MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i];
-
-               il_offset += read_sleb128 (ptr, &ptr);
-               native_offset += read_sleb128 (ptr, &ptr);
-
-               lbe->il_start_offset = il_offset;
-               lbe->native_start_offset = native_offset;
-
-               il_offset += read_sleb128 (ptr, &ptr);
-               native_offset += read_sleb128 (ptr, &ptr);
-
-               lbe->il_end_offset = il_offset;
-               lbe->native_end_offset = native_offset;
+               lne->il_offset = read_sleb128 (ptr, &ptr);
+               lne->native_offset = read_sleb128 (ptr, &ptr);
        }
 
        if (*ptr++) {
@@ -799,20 +794,6 @@ mono_debug_read_method (MonoDebugMethodAddress *address)
        return jit;
 }
 
-/*
- * This is called via the `mono_debugger_class_init_func' from mono_class_init() each time
- * a new class is initialized.
- */
-static void
-mono_debug_start_add_type (MonoClass *klass)
-{
-       MonoDebugHandle *handle;
-
-       handle = _mono_debug_get_image (klass->image);
-       if (!handle)
-               return;
-}
-
 static void
 mono_debug_add_type (MonoClass *klass)
 {
@@ -854,14 +835,13 @@ mono_debug_add_type (MonoClass *klass)
        g_assert (total_size + 9 < DATA_TABLE_CHUNK_SIZE);
 
        entry = (MonoDebugClassEntry *) allocate_data_item (
-               mono_symbol_table->type_table, MONO_DEBUG_DATA_ITEM_CLASS, total_size);
+               handle->type_table, MONO_DEBUG_DATA_ITEM_CLASS, total_size);
 
        entry->size = total_size;
-       entry->symfile_id = handle->index;
 
        memcpy (&entry->data, oldptr, size);
 
-       write_data_item (mono_symbol_table->type_table, (guint8 *) entry);
+       write_data_item (handle->type_table, (guint8 *) entry);
 
        if (max_size > BUFSIZ)
                g_free (oldptr);
@@ -888,6 +868,10 @@ MonoDebugMethodJitInfo *
 mono_debug_find_method (MonoMethod *method, MonoDomain *domain)
 {
        MonoDebugMethodJitInfo *res;
+
+       if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
+               return NULL;
+
        mono_debugger_lock ();
        res = find_method (method, domain);
        mono_debugger_unlock ();
@@ -923,7 +907,7 @@ mono_debug_lookup_method_addresses (MonoMethod *method)
        GSList *list;
        guint8 *ptr;
 
-       g_assert (mono_debug_debugger_version == 2);
+       g_assert (mono_debug_debugger_version == 4);
 
        mono_debugger_lock ();
 
@@ -969,15 +953,19 @@ il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_o
 
        jit = find_method (method, domain);
        if (!jit || !jit->line_numbers)
-               return -1;
+               goto cleanup_and_fail;
 
        for (i = jit->num_line_numbers - 1; i >= 0; i--) {
                MonoDebugLineNumberEntry lne = jit->line_numbers [i];
 
-               if (lne.native_offset <= native_offset)
+               if (lne.native_offset <= native_offset) {
+                       mono_debug_free_method_jit_info (jit);
                        return lne.il_offset;
+               }
        }
 
+cleanup_and_fail:
+       mono_debug_free_method_jit_info (jit);
        return -1;
 }