This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mono / metadata / mono-debug-debugger.c
1 #include <config.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <mono/metadata/assembly.h>
5 #include <mono/metadata/metadata.h>
6 #include <mono/metadata/tabledefs.h>
7 #include <mono/metadata/tokentype.h>
8 #include <mono/metadata/appdomain.h>
9 #include <mono/metadata/gc-internal.h>
10 #include <mono/metadata/object-internals.h>
11 #include <mono/metadata/class-internals.h>
12 #include <mono/metadata/exception.h>
13 #include <mono/metadata/mono-debug.h>
14 #include <mono/metadata/mono-debug-debugger.h>
15 #include <mono/metadata/mono-endian.h>
16
17 #define SYMFILE_TABLE_CHUNK_SIZE        16
18 #define RANGE_TABLE_CHUNK_SIZE          256
19 #define CLASS_TABLE_CHUNK_SIZE          256
20 #define TYPE_TABLE_PTR_CHUNK_SIZE       256
21 #define TYPE_TABLE_CHUNK_SIZE           65536
22
23 static guint32 debugger_lock_level = 0;
24 static CRITICAL_SECTION debugger_lock_mutex;
25 static gboolean mono_debugger_initialized = FALSE;
26 static MonoObject *last_exception = NULL;
27
28 static gboolean must_reload_symtabs = FALSE;
29
30 static GHashTable *images = NULL;
31 static GHashTable *type_table = NULL;
32 static GHashTable *class_table = NULL;
33 static GHashTable *class_info_table = NULL;
34
35 static MonoDebuggerRangeInfo *allocate_range_entry (MonoDebuggerSymbolFile *symfile);
36 static MonoDebuggerClassInfo *allocate_class_entry (MonoDebuggerSymbolFile *symfile);
37 static guint32 allocate_type_entry (MonoDebuggerSymbolTable *table, guint32 size, guint8 **ptr);
38 static guint32 write_type (MonoDebuggerSymbolTable *table, MonoType *type);
39 static guint32 write_class (MonoDebuggerSymbolTable *table, MonoClass *klass);
40
41 MonoDebuggerSymbolTable *mono_debugger_symbol_table = NULL;
42 void (*mono_debugger_event_handler) (MonoDebuggerEvent event, gpointer data, guint32 arg) = NULL;
43
44 #define WRITE_UINT32(ptr,value) G_STMT_START {  \
45         * ((guint32 *) ptr) = value;            \
46         ptr += 4;                               \
47 } G_STMT_END
48
49 #define WRITE_POINTER(ptr,value) G_STMT_START { \
50         * ((gpointer *) ptr) = value;           \
51         ptr += sizeof (gpointer);               \
52 } G_STMT_END
53
54 #ifndef PLATFORM_WIN32
55
56 MonoDebuggerIOLayer mono_debugger_io_layer = {
57         InitializeCriticalSection, DeleteCriticalSection, TryEnterCriticalSection,
58         EnterCriticalSection, LeaveCriticalSection, WaitForSingleObjectEx, SignalObjectAndWait,
59         WaitForMultipleObjectsEx, CreateSemaphore, ReleaseSemaphore, CreateThread,
60         GetCurrentThreadId
61 };
62
63 #endif
64
65 void
66 mono_debugger_lock (void)
67 {
68         if (!mono_debugger_initialized) {
69                 debugger_lock_level++;
70                 return;
71         }
72
73         EnterCriticalSection (&debugger_lock_mutex);
74         debugger_lock_level++;
75 }
76
77 void
78 mono_debugger_unlock (void)
79 {
80         g_assert (debugger_lock_level > 0);
81
82         if (!mono_debugger_initialized) {
83                 debugger_lock_level--;
84                 return;
85         }
86
87         if (debugger_lock_level == 1) {
88                 if (must_reload_symtabs) {
89                         mono_debugger_event (MONO_DEBUGGER_EVENT_RELOAD_SYMTABS, NULL, 0);
90                         must_reload_symtabs = FALSE;
91                 }
92         }
93
94         debugger_lock_level--;
95         LeaveCriticalSection (&debugger_lock_mutex);
96 }
97
98 static MonoDebuggerSymbolFile *
99 allocate_symbol_file_entry (MonoDebuggerSymbolTable *table)
100 {
101         MonoDebuggerSymbolFile *symfile;
102
103         if (!table->symbol_files)
104                 table->symbol_files = g_new0 (MonoDebuggerSymbolFile *, SYMFILE_TABLE_CHUNK_SIZE);
105         else if (!((table->num_symbol_files + 1) % SYMFILE_TABLE_CHUNK_SIZE)) {
106                 guint32 chunks = (table->num_symbol_files + 1) / SYMFILE_TABLE_CHUNK_SIZE;
107                 guint32 size = sizeof (MonoDebuggerSymbolFile *) * SYMFILE_TABLE_CHUNK_SIZE * (chunks + 1);
108
109                 table->symbol_files = g_realloc (table->symbol_files, size);
110         }
111
112         symfile = g_new0 (MonoDebuggerSymbolFile, 1);
113         symfile->index = table->num_symbol_files;
114         symfile->range_entry_size = sizeof (MonoDebuggerRangeInfo);
115         symfile->class_entry_size = sizeof (MonoDebuggerClassInfo);
116         table->symbol_files [table->num_symbol_files++] = symfile;
117         return symfile;
118 }
119
120 void
121 mono_debugger_initialize (MonoDomain *domain)
122 {
123         MonoDebuggerSymbolTable *symbol_table;
124
125         g_assert (!mono_debugger_initialized);
126
127         InitializeCriticalSection (&debugger_lock_mutex);
128         mono_debugger_initialized = TRUE;
129
130         mono_debugger_lock ();
131
132         symbol_table = g_new0 (MonoDebuggerSymbolTable, 1);
133         symbol_table->magic = MONO_DEBUGGER_MAGIC;
134         symbol_table->version = MONO_DEBUGGER_VERSION;
135         symbol_table->total_size = sizeof (MonoDebuggerSymbolTable);
136
137         symbol_table->domain = domain;
138
139         images = g_hash_table_new (g_direct_hash, g_direct_equal);
140         type_table = g_hash_table_new (g_direct_hash, g_direct_equal);
141         class_table = g_hash_table_new (g_direct_hash, g_direct_equal);
142         class_info_table = g_hash_table_new (g_direct_hash, g_direct_equal);
143
144         mono_debugger_symbol_table = symbol_table;
145
146         mono_debugger_unlock ();
147 }
148
149 MonoDebuggerSymbolFile *
150 mono_debugger_add_symbol_file (MonoDebugHandle *handle)
151 {
152         MonoDebuggerSymbolFile *info;
153
154         g_assert (mono_debugger_initialized);
155         mono_debugger_lock ();
156
157         info = g_hash_table_lookup (images, handle->image);
158         if (info) {
159                 mono_debugger_unlock ();
160                 return info;
161         }
162
163         info = allocate_symbol_file_entry (mono_debugger_symbol_table);
164         info->symfile = handle->symfile;
165         info->image = handle->image;
166         info->image_file = handle->image_file;
167
168         g_hash_table_insert (images, handle->image, info);
169         mono_debugger_unlock ();
170
171         return info;
172 }
173
174 static void
175 write_builtin_type (MonoDebuggerSymbolTable *table, MonoClass *klass, MonoDebuggerBuiltinTypeInfo *info)
176 {
177         guint8 buffer [BUFSIZ], *ptr = buffer;
178         guint32 size;
179
180         g_assert (!klass->init_pending);
181         mono_class_init (klass);
182
183         switch (klass->byval_arg.type) {
184         case MONO_TYPE_VOID:
185                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_UNKNOWN;
186                 WRITE_UINT32 (ptr, 0);
187                 ptr += 4;
188                 break;
189
190         case MONO_TYPE_BOOLEAN:
191         case MONO_TYPE_I1:
192         case MONO_TYPE_U1:
193         case MONO_TYPE_CHAR:
194         case MONO_TYPE_I2:
195         case MONO_TYPE_U2:
196         case MONO_TYPE_I4:
197         case MONO_TYPE_U4:
198         case MONO_TYPE_R4:
199         case MONO_TYPE_I8:
200         case MONO_TYPE_U8:
201         case MONO_TYPE_R8:
202                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_FUNDAMENTAL;
203                 WRITE_UINT32 (ptr, klass->instance_size - sizeof (MonoObject));
204                 ptr += 4;
205                 break;
206
207         case MONO_TYPE_STRING: {
208                 MonoString string;
209
210                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_STRING;
211                 WRITE_UINT32 (ptr, klass->instance_size);
212                 ptr += 4;
213                 *ptr++ = (guint8*)&string.length - (guint8*)&string;
214                 *ptr++ = sizeof (string.length);
215                 *ptr++ = (guint8*)&string.chars - (guint8*)&string;
216
217                 break;
218         }
219
220         case MONO_TYPE_I:
221         case MONO_TYPE_U:
222                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_FUNDAMENTAL;
223                 WRITE_UINT32 (ptr, sizeof (void *));
224                 ptr += 4;
225                 break;
226
227         case MONO_TYPE_VALUETYPE:
228                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_STRUCT;
229                 WRITE_UINT32 (ptr, klass->instance_size);
230                 ptr += 4;
231                 break;
232
233         case MONO_TYPE_CLASS:
234                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_CLASS;
235                 WRITE_UINT32 (ptr, klass->instance_size);
236                 ptr += 4;
237                 break;
238
239         case MONO_TYPE_OBJECT:
240                 g_assert (klass == mono_defaults.object_class);
241                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_OBJECT;
242                 WRITE_UINT32 (ptr, klass->instance_size);
243                 ptr += 4;
244                 break;
245
246         default:
247                 g_error (G_STRLOC ": Unknown builtin type %s.%s - %d", klass->name_space, klass->name, klass->byval_arg.type);
248         }
249
250         size = ptr - buffer;
251         info->cinfo->type_info = info->type_info = allocate_type_entry (table, size, &info->type_data);
252         memcpy (info->type_data, buffer, size);
253 }
254
255 static MonoDebuggerBuiltinTypeInfo *
256 add_builtin_type (MonoDebuggerSymbolFile *symfile, MonoClass *klass)
257 {
258         MonoDebuggerClassInfo *cinfo;
259         MonoDebuggerBuiltinTypeInfo *info;
260
261         cinfo = g_new0 (MonoDebuggerClassInfo, 1);
262         cinfo->klass = klass;
263         if (klass->rank) {
264                 cinfo->token = klass->element_class->type_token;
265                 cinfo->rank = klass->rank;
266         } else
267                 cinfo->token = klass->type_token;
268
269         g_hash_table_insert (class_info_table, klass, cinfo);
270
271         info = g_new0 (MonoDebuggerBuiltinTypeInfo, 1);
272         info->klass = klass;
273         info->cinfo = cinfo;
274
275         write_builtin_type (mono_debugger_symbol_table, klass, info);
276         return info;
277 }
278
279 static void
280 add_builtin_type_2 (MonoDebuggerBuiltinTypeInfo *info)
281 {
282         info->class_info = write_class (mono_debugger_symbol_table, info->klass);
283         * (guint32 *) (info->type_data + 5) = info->class_info;
284 }
285
286 static void
287 add_exception_class (MonoDebuggerSymbolFile *symfile, MonoException *exc)
288 {
289         mono_debugger_add_type (symfile, ((MonoObject *) exc)->vtable->klass);
290 }
291
292 MonoDebuggerBuiltinTypes *
293 mono_debugger_add_builtin_types (MonoDebuggerSymbolFile *symfile)
294 {
295         MonoDebuggerBuiltinTypes *types = g_new0 (MonoDebuggerBuiltinTypes, 1);
296         MonoException *exc;
297
298         mono_debugger_symbol_table->corlib = symfile;
299         mono_debugger_symbol_table->builtin_types = types;
300
301         types->total_size = sizeof (MonoDebuggerBuiltinTypes);
302         types->type_info_size = sizeof (MonoDebuggerBuiltinTypeInfo);
303
304         types->object_type = add_builtin_type (symfile, mono_defaults.object_class);
305         types->byte_type = add_builtin_type (symfile, mono_defaults.byte_class);
306         types->void_type = add_builtin_type (symfile, mono_defaults.void_class);
307         types->boolean_type = add_builtin_type (symfile, mono_defaults.boolean_class);
308         types->sbyte_type = add_builtin_type (symfile, mono_defaults.sbyte_class);
309         types->int16_type = add_builtin_type (symfile, mono_defaults.int16_class);
310         types->uint16_type = add_builtin_type (symfile, mono_defaults.uint16_class);
311         types->int32_type = add_builtin_type (symfile, mono_defaults.int32_class);
312         types->uint32_type = add_builtin_type (symfile, mono_defaults.uint32_class);
313         types->int_type = add_builtin_type (symfile, mono_defaults.int_class);
314         types->uint_type = add_builtin_type (symfile, mono_defaults.uint_class);
315         types->int64_type = add_builtin_type (symfile, mono_defaults.int64_class);
316         types->uint64_type = add_builtin_type (symfile, mono_defaults.uint64_class);
317         types->single_type = add_builtin_type (symfile, mono_defaults.single_class);
318         types->double_type = add_builtin_type (symfile, mono_defaults.double_class);
319         types->char_type = add_builtin_type (symfile, mono_defaults.char_class);
320         types->string_type = add_builtin_type (symfile, mono_defaults.string_class);
321
322         types->enum_type = add_builtin_type (symfile, mono_defaults.enum_class);
323         types->array_type = add_builtin_type (symfile, mono_defaults.array_class);
324         types->exception_type = add_builtin_type (symfile, mono_defaults.exception_class);
325
326         add_builtin_type_2 (types->object_type);
327         add_builtin_type_2 (types->byte_type);
328         add_builtin_type_2 (types->void_type);
329         add_builtin_type_2 (types->boolean_type);
330         add_builtin_type_2 (types->sbyte_type);
331         add_builtin_type_2 (types->int16_type);
332         add_builtin_type_2 (types->uint16_type);
333         add_builtin_type_2 (types->int32_type);
334         add_builtin_type_2 (types->uint32_type);
335         add_builtin_type_2 (types->int_type);
336         add_builtin_type_2 (types->uint_type);
337         add_builtin_type_2 (types->int64_type);
338         add_builtin_type_2 (types->uint64_type);
339         add_builtin_type_2 (types->single_type);
340         add_builtin_type_2 (types->double_type);
341         add_builtin_type_2 (types->char_type);
342         add_builtin_type_2 (types->string_type);
343         add_builtin_type_2 (types->enum_type);
344         add_builtin_type_2 (types->array_type);
345         add_builtin_type_2 (types->exception_type);
346
347         add_exception_class (symfile, mono_get_exception_divide_by_zero ());
348         add_exception_class (symfile, mono_get_exception_security ());
349         add_exception_class (symfile, mono_get_exception_arithmetic ());
350         add_exception_class (symfile, mono_get_exception_overflow ());
351         add_exception_class (symfile, mono_get_exception_null_reference ());
352         add_exception_class (symfile, mono_get_exception_thread_abort ());
353         add_exception_class (symfile, mono_get_exception_invalid_cast ());
354         add_exception_class (symfile, mono_get_exception_index_out_of_range ());
355         add_exception_class (symfile, mono_get_exception_thread_abort ());
356         add_exception_class (symfile, mono_get_exception_index_out_of_range ());
357         add_exception_class (symfile, mono_get_exception_array_type_mismatch ());
358         add_exception_class (symfile, mono_get_exception_missing_method ());
359         add_exception_class (symfile, mono_get_exception_appdomain_unloaded ());
360         add_exception_class (symfile, mono_get_exception_stack_overflow ());
361
362         return types;
363 }
364
365 void
366 mono_debugger_add_type (MonoDebuggerSymbolFile *symfile, MonoClass *klass)
367 {
368         MonoDebuggerClassInfo *cinfo;
369
370         mono_debugger_lock ();
371
372         cinfo = g_hash_table_lookup (class_info_table, klass);
373         if (cinfo) {
374                 mono_debugger_unlock ();
375                 return;
376         }
377
378         symfile->generation++;
379
380         cinfo = allocate_class_entry (symfile);
381         cinfo->klass = klass;
382         if (klass->rank) {
383                 cinfo->token = klass->element_class->type_token;
384                 cinfo->rank = klass->rank;
385         } else
386                 cinfo->token = klass->type_token;
387         g_hash_table_insert (class_info_table, klass, cinfo);
388
389         cinfo->type_info = write_class (mono_debugger_symbol_table, klass);
390
391         must_reload_symtabs = TRUE;
392         mono_debugger_unlock ();
393 }
394
395 void
396 mono_debugger_add_method (MonoDebuggerSymbolFile *symfile, MonoDebugMethodInfo *minfo,
397                           MonoDebugMethodJitInfo *jit)
398 {
399         MonoSymbolFileMethodAddress *address;
400         MonoSymbolFileLexicalBlockEntry *block;
401         MonoDebugVarInfo *var_table;
402         MonoDebuggerRangeInfo *range;
403         MonoMethodHeader *header;
404         guint32 size, num_variables, variable_size, variable_offset;
405         guint32 type_size, type_offset, *type_index_table, has_this;
406         guint32 line_size, line_offset, block_offset, block_size;
407         MonoDebugLexicalBlockEntry *block_table;
408         MonoDebugLineNumberEntry *line_table;
409         guint32 *type_table;
410         guint8 *ptr;
411         int i;
412
413         if (!symfile->symfile->method_hash)
414                 return;
415
416         header = ((MonoMethodNormal *) minfo->method)->header;
417
418         symfile->generation++;
419
420         size = sizeof (MonoSymbolFileMethodAddress);
421
422         num_variables = read32(&(minfo->entry->_num_parameters)) + read32(&(minfo->entry->_num_locals));
423         has_this = jit->this_var != NULL;
424
425         variable_size = (num_variables + has_this) * sizeof (MonoDebugVarInfo);
426         variable_offset = size;
427         size += variable_size;
428
429         type_size = (num_variables + 1) * sizeof (gpointer);
430         type_offset = size;
431         size += type_size;
432
433         if (jit->line_numbers) {
434                 line_offset = size;
435                 line_size = jit->line_numbers->len * sizeof (MonoDebugLineNumberEntry);
436                 size += line_size;
437         }
438
439         block_size = read32(&(minfo->entry->_num_lexical_blocks)) * sizeof (MonoSymbolFileLexicalBlockEntry);
440         block_offset = size;
441         size += block_size;
442
443         address = g_malloc0 (size);
444         ptr = (guint8 *) address;
445
446         block = (MonoSymbolFileLexicalBlockEntry *)
447                 (symfile->symfile->raw_contents + read32(&(minfo->entry->_lexical_block_table_offset)));
448         block_table = (MonoDebugLexicalBlockEntry *) (ptr + block_offset);
449
450         for (i = 0; i < read32(&(minfo->entry->_num_lexical_blocks)); i++, block++) {
451                 block_table [i].start_address = _mono_debug_address_from_il_offset (jit, read32(&(block->_start_offset)));
452                 block_table [i].end_address = _mono_debug_address_from_il_offset (jit, read32(&(block->_end_offset)));
453         }
454
455         address->size = size;
456         address->has_this = has_this;
457         address->start_address = jit->code_start;
458         address->end_address = jit->code_start + jit->code_size;
459         address->method_start_address = address->start_address + jit->prologue_end;
460         address->method_end_address = address->start_address + jit->epilogue_begin;
461         address->wrapper_address = jit->wrapper_addr;
462         address->variable_table_offset = variable_offset;
463         address->type_table_offset = type_offset;
464         address->lexical_block_table_offset = block_offset;
465
466         if (jit->line_numbers) {
467                 address->num_line_numbers = jit->line_numbers->len;
468                 address->line_number_offset = line_offset;
469
470                 line_table = (MonoDebugLineNumberEntry *) (ptr + line_offset);
471                 memcpy (line_table, jit->line_numbers->data, line_size);
472         }
473
474         range = allocate_range_entry (symfile);
475         range->index = minfo->index;
476         range->start_address = address->start_address;
477         range->end_address = address->end_address;
478         range->dynamic_data = address;
479         range->dynamic_size = size;
480
481         if ((minfo->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
482             (minfo->method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
483             (minfo->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
484                 return;
485
486         var_table = (MonoDebugVarInfo *) (ptr + variable_offset);
487         type_table = (guint32 *) (ptr + type_offset);
488
489         type_index_table = (guint32 *)
490                 (symfile->symfile->raw_contents + read32(&(minfo->entry->_type_index_table_offset)));
491
492         if (jit->this_var)
493                 *var_table++ = *jit->this_var;
494         *type_table++ = write_type (mono_debugger_symbol_table, &minfo->method->klass->this_arg);
495
496         if (jit->num_params != read32(&(minfo->entry->_num_parameters))) {
497                 g_warning (G_STRLOC ": Method %s.%s has %d parameters, but symbol file claims it has %d.",
498                            minfo->method->klass->name, minfo->method->name, jit->num_params,
499                            read32(&(minfo->entry->_num_parameters)));
500                 var_table += read32(&(minfo->entry->_num_parameters));
501         } else {
502                 for (i = 0; i < jit->num_params; i++) {
503                         *var_table++ = jit->params [i];
504                         *type_table++ = write_type (mono_debugger_symbol_table, minfo->method->signature->params [i]);
505                 }
506         }
507
508         if (jit->num_locals < read32(&(minfo->entry->_num_locals))) {
509                 g_warning (G_STRLOC ": Method %s.%s has %d locals, but symbol file claims it has %d.",
510                            minfo->method->klass->name, minfo->method->name, jit->num_locals,
511                            read32(&(minfo->entry->_num_locals)));
512                 var_table += read32(&(minfo->entry->_num_locals));
513         } else {
514                 g_assert ((header != NULL) || (minfo->entry->_num_locals == 0));
515                 for (i = 0; i < read32(&(minfo->entry->_num_locals)); i++) {
516                         *var_table++ = jit->locals [i];
517                         *type_table++ = write_type (mono_debugger_symbol_table, header->locals [i]);
518                 }
519         }
520
521         must_reload_symtabs = TRUE;
522 }
523
524 static MonoDebuggerRangeInfo *
525 allocate_range_entry (MonoDebuggerSymbolFile *symfile)
526 {
527         MonoDebuggerRangeInfo *retval;
528         guint32 size, chunks;
529
530         if (!symfile->range_table) {
531                 size = sizeof (MonoDebuggerRangeInfo) * RANGE_TABLE_CHUNK_SIZE;
532                 symfile->range_table = g_malloc0 (size);
533                 symfile->num_range_entries = 1;
534                 return symfile->range_table;
535         }
536
537         if (!((symfile->num_range_entries + 1) % RANGE_TABLE_CHUNK_SIZE)) {
538                 chunks = (symfile->num_range_entries + 1) / RANGE_TABLE_CHUNK_SIZE;
539                 size = sizeof (MonoDebuggerRangeInfo) * RANGE_TABLE_CHUNK_SIZE * (chunks + 1);
540
541                 symfile->range_table = g_realloc (symfile->range_table, size);
542         }
543
544         retval = symfile->range_table + symfile->num_range_entries;
545         symfile->num_range_entries++;
546         return retval;
547 }
548
549 static MonoDebuggerClassInfo *
550 allocate_class_entry (MonoDebuggerSymbolFile *symfile)
551 {
552         MonoDebuggerClassInfo *retval;
553         guint32 size, chunks;
554
555         if (!symfile->class_table) {
556                 size = sizeof (MonoDebuggerClassInfo) * CLASS_TABLE_CHUNK_SIZE;
557                 symfile->class_table = g_malloc0 (size);
558                 symfile->num_class_entries = 1;
559                 return symfile->class_table;
560         }
561
562         if (!((symfile->num_class_entries + 1) % CLASS_TABLE_CHUNK_SIZE)) {
563                 chunks = (symfile->num_class_entries + 1) / CLASS_TABLE_CHUNK_SIZE;
564                 size = sizeof (MonoDebuggerClassInfo) * CLASS_TABLE_CHUNK_SIZE * (chunks + 1);
565
566                 symfile->class_table = g_realloc (symfile->class_table, size);
567         }
568
569         retval = symfile->class_table + symfile->num_class_entries;
570         symfile->num_class_entries++;
571         return retval;
572 }
573
574 /*
575  * Allocate a new entry of size `size' in the type table.
576  * Returns the global offset which is to be used to reference this type and
577  * a pointer (in the `ptr' argument) which is to be used to write the type.
578  */
579 static guint32
580 allocate_type_entry (MonoDebuggerSymbolTable *table, guint32 size, guint8 **ptr)
581 {
582         guint32 retval;
583         guint8 *data;
584
585         g_assert (size + 4 < TYPE_TABLE_CHUNK_SIZE);
586         g_assert (ptr != NULL);
587
588         /* Initialize things if necessary. */
589         if (!table->current_type_table) {
590                 table->current_type_table = g_malloc0 (TYPE_TABLE_CHUNK_SIZE);
591                 table->type_table_size = TYPE_TABLE_CHUNK_SIZE;
592                 table->type_table_chunk_size = TYPE_TABLE_CHUNK_SIZE;
593                 table->type_table_offset = 1;
594         }
595
596  again:
597         /* First let's check whether there's still enough room in the current_type_table. */
598         if (table->type_table_offset + size + 4 < table->type_table_size) {
599                 retval = table->type_table_offset;
600                 table->type_table_offset += size + 4;
601                 data = ((guint8 *) table->current_type_table) + retval - table->type_table_start;
602                 *(gint32 *) data = size;
603                 data += sizeof(gint32);
604                 *ptr = data;
605                 return retval;
606         }
607
608         /* Add the current_type_table to the type_tables vector and ... */
609         if (!table->type_tables) {
610                 guint32 tsize = sizeof (gpointer) * TYPE_TABLE_PTR_CHUNK_SIZE;
611                 table->type_tables = g_malloc0 (tsize);
612         }
613
614         if (!((table->num_type_tables + 1) % TYPE_TABLE_PTR_CHUNK_SIZE)) {
615                 guint32 chunks = (table->num_type_tables + 1) / TYPE_TABLE_PTR_CHUNK_SIZE;
616                 guint32 tsize = sizeof (gpointer) * TYPE_TABLE_PTR_CHUNK_SIZE * (chunks + 1);
617
618                 table->type_tables = g_realloc (table->type_tables, tsize);
619         }
620
621         table->type_tables [table->num_type_tables++] = table->current_type_table;
622
623         /* .... allocate a new current_type_table. */
624         table->current_type_table = g_malloc0 (TYPE_TABLE_CHUNK_SIZE);
625         table->type_table_start = table->type_table_offset = table->type_table_size;
626         table->type_table_size += TYPE_TABLE_CHUNK_SIZE;
627
628         goto again;
629 }
630
631 static gboolean
632 property_is_static (MonoProperty *prop)
633 {
634         MonoMethod *method;
635
636         method = prop->get;
637         if (!method)
638                 method = prop->set;
639
640         return method->flags & METHOD_ATTRIBUTE_STATIC;
641 }
642
643 static guint32
644 write_class (MonoDebuggerSymbolTable *table, MonoClass *klass)
645 {
646         guint8 buffer [BUFSIZ], *ptr = buffer, *old_ptr;
647         GPtrArray *methods = NULL, *static_methods = NULL, *ctors = NULL;
648         int num_fields = 0, num_static_fields = 0, num_properties = 0, num_static_properties = 0;
649         int num_methods = 0, num_static_methods = 0, num_params = 0, num_static_params = 0, base_offset = 0;
650         int num_ctors = 0, num_ctor_params = 0;
651         int field_info_size = 0, static_field_info_size = 0, property_info_size = 0;
652         int static_property_info_size = 0, method_info_size = 0, static_method_info_size = 0;
653         int ctor_info_size = 0, iface_info_size = 0;
654         guint32 size, data_size, offset, data_offset;
655         GHashTable *method_slots = NULL;
656         int i;
657
658         g_assert (!klass->init_pending);
659         mono_class_init (klass);
660
661         offset = GPOINTER_TO_UINT (g_hash_table_lookup (class_table, klass));
662         if (offset)
663                 return offset;
664
665         if (klass->enumtype) {
666                 offset = allocate_type_entry (table, 13, &ptr);
667                 g_hash_table_insert (class_table, klass, GUINT_TO_POINTER (offset));
668
669                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_ENUM;
670                 WRITE_UINT32 (ptr, klass->instance_size);
671                 WRITE_UINT32 (ptr, table->builtin_types->enum_type->type_info);
672                 WRITE_UINT32 (ptr, write_type (table, klass->enum_basetype));
673                 return offset;
674         }
675
676         for (i = 0; i < klass->field.count; i++)
677                 if (!(klass->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC))
678                         ++num_fields;
679                 else
680                         ++num_static_fields;
681
682         for (i = 0; i < klass->property.count; i++)
683                 if (!property_is_static (&klass->properties [i]))
684                         ++num_properties;
685                 else
686                         ++num_static_properties;
687
688         method_slots = g_hash_table_new (NULL, NULL);
689         methods = g_ptr_array_new ();
690         static_methods = g_ptr_array_new ();
691         ctors = g_ptr_array_new ();
692
693         for (i = 0; i < klass->method.count; i++) {
694                 MonoMethod *method = klass->methods [i];
695
696                 if (!strcmp (method->name, ".cctor"))
697                         continue;
698                 if (!((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))
699                         continue;
700
701                 if (!strcmp (method->name, ".ctor")) {
702                         ++num_ctors;
703                         num_ctor_params += method->signature->param_count;
704                         g_ptr_array_add (ctors, method);
705                         continue;
706                 }
707
708                 if (method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME)
709                         continue;
710                 
711                 if (method->slot != -1) {
712                         if (g_hash_table_lookup (method_slots, GUINT_TO_POINTER (method->slot)))
713                                 continue;
714                         g_hash_table_insert (method_slots, GUINT_TO_POINTER (method->slot), method);
715                 }
716
717                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
718                         ++num_static_methods;
719                         num_static_params += method->signature->param_count;
720                         g_ptr_array_add (static_methods, method);
721                 } else {
722                         ++num_methods;
723                         num_params += method->signature->param_count;
724                         g_ptr_array_add (methods, method);
725                 }
726         }
727
728         g_hash_table_destroy (method_slots);
729
730         field_info_size = num_fields * 8;
731         static_field_info_size = num_static_fields * 8;
732         property_info_size = num_properties * (4 + 2 * sizeof (gpointer));
733         static_property_info_size = num_static_properties * (4 + 2 * sizeof (gpointer));
734         method_info_size = num_methods * (4 + 2 * sizeof (gpointer)) + num_params * 4;
735         static_method_info_size = num_static_methods * (4 + 2 * sizeof (gpointer)) +
736                 num_static_params * 4;
737         ctor_info_size = num_ctors * (4 + 2 * sizeof (gpointer)) + num_ctor_params * 4;
738         iface_info_size = klass->interface_count * 4;
739
740         size = 74 + sizeof (gpointer) + field_info_size + static_field_info_size +
741                 property_info_size + static_property_info_size + method_info_size +
742                 static_method_info_size + ctor_info_size + iface_info_size;
743
744         data_size = size;
745
746         offset = allocate_type_entry (table, data_size, &ptr);
747         old_ptr = ptr;
748
749         g_hash_table_insert (class_table, klass, GUINT_TO_POINTER (offset));
750
751         *ptr++ = MONO_DEBUGGER_TYPE_KIND_CLASS_INFO;
752
753         if (klass->valuetype)
754                 base_offset = - sizeof (MonoObject);
755
756         WRITE_UINT32 (ptr, klass->instance_size + base_offset);
757         *ptr++ = klass->valuetype;
758         WRITE_POINTER (ptr, klass);
759         data_offset = 0;
760         WRITE_UINT32 (ptr, num_fields);
761         WRITE_UINT32 (ptr, data_offset);
762         data_offset += field_info_size;
763         WRITE_UINT32 (ptr, num_properties);
764         WRITE_UINT32 (ptr, data_offset);
765         data_offset += property_info_size;
766         WRITE_UINT32 (ptr, num_methods);
767         WRITE_UINT32 (ptr, data_offset);
768         data_offset += method_info_size;
769         WRITE_UINT32 (ptr, num_static_fields);
770         WRITE_UINT32 (ptr, data_offset);
771         data_offset += static_field_info_size;
772         WRITE_UINT32 (ptr, num_static_properties);
773         WRITE_UINT32 (ptr, data_offset);
774         data_offset += static_property_info_size;
775         WRITE_UINT32 (ptr, num_static_methods);
776         WRITE_UINT32 (ptr, data_offset);
777         data_offset += static_method_info_size;
778         WRITE_UINT32 (ptr, num_ctors);
779         WRITE_UINT32 (ptr, data_offset);
780         data_offset += ctor_info_size;
781         WRITE_UINT32 (ptr, klass->interface_count);
782         WRITE_UINT32 (ptr, data_offset);
783         data_offset += iface_info_size;
784
785         if (klass->parent && (klass->parent != mono_defaults.object_class))
786                 WRITE_UINT32 (ptr, write_class (table, klass->parent));
787         else
788                 WRITE_UINT32 (ptr, 0);
789
790         for (i = 0; i < klass->field.count; i++) {
791                 if (klass->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC)
792                         continue;
793
794                 WRITE_UINT32 (ptr, klass->fields [i].offset + base_offset);
795                 WRITE_UINT32 (ptr, write_type (table, klass->fields [i].type));
796         }
797
798         for (i = 0; i < klass->property.count; i++) {
799                 if (property_is_static (&klass->properties [i]))
800                         continue;
801
802                 if (klass->properties [i].get)
803                         WRITE_UINT32 (ptr, write_type (table, klass->properties [i].get->signature->ret));
804                 else
805                         WRITE_UINT32 (ptr, 0);
806                 WRITE_POINTER (ptr, klass->properties [i].get);
807                 WRITE_POINTER (ptr, klass->properties [i].set);
808         }
809
810         for (i = 0; i < methods->len; i++) {
811                 MonoMethod *method = g_ptr_array_index (methods, i);
812                 int j;
813
814                 WRITE_POINTER (ptr, method);
815                 if ((method->signature->ret) && (method->signature->ret->type != MONO_TYPE_VOID))
816                         WRITE_UINT32 (ptr, write_type (table, method->signature->ret));
817                 else
818                         WRITE_UINT32 (ptr, 0);
819                 WRITE_UINT32 (ptr, method->signature->param_count);
820                 for (j = 0; j < method->signature->param_count; j++)
821                         WRITE_UINT32 (ptr, write_type (table, method->signature->params [j]));
822         }
823
824         g_ptr_array_free (methods, FALSE);
825
826         for (i = 0; i < klass->field.count; i++) {
827                 if (!(klass->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC))
828                         continue;
829
830                 WRITE_UINT32 (ptr, klass->fields [i].offset);
831                 WRITE_UINT32 (ptr, write_type (table, klass->fields [i].type));
832         }
833
834         for (i = 0; i < klass->property.count; i++) {
835                 if (!property_is_static (&klass->properties [i]))
836                         continue;
837
838                 if (klass->properties [i].get)
839                         WRITE_UINT32 (ptr, write_type (table, klass->properties [i].get->signature->ret));
840                 else
841                         WRITE_UINT32 (ptr, 0);
842                 WRITE_POINTER (ptr, klass->properties [i].get);
843                 WRITE_POINTER (ptr, klass->properties [i].set);
844         }
845
846         for (i = 0; i < static_methods->len; i++) {
847                 MonoMethod *method = g_ptr_array_index (static_methods, i);
848                 int j;
849
850                 WRITE_POINTER (ptr, method);
851                 if ((method->signature->ret) && (method->signature->ret->type != MONO_TYPE_VOID))
852                         WRITE_UINT32 (ptr, write_type (table, method->signature->ret));
853                 else
854                         WRITE_UINT32 (ptr, 0);
855                 WRITE_UINT32 (ptr, method->signature->param_count);
856                 for (j = 0; j < method->signature->param_count; j++)
857                         WRITE_UINT32 (ptr, write_type (table, method->signature->params [j]));
858         }
859
860         g_ptr_array_free (static_methods, FALSE);
861
862         for (i = 0; i < ctors->len; i++) {
863                 MonoMethod *ctor = g_ptr_array_index (ctors, i);
864                 int j;
865
866                 WRITE_POINTER (ptr, ctor);
867                 WRITE_UINT32 (ptr, 0);
868                 WRITE_UINT32 (ptr, ctor->signature->param_count);
869                 for (j = 0; j < ctor->signature->param_count; j++)
870                         WRITE_UINT32 (ptr, write_type (table, ctor->signature->params [j]));
871         }
872
873         g_ptr_array_free (ctors, FALSE);
874
875         for (i = 0; i < klass->interface_count; i++)
876                 WRITE_UINT32 (ptr, write_class (table, klass->interfaces [i]));
877
878         if (ptr - old_ptr != data_size) {
879                 g_warning (G_STRLOC ": %d,%d,%d", ptr - old_ptr, data_size, sizeof (gpointer));
880                 if (klass)
881                         g_warning (G_STRLOC ": %s.%s", klass->name_space, klass->name);
882                 g_assert_not_reached ();
883         }
884
885         return offset;
886 }
887
888 /*
889  * Adds type `type' to the type table and returns its offset.
890  */
891 static guint32
892 write_type (MonoDebuggerSymbolTable *table, MonoType *type)
893 {
894         guint8 buffer [BUFSIZ], *ptr = buffer;
895         guint32 size, offset;
896         MonoClass *klass;
897
898         offset = GPOINTER_TO_UINT (g_hash_table_lookup (type_table, type));
899         if (offset)
900                 return offset;
901
902         klass = mono_class_from_mono_type (type);
903         if (klass->init_pending)
904                 return 0;
905         mono_class_init (klass);
906
907         switch (type->type) {
908         case MONO_TYPE_VOID:
909                 return table->builtin_types->void_type->type_info;
910
911         case MONO_TYPE_BOOLEAN:
912                 return table->builtin_types->boolean_type->type_info;
913
914         case MONO_TYPE_I1:
915                 return table->builtin_types->sbyte_type->type_info;
916
917         case MONO_TYPE_U1:
918                 return table->builtin_types->byte_type->type_info;
919
920         case MONO_TYPE_CHAR:
921                 return table->builtin_types->char_type->type_info;
922
923         case MONO_TYPE_I2:
924                 return table->builtin_types->int16_type->type_info;
925
926         case MONO_TYPE_U2:
927                 return table->builtin_types->uint16_type->type_info;
928
929         case MONO_TYPE_I4:
930                 return table->builtin_types->int32_type->type_info;
931
932         case MONO_TYPE_U4:
933                 return table->builtin_types->uint32_type->type_info;
934
935         case MONO_TYPE_I8:
936                 return table->builtin_types->int64_type->type_info;
937
938         case MONO_TYPE_U8:
939                 return table->builtin_types->uint64_type->type_info;
940
941         case MONO_TYPE_R4:
942                 return table->builtin_types->single_type->type_info;
943
944         case MONO_TYPE_R8:
945                 return table->builtin_types->double_type->type_info;
946
947         case MONO_TYPE_STRING:
948                 return table->builtin_types->string_type->type_info;
949
950         case MONO_TYPE_I:
951                 return table->builtin_types->int_type->type_info;
952
953         case MONO_TYPE_U:
954                 return table->builtin_types->uint_type->type_info;
955
956         case MONO_TYPE_SZARRAY: {
957                 MonoArray array;
958
959                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_SZARRAY;
960                 WRITE_UINT32 (ptr, sizeof (MonoArray));
961                 g_assert (table->builtin_types->array_type->type_info != 0);
962                 WRITE_UINT32 (ptr, table->builtin_types->array_type->type_info);
963                 *ptr++ = (guint8*)&array.max_length - (guint8*)&array;
964                 *ptr++ = sizeof (array.max_length);
965                 *ptr++ = (guint8*)&array.vector - (guint8*)&array;
966                 WRITE_UINT32 (ptr, write_type (table, &type->data.klass->byval_arg));
967                 break;
968         }
969
970         case MONO_TYPE_ARRAY: {
971                 MonoArray array;
972                 MonoArrayBounds bounds;
973
974                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_ARRAY;
975                 WRITE_UINT32 (ptr, sizeof (MonoArray));
976                 g_assert (table->builtin_types->array_type->type_info != 0);
977                 WRITE_UINT32 (ptr, table->builtin_types->array_type->type_info);
978                 *ptr++ = (guint8*)&array.max_length - (guint8*)&array;
979                 *ptr++ = sizeof (array.max_length);
980                 *ptr++ = (guint8*)&array.vector - (guint8*)&array;
981                 *ptr++ = klass->rank;
982                 *ptr++ = (guint8*)&array.bounds - (guint8*)&array;
983                 *ptr++ = sizeof (MonoArrayBounds);
984                 *ptr++ = (guint8*)&bounds.lower_bound - (guint8*)&bounds;
985                 *ptr++ = sizeof (bounds.lower_bound);
986                 *ptr++ = (guint8*)&bounds.length - (guint8*)&bounds;
987                 *ptr++ = sizeof (bounds.length);
988                 WRITE_UINT32 (ptr, write_type (table, &type->data.array->eklass->byval_arg));
989                 break;
990         }
991
992         case MONO_TYPE_VALUETYPE:
993         case MONO_TYPE_CLASS:
994         case MONO_TYPE_OBJECT:
995                 return write_class (table, klass);
996
997         case MONO_TYPE_PTR:
998                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_POINTER;
999                 WRITE_UINT32 (ptr, sizeof (gpointer));
1000                 WRITE_UINT32 (ptr, write_type (table, type->data.type));
1001                 break;
1002
1003         default:
1004                 /* g_message (G_STRLOC ": %s.%s - %p - %d", klass->name_space, klass->name, klass, type->type); */
1005                 *ptr++ = MONO_DEBUGGER_TYPE_KIND_UNKNOWN;
1006                 WRITE_UINT32 (ptr, klass->instance_size);
1007                 WRITE_UINT32 (ptr, write_class (table, klass));
1008                 break;
1009         }
1010
1011         size = ptr - buffer;
1012         offset = allocate_type_entry (mono_debugger_symbol_table, size, &ptr);
1013         memcpy (ptr, buffer, size);
1014
1015         return offset;
1016 }
1017
1018 MonoReflectionMethod *
1019 ves_icall_MonoDebugger_GetMethod (MonoReflectionAssembly *assembly, guint32 token)
1020 {
1021         MonoMethod *method;
1022
1023         method = mono_get_method (mono_assembly_get_image (assembly->assembly), token, NULL);
1024
1025         return mono_method_get_object (mono_domain_get (), method, NULL);
1026 }
1027
1028 int
1029 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionAssembly *assembly, MonoReflectionMethod *method)
1030 {
1031         return method->method->token;
1032 }
1033
1034 MonoReflectionType *
1035 ves_icall_MonoDebugger_GetType (MonoReflectionAssembly *assembly, guint32 token)
1036 {
1037         MonoClass *klass;
1038
1039         klass = mono_class_get (mono_assembly_get_image (assembly->assembly), token);
1040         if (!klass) {
1041                 g_warning (G_STRLOC ": %x", token);
1042                 return NULL;
1043         }
1044
1045         return mono_type_get_object (mono_domain_get (), &klass->byval_arg);
1046 }
1047
1048 MonoReflectionType *
1049 ves_icall_MonoDebugger_GetLocalTypeFromSignature (MonoReflectionAssembly *assembly, MonoArray *signature)
1050 {
1051         MonoDomain *domain; 
1052         MonoImage *image;
1053         MonoType *type;
1054         const char *ptr;
1055         int len = 0;
1056
1057         MONO_CHECK_ARG_NULL (assembly);
1058         MONO_CHECK_ARG_NULL (signature);
1059
1060         domain = mono_domain_get();
1061         image = mono_assembly_get_image (assembly->assembly);
1062
1063         ptr = mono_array_addr (signature, char, 0);
1064         g_assert (*ptr++ == 0x07);
1065         len = mono_metadata_decode_value (ptr, &ptr);
1066         g_assert (len == 1);
1067
1068         type = mono_metadata_parse_type (image, MONO_PARSE_LOCAL, 0, ptr, &ptr);
1069
1070         return mono_type_get_object (domain, type);
1071 }
1072
1073 void
1074 mono_debugger_event (MonoDebuggerEvent event, gpointer data, guint32 arg)
1075 {
1076         if (mono_debugger_event_handler)
1077                 (* mono_debugger_event_handler) (event, data, arg);
1078 }
1079
1080 void
1081 mono_debugger_cleanup (void)
1082 {
1083         /* Do nothing yet. */
1084 }
1085
1086 /*
1087  * Debugger breakpoint interface.
1088  *
1089  * This interface is used to insert breakpoints on methods which are not yet JITed.
1090  * The debugging code keeps a list of all such breakpoints and automatically inserts the
1091  * breakpoint when the method is JITed.
1092  */
1093
1094 static GPtrArray *breakpoints = NULL;
1095
1096 int
1097 mono_debugger_insert_breakpoint_full (MonoMethodDesc *desc)
1098 {
1099         static int last_breakpoint_id = 0;
1100         MonoDebuggerBreakpointInfo *info;
1101
1102         info = g_new0 (MonoDebuggerBreakpointInfo, 1);
1103         info->desc = desc;
1104         info->index = ++last_breakpoint_id;
1105
1106         if (!breakpoints)
1107                 breakpoints = g_ptr_array_new ();
1108
1109         g_ptr_array_add (breakpoints, info);
1110
1111         return info->index;
1112 }
1113
1114 int
1115 mono_debugger_remove_breakpoint (int breakpoint_id)
1116 {
1117         int i;
1118
1119         if (!breakpoints)
1120                 return 0;
1121
1122         for (i = 0; i < breakpoints->len; i++) {
1123                 MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i);
1124
1125                 if (info->index != breakpoint_id)
1126                         continue;
1127
1128                 mono_method_desc_free (info->desc);
1129                 g_ptr_array_remove (breakpoints, info);
1130                 g_free (info);
1131                 return 1;
1132         }
1133
1134         return 0;
1135 }
1136
1137 int
1138 mono_debugger_insert_breakpoint (const gchar *method_name, gboolean include_namespace)
1139 {
1140         MonoMethodDesc *desc;
1141
1142         desc = mono_method_desc_new (method_name, include_namespace);
1143         if (!desc)
1144                 return 0;
1145
1146         return mono_debugger_insert_breakpoint_full (desc);
1147 }
1148
1149 int
1150 mono_debugger_method_has_breakpoint (MonoMethod *method)
1151 {
1152         int i;
1153
1154         if (!breakpoints || (method->wrapper_type != MONO_WRAPPER_NONE))
1155                 return 0;
1156
1157         for (i = 0; i < breakpoints->len; i++) {
1158                 MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i);
1159
1160                 if (!mono_method_desc_full_match (info->desc, method))
1161                         continue;
1162
1163                 return info->index;
1164         }
1165
1166         return 0;
1167 }
1168
1169 void
1170 mono_debugger_breakpoint_callback (MonoMethod *method, guint32 index)
1171 {
1172         mono_debugger_event (MONO_DEBUGGER_EVENT_BREAKPOINT, method, index);
1173 }
1174
1175 gboolean
1176 mono_debugger_unhandled_exception (gpointer addr, MonoObject *exc)
1177 {
1178         if (!mono_debugger_initialized)
1179                 return FALSE;
1180
1181         // Prevent the object from being finalized.
1182         last_exception = exc;
1183         mono_debugger_event (MONO_DEBUGGER_EVENT_UNHANDLED_EXCEPTION, exc, addr);
1184         return TRUE;
1185 }
1186
1187 static gchar *
1188 get_exception_message (MonoObject *exc)
1189 {
1190         char *message = NULL;
1191         MonoString *str; 
1192         MonoMethod *method;
1193         MonoClass *klass;
1194         gint i;
1195
1196         if (mono_object_isinst (exc, mono_defaults.exception_class)) {
1197                 klass = exc->vtable->klass;
1198                 method = NULL;
1199                 while (klass && method == NULL) {
1200                         for (i = 0; i < klass->method.count; ++i) {
1201                                 method = klass->methods [i];
1202                                 if (!strcmp ("ToString", method->name) &&
1203                                     method->signature->param_count == 0 &&
1204                                     method->flags & METHOD_ATTRIBUTE_VIRTUAL &&
1205                                     method->flags & METHOD_ATTRIBUTE_PUBLIC) {
1206                                         break;
1207                                 }
1208                                 method = NULL;
1209                         }
1210                         
1211                         if (method == NULL)
1212                                 klass = klass->parent;
1213                 }
1214
1215                 g_assert (method);
1216
1217                 str = (MonoString *) mono_runtime_invoke (method, exc, NULL, NULL);
1218                 if (str)
1219                         message = mono_string_to_utf8 (str);
1220         }
1221
1222         return message;
1223 }
1224
1225 MonoObject *
1226 mono_debugger_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
1227 {
1228         MonoObject *retval;
1229         gchar *message;
1230
1231         if (method->klass->valuetype && (obj != NULL))
1232                 obj = mono_value_box (mono_domain_get (), method->klass, obj);
1233
1234         if (!strcmp (method->name, ".ctor")) {
1235                 retval = obj = mono_object_new (mono_domain_get (), method->klass);
1236
1237                 mono_runtime_invoke (method, obj, params, exc);
1238         } else
1239                 retval = mono_runtime_invoke (method, obj, params, exc);
1240
1241         if (!exc || (*exc == NULL))
1242                 return retval;
1243
1244         message = get_exception_message (*exc);
1245         if (message) {
1246                 *exc = (MonoObject *) mono_string_new_wrapper (message);
1247                 g_free (message);
1248         }
1249
1250         return retval;
1251 }
1252
1253 guint32
1254 mono_debugger_lookup_type (const gchar *type_name)
1255 {
1256         int i;
1257
1258         mono_debugger_lock ();
1259
1260         for (i = 0; i < mono_debugger_symbol_table->num_symbol_files; i++) {
1261                 MonoDebuggerSymbolFile *symfile = mono_debugger_symbol_table->symbol_files [i];
1262                 MonoType *type;
1263                 guint32 offset;
1264                 gchar *name;
1265
1266                 name = g_strdup (type_name);
1267                 type = mono_reflection_type_from_name (name, symfile->image);
1268                 g_free (name);
1269                 if (!type)
1270                         continue;
1271
1272                 offset = write_type (mono_debugger_symbol_table, type);
1273
1274                 mono_debugger_unlock ();
1275                 return offset;
1276         }
1277
1278         mono_debugger_unlock ();
1279         return 0;
1280 }
1281
1282 gint32
1283 mono_debugger_lookup_assembly (const gchar *name)
1284 {
1285         MonoAssembly *assembly;
1286         MonoImageOpenStatus status;
1287         int i;
1288
1289         mono_debugger_lock ();
1290
1291  again:
1292         for (i = 0; i < mono_debugger_symbol_table->num_symbol_files; i++) {
1293                 MonoDebuggerSymbolFile *symfile = mono_debugger_symbol_table->symbol_files [i];
1294
1295                 if (!strcmp (symfile->image_file, name)) {
1296                         mono_debugger_unlock ();
1297                         return i;
1298                 }
1299         }
1300
1301         assembly = mono_assembly_open (name, &status);
1302
1303         if (status != MONO_IMAGE_OK) {
1304                 g_warning (G_STRLOC ": Cannot open image `%s'", name);
1305                 mono_debugger_unlock ();
1306                 return -1;
1307         }
1308
1309         must_reload_symtabs = TRUE;
1310         goto again;
1311 }