* culture-info.h: Make defines more consistent, add calendar data
[mono.git] / mono / metadata / mono-debug-debugger.c
index 8fefc5e98485dca6a5b6d4d735464559287c0119..f8f6a8f433941f20a97fea576498c6f37255c092 100644 (file)
@@ -8,6 +8,7 @@
 #include <mono/metadata/exception.h>
 #include <mono/metadata/mono-debug.h>
 #include <mono/metadata/mono-debug-debugger.h>
+#include <mono/metadata/mono-endian.h>
 
 #define SYMFILE_TABLE_CHUNK_SIZE       16
 #define RANGE_TABLE_CHUNK_SIZE         256
 #define TYPE_TABLE_PTR_CHUNK_SIZE      256
 #define TYPE_TABLE_CHUNK_SIZE          65536
 
+static guint32 debugger_lock_level = 0;
 static CRITICAL_SECTION debugger_lock_mutex;
 static gboolean mono_debugger_initialized = FALSE;
 
+static gboolean must_reload_symtabs = FALSE;
+
 static GHashTable *images = NULL;
 static GHashTable *type_table = NULL;
 static GHashTable *class_table = NULL;
@@ -47,7 +51,8 @@ void (*mono_debugger_event_handler) (MonoDebuggerEvent event, gpointer data, gui
 MonoDebuggerIOLayer mono_debugger_io_layer = {
        InitializeCriticalSection, DeleteCriticalSection, TryEnterCriticalSection,
        EnterCriticalSection, LeaveCriticalSection, WaitForSingleObject, SignalObjectAndWait,
-       WaitForMultipleObjects, CreateSemaphore, ReleaseSemaphore, CreateThread
+       WaitForMultipleObjects, CreateSemaphore, ReleaseSemaphore, CreateThread,
+       GetCurrentThreadId
 };
 
 #endif
@@ -55,15 +60,34 @@ MonoDebuggerIOLayer mono_debugger_io_layer = {
 void
 mono_debugger_lock (void)
 {
-       if (mono_debugger_initialized)
-               EnterCriticalSection (&debugger_lock_mutex);
+       if (!mono_debugger_initialized) {
+               debugger_lock_level++;
+               return;
+       }
+
+       EnterCriticalSection (&debugger_lock_mutex);
+       debugger_lock_level++;
 }
 
 void
 mono_debugger_unlock (void)
 {
-       if (mono_debugger_initialized)
-               LeaveCriticalSection (&debugger_lock_mutex);
+       g_assert (debugger_lock_level > 0);
+
+       if (!mono_debugger_initialized) {
+               debugger_lock_level--;
+               return;
+       }
+
+       if (debugger_lock_level == 1) {
+               if (must_reload_symtabs) {
+                       mono_debugger_event (MONO_DEBUGGER_EVENT_RELOAD_SYMTABS, NULL, 0);
+                       must_reload_symtabs = FALSE;
+               }
+       }
+
+       debugger_lock_level--;
+       LeaveCriticalSection (&debugger_lock_mutex);
 }
 
 static MonoDebuggerSymbolFile *
@@ -82,6 +106,8 @@ allocate_symbol_file_entry (MonoDebuggerSymbolTable *table)
 
        symfile = g_new0 (MonoDebuggerSymbolFile, 1);
        symfile->index = table->num_symbol_files;
+       symfile->range_entry_size = sizeof (MonoDebuggerRangeInfo);
+       symfile->class_entry_size = sizeof (MonoDebuggerClassInfo);
        table->symbol_files [table->num_symbol_files++] = symfile;
        return symfile;
 }
@@ -94,6 +120,7 @@ mono_debugger_initialize (MonoDomain *domain)
        g_assert (!mono_debugger_initialized);
 
        InitializeCriticalSection (&debugger_lock_mutex);
+       mono_debugger_initialized = TRUE;
 
        mono_debugger_lock ();
 
@@ -110,7 +137,6 @@ mono_debugger_initialize (MonoDomain *domain)
        class_info_table = g_hash_table_new (g_direct_hash, g_direct_equal);
 
        mono_debugger_symbol_table = symbol_table;
-       mono_debugger_initialized = TRUE;
 
        mono_debugger_unlock ();
 }
@@ -124,8 +150,10 @@ mono_debugger_add_symbol_file (MonoDebugHandle *handle)
        mono_debugger_lock ();
 
        info = g_hash_table_lookup (images, handle->image);
-       if (info)
+       if (info) {
+               mono_debugger_unlock ();
                return info;
+       }
 
        info = allocate_symbol_file_entry (mono_debugger_symbol_table);
        info->symfile = handle->symfile;
@@ -333,7 +361,7 @@ mono_debugger_add_type (MonoDebuggerSymbolFile *symfile, MonoClass *klass)
 
        cinfo->type_info = write_class (mono_debugger_symbol_table, klass);
 
-       mono_debugger_event (MONO_DEBUGGER_EVENT_TYPE_ADDED, NULL, 0);
+       must_reload_symtabs = TRUE;
        mono_debugger_unlock ();
 }
 
@@ -364,7 +392,7 @@ mono_debugger_add_method (MonoDebuggerSymbolFile *symfile, MonoDebugMethodInfo *
 
        size = sizeof (MonoSymbolFileMethodAddress);
 
-       num_variables = minfo->entry->num_parameters + minfo->entry->num_locals;
+       num_variables = read32(&(minfo->entry->_num_parameters)) + read32(&(minfo->entry->_num_locals));
        has_this = jit->this_var != NULL;
 
        variable_size = (num_variables + has_this) * sizeof (MonoDebugVarInfo);
@@ -381,7 +409,7 @@ mono_debugger_add_method (MonoDebuggerSymbolFile *symfile, MonoDebugMethodInfo *
                size += line_size;
        }
 
-       block_size = minfo->entry->num_lexical_blocks * sizeof (MonoSymbolFileLexicalBlockEntry);
+       block_size = read32(&(minfo->entry->_num_lexical_blocks)) * sizeof (MonoSymbolFileLexicalBlockEntry);
        block_offset = size;
        size += block_size;
 
@@ -389,12 +417,12 @@ mono_debugger_add_method (MonoDebuggerSymbolFile *symfile, MonoDebugMethodInfo *
        ptr = (guint8 *) address;
 
        block = (MonoSymbolFileLexicalBlockEntry *)
-               (symfile->symfile->raw_contents + minfo->entry->lexical_block_table_offset);
+               (symfile->symfile->raw_contents + read32(&(minfo->entry->_lexical_block_table_offset)));
        block_table = (MonoDebugLexicalBlockEntry *) (ptr + block_offset);
 
-       for (i = 0; i < minfo->entry->num_lexical_blocks; i++, block++) {
-               block_table [i].start_address = _mono_debug_address_from_il_offset (jit, block->start_offset);
-               block_table [i].end_address = _mono_debug_address_from_il_offset (jit, block->end_offset);
+       for (i = 0; i < read32(&(minfo->entry->_num_lexical_blocks)); i++, block++) {
+               block_table [i].start_address = _mono_debug_address_from_il_offset (jit, read32(&(block->_start_offset)));
+               block_table [i].end_address = _mono_debug_address_from_il_offset (jit, read32(&(block->_end_offset)));
        }
 
        address->size = size;
@@ -432,17 +460,17 @@ mono_debugger_add_method (MonoDebuggerSymbolFile *symfile, MonoDebugMethodInfo *
        type_table = (guint32 *) (ptr + type_offset);
 
        type_index_table = (guint32 *)
-               (symfile->symfile->raw_contents + minfo->entry->type_index_table_offset);
+               (symfile->symfile->raw_contents + read32(&(minfo->entry->_type_index_table_offset)));
 
        if (jit->this_var)
                *var_table++ = *jit->this_var;
        *type_table++ = write_type (mono_debugger_symbol_table, &minfo->method->klass->this_arg);
 
-       if (jit->num_params != minfo->entry->num_parameters) {
+       if (jit->num_params != read32(&(minfo->entry->_num_parameters))) {
                g_warning (G_STRLOC ": Method %s.%s has %d parameters, but symbol file claims it has %d.",
                           minfo->method->klass->name, minfo->method->name, jit->num_params,
-                          minfo->entry->num_parameters);
-               var_table += minfo->entry->num_parameters;
+                          read32(&(minfo->entry->_num_parameters)));
+               var_table += read32(&(minfo->entry->_num_parameters));
        } else {
                for (i = 0; i < jit->num_params; i++) {
                        *var_table++ = jit->params [i];
@@ -450,20 +478,20 @@ mono_debugger_add_method (MonoDebuggerSymbolFile *symfile, MonoDebugMethodInfo *
                }
        }
 
-       if (jit->num_locals < minfo->entry->num_locals) {
+       if (jit->num_locals < read32(&(minfo->entry->_num_locals))) {
                g_warning (G_STRLOC ": Method %s.%s has %d locals, but symbol file claims it has %d.",
                           minfo->method->klass->name, minfo->method->name, jit->num_locals,
-                          minfo->entry->num_locals);
-               var_table += minfo->entry->num_locals;
+                          read32(&(minfo->entry->_num_locals)));
+               var_table += read32(&(minfo->entry->_num_locals));
        } else {
-               g_assert ((header != NULL) || (minfo->entry->num_locals == 0));
-               for (i = 0; i < minfo->entry->num_locals; i++) {
+               g_assert ((header != NULL) || (minfo->entry->_num_locals == 0));
+               for (i = 0; i < read32(&(minfo->entry->_num_locals)); i++) {
                        *var_table++ = jit->locals [i];
                        *type_table++ = write_type (mono_debugger_symbol_table, header->locals [i]);
                }
        }
 
-       mono_debugger_event (MONO_DEBUGGER_EVENT_METHOD_ADDED, NULL, 0);
+       must_reload_symtabs = TRUE;
 }
 
 static MonoDebuggerRangeInfo *
@@ -472,8 +500,6 @@ allocate_range_entry (MonoDebuggerSymbolFile *symfile)
        MonoDebuggerRangeInfo *retval;
        guint32 size, chunks;
 
-       symfile->range_entry_size = sizeof (MonoDebuggerRangeInfo);
-
        if (!symfile->range_table) {
                size = sizeof (MonoDebuggerRangeInfo) * RANGE_TABLE_CHUNK_SIZE;
                symfile->range_table = g_malloc0 (size);
@@ -499,8 +525,6 @@ allocate_class_entry (MonoDebuggerSymbolFile *symfile)
        MonoDebuggerClassInfo *retval;
        guint32 size, chunks;
 
-       symfile->class_entry_size = sizeof (MonoDebuggerClassInfo);
-
        if (!symfile->class_table) {
                size = sizeof (MonoDebuggerClassInfo) * CLASS_TABLE_CHUNK_SIZE;
                symfile->class_table = g_malloc0 (size);
@@ -653,9 +677,12 @@ write_class (MonoDebuggerSymbolTable *table, MonoClass *klass)
 
                if (method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME)
                        continue;
-               if (g_hash_table_lookup (method_slots, GUINT_TO_POINTER (method->slot)))
-                       continue;
-               g_hash_table_insert (method_slots, GUINT_TO_POINTER (method->slot), method);
+               
+               if (method->slot != -1) {
+                       if (g_hash_table_lookup (method_slots, GUINT_TO_POINTER (method->slot)))
+                               continue;
+                       g_hash_table_insert (method_slots, GUINT_TO_POINTER (method->slot), method);
+               }
 
                if (method->flags & METHOD_ATTRIBUTE_STATIC) {
                        ++num_static_methods;
@@ -1169,8 +1196,11 @@ mono_debugger_lookup_type (const gchar *type_name)
                MonoDebuggerSymbolFile *symfile = mono_debugger_symbol_table->symbol_files [i];
                MonoType *type;
                guint32 offset;
+               gchar *name;
 
-               type = mono_reflection_type_from_name (type_name, symfile->image);
+               name = g_strdup (type_name);
+               type = mono_reflection_type_from_name (name, symfile->image);
+               g_free (name);
                if (!type)
                        continue;
 
@@ -1183,3 +1213,34 @@ mono_debugger_lookup_type (const gchar *type_name)
        mono_debugger_unlock ();
        return 0;
 }
+
+gint32
+mono_debugger_lookup_assembly (const gchar *name)
+{
+       MonoAssembly *assembly;
+       MonoImageOpenStatus status;
+       int i;
+
+       mono_debugger_lock ();
+
+ again:
+       for (i = 0; i < mono_debugger_symbol_table->num_symbol_files; i++) {
+               MonoDebuggerSymbolFile *symfile = mono_debugger_symbol_table->symbol_files [i];
+
+               if (!strcmp (symfile->image_file, name)) {
+                       mono_debugger_unlock ();
+                       return i;
+               }
+       }
+
+       assembly = mono_assembly_open (name, &status);
+
+       if (status != MONO_IMAGE_OK) {
+               g_warning (G_STRLOC ": Cannot open image `%s'", name);
+               mono_debugger_unlock ();
+               return -1;
+       }
+
+       must_reload_symtabs = TRUE;
+       goto again;
+}