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/os/gc_wrapper.h>
11 #include <mono/metadata/object-internals.h>
12 #include <mono/metadata/class-internals.h>
13 #include <mono/metadata/exception.h>
14 #include <mono/metadata/mono-debug.h>
15 #include <mono/metadata/mono-debug-debugger.h>
16 #include <mono/metadata/mono-endian.h>
18 #define SYMFILE_TABLE_CHUNK_SIZE 16
19 #define RANGE_TABLE_CHUNK_SIZE 256
20 #define CLASS_TABLE_CHUNK_SIZE 256
21 #define TYPE_TABLE_PTR_CHUNK_SIZE 256
22 #define TYPE_TABLE_CHUNK_SIZE 65536
23 #define MISC_TABLE_PTR_CHUNK_SIZE 256
24 #define MISC_TABLE_CHUNK_SIZE 65536
26 static guint32 debugger_lock_level = 0;
27 static CRITICAL_SECTION debugger_lock_mutex;
28 static gboolean mono_debugger_initialized = FALSE;
29 static MonoObject *last_exception = NULL;
31 static gboolean must_reload_symtabs = FALSE;
32 static gboolean builtin_types_initialized = FALSE;
34 static GHashTable *images = NULL;
35 static GHashTable *type_table = NULL;
36 static GHashTable *misc_table = NULL;
37 static GHashTable *class_table = NULL;
38 static GHashTable *class_info_table = NULL;
40 static MonoDebuggerRangeInfo *allocate_range_entry (MonoDebuggerSymbolFile *symfile);
41 static MonoDebuggerClassInfo *allocate_class_entry (MonoDebuggerSymbolFile *symfile);
42 static guint32 allocate_type_entry (MonoDebuggerSymbolTable *table, guint32 size, guint8 **ptr);
43 static guint32 write_type (MonoDebuggerSymbolTable *table, MonoType *type);
44 static guint32 do_write_class (MonoDebuggerSymbolTable *table, MonoClass *klass,
45 MonoDebuggerClassInfo *cinfo);
46 static guint32 write_class (MonoDebuggerSymbolTable *table, MonoClass *klass);
48 MonoDebuggerSymbolTable *mono_debugger_symbol_table = NULL;
49 void (*mono_debugger_event_handler) (MonoDebuggerEvent event, gpointer data, guint32 arg) = NULL;
51 #define WRITE_UINT32(ptr,value) G_STMT_START { \
52 * ((guint32 *) ptr) = value; \
56 #define WRITE_POINTER(ptr,value) G_STMT_START { \
57 * ((gpointer *) ptr) = value; \
58 ptr += sizeof (gpointer); \
61 #define WRITE_STRING(ptr,value) G_STMT_START { \
62 memcpy (ptr, value, strlen (value)+1); \
63 ptr += strlen (value)+1; \
66 #ifndef PLATFORM_WIN32
68 MonoDebuggerIOLayer mono_debugger_io_layer = {
69 InitializeCriticalSection, DeleteCriticalSection, TryEnterCriticalSection,
70 EnterCriticalSection, LeaveCriticalSection, WaitForSingleObjectEx, SignalObjectAndWait,
71 WaitForMultipleObjectsEx, CreateSemaphore, ReleaseSemaphore, CreateThread,
78 mono_debugger_lock (void)
80 if (!mono_debugger_initialized) {
81 debugger_lock_level++;
85 EnterCriticalSection (&debugger_lock_mutex);
86 debugger_lock_level++;
90 mono_debugger_unlock (void)
92 g_assert (debugger_lock_level > 0);
94 if (!mono_debugger_initialized) {
95 debugger_lock_level--;
99 if (debugger_lock_level == 1) {
100 if (must_reload_symtabs) {
101 mono_debugger_event (MONO_DEBUGGER_EVENT_RELOAD_SYMTABS, NULL, 0);
102 must_reload_symtabs = FALSE;
106 debugger_lock_level--;
107 LeaveCriticalSection (&debugger_lock_mutex);
110 static MonoDebuggerSymbolFile *
111 allocate_symbol_file_entry (MonoDebuggerSymbolTable *table)
113 MonoDebuggerSymbolFile *symfile;
115 if (!table->symbol_files)
116 table->symbol_files = g_new0 (MonoDebuggerSymbolFile *, SYMFILE_TABLE_CHUNK_SIZE);
117 else if (!((table->num_symbol_files + 1) % SYMFILE_TABLE_CHUNK_SIZE)) {
118 guint32 chunks = (table->num_symbol_files + 1) / SYMFILE_TABLE_CHUNK_SIZE;
119 guint32 size = sizeof (MonoDebuggerSymbolFile *) * SYMFILE_TABLE_CHUNK_SIZE * (chunks + 1);
121 table->symbol_files = g_realloc (table->symbol_files, size);
124 symfile = g_new0 (MonoDebuggerSymbolFile, 1);
125 symfile->index = table->num_symbol_files;
126 symfile->range_entry_size = sizeof (MonoDebuggerRangeInfo);
127 symfile->class_entry_size = sizeof (MonoDebuggerClassInfo);
128 symfile->class_table_size = sizeof (MonoDebuggerClassTable);
129 table->symbol_files [table->num_symbol_files++] = symfile;
134 mono_debugger_initialize (void)
136 MonoDebuggerSymbolTable *symbol_table;
138 MONO_GC_REGISTER_ROOT (last_exception);
140 g_assert (!mono_debugger_initialized);
142 InitializeCriticalSection (&debugger_lock_mutex);
143 mono_debugger_initialized = TRUE;
145 mono_debugger_lock ();
147 symbol_table = g_new0 (MonoDebuggerSymbolTable, 1);
148 symbol_table->magic = MONO_DEBUGGER_MAGIC;
149 symbol_table->version = MONO_DEBUGGER_VERSION;
150 symbol_table->total_size = sizeof (MonoDebuggerSymbolTable);
152 images = g_hash_table_new (g_direct_hash, g_direct_equal);
153 type_table = g_hash_table_new (g_direct_hash, g_direct_equal);
154 misc_table = g_hash_table_new (g_direct_hash, g_direct_equal);
155 class_table = g_hash_table_new (g_direct_hash, g_direct_equal);
156 class_info_table = g_hash_table_new (g_direct_hash, g_direct_equal);
158 mono_debugger_symbol_table = symbol_table;
160 mono_debugger_unlock ();
163 MonoDebuggerSymbolFile *
164 mono_debugger_add_symbol_file (MonoDebugHandle *handle)
166 MonoDebuggerSymbolFile *info;
168 g_assert (mono_debugger_initialized);
169 mono_debugger_lock ();
171 info = g_hash_table_lookup (images, handle->image);
173 mono_debugger_unlock ();
177 info = allocate_symbol_file_entry (mono_debugger_symbol_table);
178 info->symfile = handle->symfile;
179 info->image = handle->image;
180 info->image_file = handle->image_file;
182 g_hash_table_insert (images, handle->image, info);
183 mono_debugger_unlock ();
189 write_builtin_type (MonoDebuggerSymbolTable *table, MonoDebuggerSymbolFile *symfile,
190 MonoClass *klass, MonoDebuggerBuiltinTypeInfo *info)
192 guint8 buffer [BUFSIZ], *ptr = buffer;
195 g_assert (!klass->init_pending);
196 mono_class_init (klass);
198 switch (klass->byval_arg.type) {
200 *ptr++ = MONO_DEBUGGER_TYPE_KIND_UNKNOWN;
201 WRITE_UINT32 (ptr, 0);
205 case MONO_TYPE_BOOLEAN:
217 *ptr++ = MONO_DEBUGGER_TYPE_KIND_FUNDAMENTAL;
218 WRITE_UINT32 (ptr, klass->instance_size - sizeof (MonoObject));
222 case MONO_TYPE_STRING: {
225 *ptr++ = MONO_DEBUGGER_TYPE_KIND_STRING;
226 WRITE_UINT32 (ptr, klass->instance_size);
228 *ptr++ = (guint8*)&string.length - (guint8*)&string;
229 *ptr++ = sizeof (string.length);
230 *ptr++ = (guint8*)&string.chars - (guint8*)&string;
237 *ptr++ = MONO_DEBUGGER_TYPE_KIND_FUNDAMENTAL;
238 WRITE_UINT32 (ptr, sizeof (void *));
242 case MONO_TYPE_VALUETYPE:
243 *ptr++ = MONO_DEBUGGER_TYPE_KIND_STRUCT;
244 WRITE_UINT32 (ptr, klass->instance_size);
248 case MONO_TYPE_CLASS:
249 *ptr++ = MONO_DEBUGGER_TYPE_KIND_CLASS;
250 WRITE_UINT32 (ptr, klass->instance_size);
254 case MONO_TYPE_OBJECT:
255 g_assert (klass == mono_defaults.object_class);
256 *ptr++ = MONO_DEBUGGER_TYPE_KIND_OBJECT;
257 WRITE_UINT32 (ptr, klass->instance_size);
262 g_error (G_STRLOC ": Unknown builtin type %s.%s - %d", klass->name_space, klass->name, klass->byval_arg.type);
266 info->type_info = allocate_type_entry (table, size, &info->type_data);
267 memcpy (info->type_data, buffer, size);
269 info->centry->info = g_new0 (MonoDebuggerClassInfo, 1); //allocate_class_entry (symfile);
270 info->centry->info->klass = klass;
272 info->centry->info->token = klass->element_class->type_token;
273 info->centry->info->rank = klass->rank;
275 info->centry->info->token = klass->type_token;
276 info->centry->info->type_info = info->type_info;
279 static MonoDebuggerBuiltinTypeInfo *
280 add_builtin_type (MonoDebuggerSymbolFile *symfile, MonoClass *klass)
282 MonoDebuggerClassEntry *centry;
283 MonoDebuggerBuiltinTypeInfo *info;
285 centry = g_new0 (MonoDebuggerClassEntry, 1);
287 info = g_new0 (MonoDebuggerBuiltinTypeInfo, 1);
289 info->centry = centry;
291 g_hash_table_insert (class_info_table, klass, centry);
293 write_builtin_type (mono_debugger_symbol_table, symfile, klass, info);
298 add_builtin_type_2 (MonoDebuggerBuiltinTypeInfo *info)
300 info->class_info = do_write_class (mono_debugger_symbol_table, info->klass, NULL);
301 * (guint32 *) (info->type_data + 5) = info->class_info;
305 add_exception_class (MonoDebuggerSymbolFile *symfile, MonoException *exc)
307 mono_debugger_start_add_type (symfile, ((MonoObject *) exc)->vtable->klass);
308 mono_debugger_add_type (symfile, ((MonoObject *) exc)->vtable->klass);
311 MonoDebuggerBuiltinTypes *
312 mono_debugger_add_builtin_types (MonoDebuggerSymbolFile *symfile)
314 MonoDebuggerBuiltinTypes *types = g_new0 (MonoDebuggerBuiltinTypes, 1);
317 mono_debugger_symbol_table->corlib = symfile;
318 mono_debugger_symbol_table->builtin_types = types;
320 types->total_size = sizeof (MonoDebuggerBuiltinTypes);
321 types->type_info_size = sizeof (MonoDebuggerBuiltinTypeInfo);
323 types->object_type = add_builtin_type (symfile, mono_defaults.object_class);
324 klass = mono_class_from_name (mono_defaults.corlib, "System", "ValueType");
326 types->valuetype_type = add_builtin_type (symfile, klass);
328 types->byte_type = add_builtin_type (symfile, mono_defaults.byte_class);
329 types->void_type = add_builtin_type (symfile, mono_defaults.void_class);
330 types->boolean_type = add_builtin_type (symfile, mono_defaults.boolean_class);
331 types->sbyte_type = add_builtin_type (symfile, mono_defaults.sbyte_class);
332 types->int16_type = add_builtin_type (symfile, mono_defaults.int16_class);
333 types->uint16_type = add_builtin_type (symfile, mono_defaults.uint16_class);
334 types->int32_type = add_builtin_type (symfile, mono_defaults.int32_class);
335 types->uint32_type = add_builtin_type (symfile, mono_defaults.uint32_class);
336 types->int_type = add_builtin_type (symfile, mono_defaults.int_class);
337 types->uint_type = add_builtin_type (symfile, mono_defaults.uint_class);
338 types->int64_type = add_builtin_type (symfile, mono_defaults.int64_class);
339 types->uint64_type = add_builtin_type (symfile, mono_defaults.uint64_class);
340 types->single_type = add_builtin_type (symfile, mono_defaults.single_class);
341 types->double_type = add_builtin_type (symfile, mono_defaults.double_class);
342 types->char_type = add_builtin_type (symfile, mono_defaults.char_class);
343 types->string_type = add_builtin_type (symfile, mono_defaults.string_class);
345 klass = mono_class_from_name (mono_defaults.corlib, "System", "Type");
347 types->type_type = add_builtin_type (symfile, klass);
349 types->enum_type = add_builtin_type (symfile, mono_defaults.enum_class);
350 types->array_type = add_builtin_type (symfile, mono_defaults.array_class);
351 types->exception_type = add_builtin_type (symfile, mono_defaults.exception_class);
353 add_builtin_type_2 (types->object_type);
354 add_builtin_type_2 (types->valuetype_type);
356 add_builtin_type_2 (types->byte_type);
357 add_builtin_type_2 (types->void_type);
358 add_builtin_type_2 (types->boolean_type);
359 add_builtin_type_2 (types->sbyte_type);
360 add_builtin_type_2 (types->int16_type);
361 add_builtin_type_2 (types->uint16_type);
362 add_builtin_type_2 (types->int32_type);
363 add_builtin_type_2 (types->uint32_type);
364 add_builtin_type_2 (types->int_type);
365 add_builtin_type_2 (types->uint_type);
366 add_builtin_type_2 (types->int64_type);
367 add_builtin_type_2 (types->uint64_type);
368 add_builtin_type_2 (types->single_type);
369 add_builtin_type_2 (types->double_type);
370 add_builtin_type_2 (types->char_type);
371 add_builtin_type_2 (types->string_type);
372 add_builtin_type_2 (types->type_type);
374 add_builtin_type_2 (types->enum_type);
375 add_builtin_type_2 (types->array_type);
376 add_builtin_type_2 (types->exception_type);
378 add_exception_class (symfile, mono_get_exception_divide_by_zero ());
379 add_exception_class (symfile, mono_get_exception_security ());
380 add_exception_class (symfile, mono_get_exception_arithmetic ());
381 add_exception_class (symfile, mono_get_exception_overflow ());
382 add_exception_class (symfile, mono_get_exception_null_reference ());
383 add_exception_class (symfile, mono_get_exception_thread_abort ());
384 add_exception_class (symfile, mono_get_exception_invalid_cast ());
385 add_exception_class (symfile, mono_get_exception_index_out_of_range ());
386 add_exception_class (symfile, mono_get_exception_thread_abort ());
387 add_exception_class (symfile, mono_get_exception_index_out_of_range ());
388 add_exception_class (symfile, mono_get_exception_array_type_mismatch ());
389 add_exception_class (symfile, mono_get_exception_missing_method ());
390 add_exception_class (symfile, mono_get_exception_appdomain_unloaded ());
391 add_exception_class (symfile, mono_get_exception_stack_overflow ());
393 builtin_types_initialized = TRUE;
399 write_class (MonoDebuggerSymbolTable *table, MonoClass *klass)
401 MonoDebuggerClassEntry *centry;
403 if (builtin_types_initialized && !klass->init_pending)
404 mono_class_init (klass);
406 centry = g_hash_table_lookup (class_info_table, klass);
408 MonoDebuggerSymbolFile *symfile = _mono_debugger_get_symfile (klass->image);
411 mono_debugger_start_add_type (symfile, klass);
412 centry = g_hash_table_lookup (class_info_table, klass);
417 g_assert (centry->info->type_info);
418 return centry->info->type_info;
421 if (!centry->type_reference) {
424 centry->type_reference = allocate_type_entry (table, 5, &ptr);
426 *ptr++ = MONO_DEBUGGER_TYPE_KIND_REFERENCE;
427 WRITE_POINTER (ptr, klass);
430 return centry->type_reference;
434 mono_debugger_start_add_type (MonoDebuggerSymbolFile *symfile, MonoClass *klass)
436 MonoDebuggerClassEntry *centry;
438 mono_debugger_lock ();
439 centry = g_hash_table_lookup (class_info_table, klass);
441 mono_debugger_unlock ();
445 centry = g_new0 (MonoDebuggerClassEntry, 1);
446 g_hash_table_insert (class_info_table, klass, centry);
447 mono_debugger_unlock ();
451 mono_debugger_add_type (MonoDebuggerSymbolFile *symfile, MonoClass *klass)
453 MonoDebuggerClassEntry *centry;
455 mono_debugger_lock ();
456 centry = g_hash_table_lookup (class_info_table, klass);
460 mono_debugger_unlock ();
464 centry->info = allocate_class_entry (symfile);
465 centry->info->klass = klass;
467 centry->info->token = klass->element_class->type_token;
468 centry->info->rank = klass->rank;
470 centry->info->token = klass->type_token;
472 do_write_class (mono_debugger_symbol_table, klass, centry->info);
474 g_assert (centry->info && centry->info->type_info);
476 symfile->generation++;
477 must_reload_symtabs = TRUE;
479 mono_debugger_unlock ();
483 mono_debugger_add_method (MonoDebuggerSymbolFile *symfile, MonoDebugMethodInfo *minfo,
484 MonoDebugMethodJitInfo *jit)
486 MonoSymbolFileMethodAddress *address;
487 MonoSymbolFileLexicalBlockEntry *block;
488 MonoDebugVarInfo *var_table;
489 MonoDebuggerRangeInfo *range;
490 MonoMethodHeader *header;
491 guint32 size, num_variables, variable_size, variable_offset;
492 guint32 type_size, type_offset, *type_index_table, has_this;
493 guint32 line_size, line_offset, block_offset, block_size;
494 MonoDebugLexicalBlockEntry *block_table;
495 MonoDebugLineNumberEntry *line_table;
500 if (!symfile->symfile->method_hash)
503 header = ((MonoMethodNormal *) minfo->method)->header;
505 symfile->generation++;
507 size = sizeof (MonoSymbolFileMethodAddress);
509 num_variables = jit->num_params + read32(&(minfo->entry->_num_locals));
510 has_this = jit->this_var != NULL;
512 variable_size = (num_variables + has_this) * sizeof (MonoDebugVarInfo);
513 variable_offset = size;
514 size += variable_size;
516 type_size = (num_variables + 1) * sizeof (gpointer);
520 if (jit->line_numbers) {
522 line_size = jit->line_numbers->len * sizeof (MonoDebugLineNumberEntry);
526 block_size = read32(&(minfo->entry->_num_lexical_blocks)) * sizeof (MonoSymbolFileLexicalBlockEntry);
530 address = g_malloc0 (size);
531 ptr = (guint8 *) address;
533 block = (MonoSymbolFileLexicalBlockEntry *)
534 (symfile->symfile->raw_contents + read32(&(minfo->entry->_lexical_block_table_offset)));
535 block_table = (MonoDebugLexicalBlockEntry *) (ptr + block_offset);
537 for (i = 0; i < read32(&(minfo->entry->_num_lexical_blocks)); i++, block++) {
538 block_table [i].start_address = _mono_debug_address_from_il_offset (jit, read32(&(block->_start_offset)));
539 block_table [i].end_address = _mono_debug_address_from_il_offset (jit, read32(&(block->_end_offset)));
542 address->size = size;
543 address->has_this = has_this;
544 address->num_params = jit->num_params;
545 address->start_address = jit->code_start;
546 address->end_address = jit->code_start + jit->code_size;
547 address->method_start_address = address->start_address + jit->prologue_end;
548 address->method_end_address = address->start_address + jit->epilogue_begin;
549 address->wrapper_address = jit->wrapper_addr;
550 address->variable_table_offset = variable_offset;
551 address->type_table_offset = type_offset;
552 address->lexical_block_table_offset = block_offset;
554 if (jit->line_numbers) {
555 address->num_line_numbers = jit->line_numbers->len;
556 address->line_number_offset = line_offset;
558 line_table = (MonoDebugLineNumberEntry *) (ptr + line_offset);
559 memcpy (line_table, jit->line_numbers->data, line_size);
562 range = allocate_range_entry (symfile);
563 range->index = minfo->index;
564 range->start_address = address->start_address;
565 range->end_address = address->end_address;
566 range->dynamic_data = address;
567 range->dynamic_size = size;
569 if ((minfo->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
570 (minfo->method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
571 (minfo->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
574 var_table = (MonoDebugVarInfo *) (ptr + variable_offset);
575 type_table = (guint32 *) (ptr + type_offset);
577 type_index_table = (guint32 *)
578 (symfile->symfile->raw_contents + read32(&(minfo->entry->_type_index_table_offset)));
581 *var_table++ = *jit->this_var;
582 *type_table++ = write_type (mono_debugger_symbol_table, &minfo->method->klass->this_arg);
584 for (i = 0; i < jit->num_params; i++) {
585 *var_table++ = jit->params [i];
586 *type_table++ = write_type (mono_debugger_symbol_table, minfo->method->signature->params [i]);
589 if (jit->num_locals < read32(&(minfo->entry->_num_locals))) {
590 g_warning (G_STRLOC ": Method %s.%s has %d locals, but symbol file claims it has %d.",
591 minfo->method->klass->name, minfo->method->name, jit->num_locals,
592 read32(&(minfo->entry->_num_locals)));
593 var_table += read32(&(minfo->entry->_num_locals));
595 g_assert ((header != NULL) || (minfo->entry->_num_locals == 0));
596 for (i = 0; i < read32(&(minfo->entry->_num_locals)); i++) {
597 *var_table++ = jit->locals [i];
598 *type_table++ = write_type (mono_debugger_symbol_table, header->locals [i]);
602 must_reload_symtabs = TRUE;
605 static MonoDebuggerRangeInfo *
606 allocate_range_entry (MonoDebuggerSymbolFile *symfile)
608 MonoDebuggerRangeInfo *retval;
609 guint32 size, chunks;
611 if (!symfile->range_table) {
612 size = sizeof (MonoDebuggerRangeInfo) * RANGE_TABLE_CHUNK_SIZE;
613 symfile->range_table = g_malloc0 (size);
614 symfile->num_range_entries = 1;
615 return symfile->range_table;
618 if (!((symfile->num_range_entries + 1) % RANGE_TABLE_CHUNK_SIZE)) {
619 chunks = (symfile->num_range_entries + 1) / RANGE_TABLE_CHUNK_SIZE;
620 size = sizeof (MonoDebuggerRangeInfo) * RANGE_TABLE_CHUNK_SIZE * (chunks + 1);
622 symfile->range_table = g_realloc (symfile->range_table, size);
625 retval = symfile->range_table + symfile->num_range_entries;
626 symfile->num_range_entries++;
630 static MonoDebuggerClassInfo *
631 allocate_class_entry (MonoDebuggerSymbolFile *symfile)
633 MonoDebuggerClassInfo *retval;
634 MonoDebuggerClassTable *table;
637 if (!symfile->class_table_start) {
638 table = g_new0 (MonoDebuggerClassTable, 1);
639 symfile->class_table_start = symfile->current_class_table = table;
641 size = sizeof (MonoDebuggerClassInfo) * CLASS_TABLE_CHUNK_SIZE;
642 table->data = g_malloc0 (size);
643 table->size = CLASS_TABLE_CHUNK_SIZE;
649 table = symfile->current_class_table;
650 if (table->index >= table->size) {
651 table = g_new0 (MonoDebuggerClassTable, 1);
653 symfile->current_class_table->next = table;
654 symfile->current_class_table = table;
656 size = sizeof (MonoDebuggerClassInfo) * CLASS_TABLE_CHUNK_SIZE;
657 table->data = g_malloc0 (size);
658 table->size = CLASS_TABLE_CHUNK_SIZE;
664 retval = table->data + table->index;
670 * Allocate a new entry of size `size' in the type table.
671 * Returns the global offset which is to be used to reference this type and
672 * a pointer (in the `ptr' argument) which is to be used to write the type.
675 allocate_type_entry (MonoDebuggerSymbolTable *table, guint32 size, guint8 **ptr)
680 g_assert (size + 4 < TYPE_TABLE_CHUNK_SIZE);
681 g_assert (ptr != NULL);
683 /* Initialize things if necessary. */
684 if (!table->current_type_table) {
685 table->current_type_table = g_malloc0 (TYPE_TABLE_CHUNK_SIZE);
686 table->type_table_size = TYPE_TABLE_CHUNK_SIZE;
687 table->type_table_chunk_size = TYPE_TABLE_CHUNK_SIZE;
688 table->type_table_offset = MONO_DEBUGGER_TYPE_MAX + 1;
692 /* First let's check whether there's still enough room in the current_type_table. */
693 if (table->type_table_offset + size + 4 < table->type_table_size) {
694 retval = table->type_table_offset;
695 table->type_table_offset += size + 4;
696 data = ((guint8 *) table->current_type_table) + retval - table->type_table_start;
697 *(gint32 *) data = size;
698 data += sizeof(gint32);
703 /* Add the current_type_table to the type_tables vector and ... */
704 if (!table->type_tables) {
705 guint32 tsize = sizeof (gpointer) * TYPE_TABLE_PTR_CHUNK_SIZE;
706 table->type_tables = g_malloc0 (tsize);
709 if (!((table->num_type_tables + 1) % TYPE_TABLE_PTR_CHUNK_SIZE)) {
710 guint32 chunks = (table->num_type_tables + 1) / TYPE_TABLE_PTR_CHUNK_SIZE;
711 guint32 tsize = sizeof (gpointer) * TYPE_TABLE_PTR_CHUNK_SIZE * (chunks + 1);
713 table->type_tables = g_realloc (table->type_tables, tsize);
716 table->type_tables [table->num_type_tables++] = table->current_type_table;
718 /* .... allocate a new current_type_table. */
719 table->current_type_table = g_malloc0 (TYPE_TABLE_CHUNK_SIZE);
720 table->type_table_start = table->type_table_offset = table->type_table_size;
721 table->type_table_size += TYPE_TABLE_CHUNK_SIZE;
727 * Allocate a new entry of size `size' in the misc table.
728 * Returns the global offset which is to be used to reference this entry and
729 * a pointer (in the `ptr' argument) which is to be used to write the entry.
732 allocate_misc_entry (MonoDebuggerSymbolTable *table, guint32 size, guint8 **ptr)
737 g_assert (size + 4 < MISC_TABLE_CHUNK_SIZE);
738 g_assert (ptr != NULL);
740 /* Initialize things if necessary. */
741 if (!table->current_misc_table) {
742 table->current_misc_table = g_malloc0 (MISC_TABLE_CHUNK_SIZE);
743 table->misc_table_size = MISC_TABLE_CHUNK_SIZE;
744 table->misc_table_chunk_size = MISC_TABLE_CHUNK_SIZE;
745 table->misc_table_offset = 1;
749 /* First let's check whether there's still enough room in the current_misc_table. */
750 if (table->misc_table_offset + size + 4 < table->misc_table_size) {
751 retval = table->misc_table_offset;
752 table->misc_table_offset += size + 4;
753 data = ((guint8 *) table->current_misc_table) + retval - table->misc_table_start;
754 *(gint32 *) data = size;
755 data += sizeof(gint32);
760 /* Add the current_misc_table to the misc_tables vector and ... */
761 if (!table->misc_tables) {
762 guint32 tsize = sizeof (gpointer) * MISC_TABLE_PTR_CHUNK_SIZE;
763 table->misc_tables = g_malloc0 (tsize);
766 if (!((table->num_misc_tables + 1) % MISC_TABLE_PTR_CHUNK_SIZE)) {
767 guint32 chunks = (table->num_misc_tables + 1) / MISC_TABLE_PTR_CHUNK_SIZE;
768 guint32 tsize = sizeof (gpointer) * MISC_TABLE_PTR_CHUNK_SIZE * (chunks + 1);
770 table->misc_tables = g_realloc (table->misc_tables, tsize);
773 table->misc_tables [table->num_misc_tables++] = table->current_misc_table;
775 /* .... allocate a new current_misc_table. */
776 table->current_misc_table = g_malloc0 (MISC_TABLE_CHUNK_SIZE);
777 table->misc_table_start = table->misc_table_offset = table->misc_table_size;
778 table->misc_table_size += MISC_TABLE_CHUNK_SIZE;
784 property_is_static (MonoProperty *prop)
792 return method->flags & METHOD_ATTRIBUTE_STATIC;
796 do_write_class (MonoDebuggerSymbolTable *table, MonoClass *klass, MonoDebuggerClassInfo *cinfo)
798 guint8 buffer [BUFSIZ], *ptr = buffer, *old_ptr;
799 GPtrArray *methods = NULL, *static_methods = NULL, *ctors = NULL;
800 int num_fields = 0, num_static_fields = 0, num_properties = 0, num_static_properties = 0;
801 int num_methods = 0, num_static_methods = 0, num_params = 0, num_static_params = 0, base_offset = 0;
802 int num_ctors = 0, num_ctor_params = 0;
803 int field_info_size = 0, static_field_info_size = 0, property_info_size = 0;
804 int static_property_info_size = 0, method_info_size = 0, static_method_info_size = 0;
805 int ctor_info_size = 0, iface_info_size = 0;
806 guint32 size, data_size, offset, data_offset;
807 GHashTable *method_slots = NULL;
810 if (klass->init_pending)
811 g_warning (G_STRLOC ": %p - %s.%s", klass, klass->name_space, klass->name);
812 g_assert (!klass->init_pending);
813 mono_class_init (klass);
815 offset = GPOINTER_TO_UINT (g_hash_table_lookup (class_table, klass));
819 if (klass->enumtype) {
820 offset = allocate_type_entry (table, 13, &ptr);
822 cinfo->type_info = offset;
823 g_hash_table_insert (class_table, klass, GUINT_TO_POINTER (offset));
825 *ptr++ = MONO_DEBUGGER_TYPE_KIND_ENUM;
826 WRITE_UINT32 (ptr, klass->instance_size);
827 WRITE_UINT32 (ptr, MONO_DEBUGGER_TYPE_ENUM);
828 WRITE_UINT32 (ptr, write_type (table, klass->enum_basetype));
832 for (i = 0; i < klass->field.count; i++)
833 if (!(klass->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC))
838 for (i = 0; i < klass->property.count; i++)
839 if (!property_is_static (&klass->properties [i]))
842 ++num_static_properties;
844 method_slots = g_hash_table_new (NULL, NULL);
845 methods = g_ptr_array_new ();
846 static_methods = g_ptr_array_new ();
847 ctors = g_ptr_array_new ();
849 for (i = 0; i < klass->method.count; i++) {
850 MonoMethod *method = klass->methods [i];
852 if (!strcmp (method->name, ".cctor"))
854 if (!((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))
857 if (!strcmp (method->name, ".ctor")) {
859 num_ctor_params += method->signature->param_count;
860 g_ptr_array_add (ctors, method);
864 if (method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME)
867 if (method->slot != -1) {
868 if (g_hash_table_lookup (method_slots, GUINT_TO_POINTER (method->slot)))
870 g_hash_table_insert (method_slots, GUINT_TO_POINTER (method->slot), method);
873 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
874 ++num_static_methods;
875 num_static_params += method->signature->param_count;
876 g_ptr_array_add (static_methods, method);
879 num_params += method->signature->param_count;
880 g_ptr_array_add (methods, method);
884 g_hash_table_destroy (method_slots);
886 field_info_size = num_fields * 8;
887 static_field_info_size = num_static_fields * 8;
888 property_info_size = num_properties * (4 + 2 * sizeof (gpointer));
889 static_property_info_size = num_static_properties * (4 + 2 * sizeof (gpointer));
890 method_info_size = num_methods * (4 + 2 * sizeof (gpointer)) + num_params * 4;
891 static_method_info_size = num_static_methods * (4 + 2 * sizeof (gpointer)) +
892 num_static_params * 4;
893 ctor_info_size = num_ctors * (4 + 2 * sizeof (gpointer)) + num_ctor_params * 4;
894 iface_info_size = klass->interface_count * 4;
896 size = 74 + sizeof (gpointer) + field_info_size + static_field_info_size +
897 property_info_size + static_property_info_size + method_info_size +
898 static_method_info_size + ctor_info_size + iface_info_size;
902 offset = allocate_type_entry (table, data_size, &ptr);
906 cinfo->type_info = offset;
908 g_hash_table_insert (class_table, klass, GUINT_TO_POINTER (offset));
910 *ptr++ = MONO_DEBUGGER_TYPE_KIND_CLASS_INFO;
912 if (klass->valuetype)
913 base_offset = - sizeof (MonoObject);
915 WRITE_UINT32 (ptr, klass->instance_size + base_offset);
916 *ptr++ = klass->valuetype;
917 WRITE_POINTER (ptr, klass);
919 WRITE_UINT32 (ptr, num_fields);
920 WRITE_UINT32 (ptr, data_offset);
921 data_offset += field_info_size;
922 WRITE_UINT32 (ptr, num_properties);
923 WRITE_UINT32 (ptr, data_offset);
924 data_offset += property_info_size;
925 WRITE_UINT32 (ptr, num_methods);
926 WRITE_UINT32 (ptr, data_offset);
927 data_offset += method_info_size;
928 WRITE_UINT32 (ptr, num_static_fields);
929 WRITE_UINT32 (ptr, data_offset);
930 data_offset += static_field_info_size;
931 WRITE_UINT32 (ptr, num_static_properties);
932 WRITE_UINT32 (ptr, data_offset);
933 data_offset += static_property_info_size;
934 WRITE_UINT32 (ptr, num_static_methods);
935 WRITE_UINT32 (ptr, data_offset);
936 data_offset += static_method_info_size;
937 WRITE_UINT32 (ptr, num_ctors);
938 WRITE_UINT32 (ptr, data_offset);
939 data_offset += ctor_info_size;
940 WRITE_UINT32 (ptr, klass->interface_count);
941 WRITE_UINT32 (ptr, data_offset);
942 data_offset += iface_info_size;
944 if (klass->parent && (klass->parent != mono_defaults.object_class))
945 WRITE_UINT32 (ptr, write_class (table, klass->parent));
947 WRITE_UINT32 (ptr, 0);
949 for (i = 0; i < klass->field.count; i++) {
950 if (klass->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC)
953 WRITE_UINT32 (ptr, klass->fields [i].offset + base_offset);
954 WRITE_UINT32 (ptr, write_type (table, klass->fields [i].type));
957 for (i = 0; i < klass->property.count; i++) {
958 if (property_is_static (&klass->properties [i]))
961 if (klass->properties [i].get)
962 WRITE_UINT32 (ptr, write_type (table, klass->properties [i].get->signature->ret));
964 WRITE_UINT32 (ptr, 0);
965 WRITE_POINTER (ptr, klass->properties [i].get);
966 WRITE_POINTER (ptr, klass->properties [i].set);
969 for (i = 0; i < methods->len; i++) {
970 MonoMethod *method = g_ptr_array_index (methods, i);
973 WRITE_POINTER (ptr, method);
974 if ((method->signature->ret) && (method->signature->ret->type != MONO_TYPE_VOID))
975 WRITE_UINT32 (ptr, write_type (table, method->signature->ret));
977 WRITE_UINT32 (ptr, 0);
978 WRITE_UINT32 (ptr, method->signature->param_count);
979 for (j = 0; j < method->signature->param_count; j++)
980 WRITE_UINT32 (ptr, write_type (table, method->signature->params [j]));
983 g_ptr_array_free (methods, FALSE);
985 for (i = 0; i < klass->field.count; i++) {
986 if (!(klass->fields [i].type->attrs & FIELD_ATTRIBUTE_STATIC))
989 WRITE_UINT32 (ptr, klass->fields [i].offset);
990 WRITE_UINT32 (ptr, write_type (table, klass->fields [i].type));
993 for (i = 0; i < klass->property.count; i++) {
994 if (!property_is_static (&klass->properties [i]))
997 if (klass->properties [i].get)
998 WRITE_UINT32 (ptr, write_type (table, klass->properties [i].get->signature->ret));
1000 WRITE_UINT32 (ptr, 0);
1001 WRITE_POINTER (ptr, klass->properties [i].get);
1002 WRITE_POINTER (ptr, klass->properties [i].set);
1005 for (i = 0; i < static_methods->len; i++) {
1006 MonoMethod *method = g_ptr_array_index (static_methods, i);
1009 WRITE_POINTER (ptr, method);
1010 if ((method->signature->ret) && (method->signature->ret->type != MONO_TYPE_VOID))
1011 WRITE_UINT32 (ptr, write_type (table, method->signature->ret));
1013 WRITE_UINT32 (ptr, 0);
1014 WRITE_UINT32 (ptr, method->signature->param_count);
1015 for (j = 0; j < method->signature->param_count; j++)
1016 WRITE_UINT32 (ptr, write_type (table, method->signature->params [j]));
1019 g_ptr_array_free (static_methods, FALSE);
1021 for (i = 0; i < ctors->len; i++) {
1022 MonoMethod *ctor = g_ptr_array_index (ctors, i);
1025 WRITE_POINTER (ptr, ctor);
1026 WRITE_UINT32 (ptr, 0);
1027 WRITE_UINT32 (ptr, ctor->signature->param_count);
1028 for (j = 0; j < ctor->signature->param_count; j++)
1029 WRITE_UINT32 (ptr, write_type (table, ctor->signature->params [j]));
1032 g_ptr_array_free (ctors, FALSE);
1034 for (i = 0; i < klass->interface_count; i++)
1035 WRITE_UINT32 (ptr, write_class (table, klass->interfaces [i]));
1037 if (ptr - old_ptr != data_size) {
1038 g_warning (G_STRLOC ": %d,%d,%d", ptr - old_ptr, data_size, sizeof (gpointer));
1040 g_warning (G_STRLOC ": %s.%s", klass->name_space, klass->name);
1041 g_assert_not_reached ();
1048 * Adds type `type' to the type table and returns its offset.
1051 write_type (MonoDebuggerSymbolTable *table, MonoType *type)
1053 guint8 buffer [BUFSIZ], *ptr = buffer;
1054 guint32 size, offset;
1057 offset = GPOINTER_TO_UINT (g_hash_table_lookup (type_table, type));
1061 klass = mono_class_from_mono_type (type);
1062 if (type->type == MONO_TYPE_CLASS)
1063 return write_class (table, klass);
1065 // mono_class_init (klass);
1067 switch (type->type) {
1068 case MONO_TYPE_VOID:
1069 return MONO_DEBUGGER_TYPE_VOID;
1071 case MONO_TYPE_BOOLEAN:
1072 return MONO_DEBUGGER_TYPE_BOOLEAN;
1075 return MONO_DEBUGGER_TYPE_I1;
1078 return MONO_DEBUGGER_TYPE_U1;
1080 case MONO_TYPE_CHAR:
1081 return MONO_DEBUGGER_TYPE_CHAR;
1084 return MONO_DEBUGGER_TYPE_I2;
1087 return MONO_DEBUGGER_TYPE_U2;
1090 return MONO_DEBUGGER_TYPE_I4;
1093 return MONO_DEBUGGER_TYPE_U4;
1096 return MONO_DEBUGGER_TYPE_I8;
1099 return MONO_DEBUGGER_TYPE_U8;
1102 return MONO_DEBUGGER_TYPE_R4;
1105 return MONO_DEBUGGER_TYPE_R8;
1107 case MONO_TYPE_STRING:
1108 return MONO_DEBUGGER_TYPE_STRING;
1111 return MONO_DEBUGGER_TYPE_I;
1114 return MONO_DEBUGGER_TYPE_U;
1116 case MONO_TYPE_SZARRAY: {
1119 *ptr++ = MONO_DEBUGGER_TYPE_KIND_SZARRAY;
1120 WRITE_UINT32 (ptr, sizeof (MonoArray));
1121 WRITE_UINT32 (ptr, MONO_DEBUGGER_TYPE_ARRAY);
1122 *ptr++ = (guint8*)&array.max_length - (guint8*)&array;
1123 *ptr++ = sizeof (array.max_length);
1124 *ptr++ = (guint8*)&array.vector - (guint8*)&array;
1125 WRITE_UINT32 (ptr, write_type (table, &type->data.klass->byval_arg));
1129 case MONO_TYPE_ARRAY: {
1131 MonoArrayBounds bounds;
1133 *ptr++ = MONO_DEBUGGER_TYPE_KIND_ARRAY;
1134 WRITE_UINT32 (ptr, sizeof (MonoArray));
1135 WRITE_UINT32 (ptr, MONO_DEBUGGER_TYPE_ARRAY);
1136 *ptr++ = (guint8*)&array.max_length - (guint8*)&array;
1137 *ptr++ = sizeof (array.max_length);
1138 *ptr++ = (guint8*)&array.vector - (guint8*)&array;
1139 *ptr++ = klass->rank;
1140 *ptr++ = (guint8*)&array.bounds - (guint8*)&array;
1141 *ptr++ = sizeof (MonoArrayBounds);
1142 *ptr++ = (guint8*)&bounds.lower_bound - (guint8*)&bounds;
1143 *ptr++ = sizeof (bounds.lower_bound);
1144 *ptr++ = (guint8*)&bounds.length - (guint8*)&bounds;
1145 *ptr++ = sizeof (bounds.length);
1146 WRITE_UINT32 (ptr, write_type (table, &type->data.array->eklass->byval_arg));
1150 case MONO_TYPE_VALUETYPE:
1151 case MONO_TYPE_CLASS:
1152 case MONO_TYPE_GENERICINST:
1153 case MONO_TYPE_OBJECT:
1154 return write_class (table, klass);
1157 *ptr++ = MONO_DEBUGGER_TYPE_KIND_POINTER;
1158 WRITE_UINT32 (ptr, sizeof (gpointer));
1159 WRITE_UINT32 (ptr, write_type (table, type->data.type));
1163 /* g_message (G_STRLOC ": %s.%s - %p - %d", klass->name_space, klass->name, klass, type->type); */
1164 *ptr++ = MONO_DEBUGGER_TYPE_KIND_UNKNOWN;
1165 WRITE_UINT32 (ptr, klass->instance_size);
1166 WRITE_UINT32 (ptr, write_class (table, klass));
1170 size = ptr - buffer;
1171 offset = allocate_type_entry (mono_debugger_symbol_table, size, &ptr);
1172 memcpy (ptr, buffer, size);
1177 MonoReflectionMethod *
1178 ves_icall_MonoDebugger_GetMethod (MonoReflectionAssembly *assembly, guint32 token)
1182 method = mono_get_method (mono_assembly_get_image (assembly->assembly), token, NULL);
1184 return mono_method_get_object (mono_domain_get (), method, NULL);
1188 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionAssembly *assembly, MonoReflectionMethod *method)
1190 return method->method->token;
1193 MonoReflectionType *
1194 ves_icall_MonoDebugger_GetType (MonoReflectionAssembly *assembly, guint32 token)
1198 klass = mono_class_get (mono_assembly_get_image (assembly->assembly), token);
1200 g_warning (G_STRLOC ": %x", token);
1204 return mono_type_get_object (mono_domain_get (), &klass->byval_arg);
1207 MonoReflectionType *
1208 ves_icall_MonoDebugger_GetLocalTypeFromSignature (MonoReflectionAssembly *assembly, MonoArray *signature)
1216 MONO_CHECK_ARG_NULL (assembly);
1217 MONO_CHECK_ARG_NULL (signature);
1219 domain = mono_domain_get();
1220 image = mono_assembly_get_image (assembly->assembly);
1222 ptr = mono_array_addr (signature, char, 0);
1223 g_assert (*ptr++ == 0x07);
1224 len = mono_metadata_decode_value (ptr, &ptr);
1225 g_assert (len == 1);
1227 type = mono_metadata_parse_type (image, MONO_PARSE_LOCAL, 0, ptr, &ptr);
1229 return mono_type_get_object (domain, type);
1233 mono_debugger_event (MonoDebuggerEvent event, gpointer data, guint32 arg)
1235 if (mono_debugger_event_handler)
1236 (* mono_debugger_event_handler) (event, data, arg);
1240 mono_debugger_cleanup (void)
1242 /* Do nothing yet. */
1246 * Debugger breakpoint interface.
1248 * This interface is used to insert breakpoints on methods which are not yet JITed.
1249 * The debugging code keeps a list of all such breakpoints and automatically inserts the
1250 * breakpoint when the method is JITed.
1253 static GPtrArray *breakpoints = NULL;
1256 mono_debugger_insert_breakpoint_full (MonoMethodDesc *desc)
1258 static int last_breakpoint_id = 0;
1259 MonoDebuggerBreakpointInfo *info;
1261 info = g_new0 (MonoDebuggerBreakpointInfo, 1);
1263 info->index = ++last_breakpoint_id;
1266 breakpoints = g_ptr_array_new ();
1268 g_ptr_array_add (breakpoints, info);
1274 mono_debugger_remove_breakpoint (int breakpoint_id)
1281 for (i = 0; i < breakpoints->len; i++) {
1282 MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i);
1284 if (info->index != breakpoint_id)
1287 mono_method_desc_free (info->desc);
1288 g_ptr_array_remove (breakpoints, info);
1297 mono_debugger_insert_breakpoint (const gchar *method_name, gboolean include_namespace)
1299 MonoMethodDesc *desc;
1301 desc = mono_method_desc_new (method_name, include_namespace);
1305 return mono_debugger_insert_breakpoint_full (desc);
1309 mono_debugger_method_has_breakpoint (MonoMethod *method)
1313 if (!breakpoints || (method->wrapper_type != MONO_WRAPPER_NONE))
1316 for (i = 0; i < breakpoints->len; i++) {
1317 MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i);
1319 if (!mono_method_desc_full_match (info->desc, method))
1329 mono_debugger_breakpoint_callback (MonoMethod *method, guint32 index)
1331 mono_debugger_event (MONO_DEBUGGER_EVENT_BREAKPOINT, method, index);
1335 mono_debugger_unhandled_exception (gpointer addr, MonoObject *exc)
1337 if (!mono_debugger_initialized)
1340 // Prevent the object from being finalized.
1341 last_exception = exc;
1342 mono_debugger_event (MONO_DEBUGGER_EVENT_UNHANDLED_EXCEPTION, exc, addr);
1347 get_exception_message (MonoObject *exc)
1349 char *message = NULL;
1355 if (mono_object_isinst (exc, mono_defaults.exception_class)) {
1356 klass = exc->vtable->klass;
1358 while (klass && method == NULL) {
1359 for (i = 0; i < klass->method.count; ++i) {
1360 method = klass->methods [i];
1361 if (!strcmp ("ToString", method->name) &&
1362 method->signature->param_count == 0 &&
1363 method->flags & METHOD_ATTRIBUTE_VIRTUAL &&
1364 method->flags & METHOD_ATTRIBUTE_PUBLIC) {
1371 klass = klass->parent;
1376 str = (MonoString *) mono_runtime_invoke (method, exc, NULL, NULL);
1378 message = mono_string_to_utf8 (str);
1385 mono_debugger_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
1390 if (method->klass->valuetype && (obj != NULL))
1391 obj = mono_value_box (mono_domain_get (), method->klass, obj);
1393 if (!strcmp (method->name, ".ctor")) {
1394 retval = obj = mono_object_new (mono_domain_get (), method->klass);
1396 mono_runtime_invoke (method, obj, params, exc);
1398 retval = mono_runtime_invoke (method, obj, params, exc);
1400 if (!exc || (*exc == NULL))
1403 message = get_exception_message (*exc);
1405 *exc = (MonoObject *) mono_string_new_wrapper (message);
1413 mono_debugger_lookup_type (const gchar *type_name)
1417 mono_debugger_lock ();
1419 for (i = 0; i < mono_debugger_symbol_table->num_symbol_files; i++) {
1420 MonoDebuggerSymbolFile *symfile = mono_debugger_symbol_table->symbol_files [i];
1425 name = g_strdup (type_name);
1426 type = mono_reflection_type_from_name (name, symfile->image);
1431 offset = write_type (mono_debugger_symbol_table, type);
1433 mono_debugger_unlock ();
1437 mono_debugger_unlock ();
1442 mono_debugger_lookup_assembly (const gchar *name)
1444 MonoAssembly *assembly;
1445 MonoImageOpenStatus status;
1448 mono_debugger_lock ();
1451 for (i = 0; i < mono_debugger_symbol_table->num_symbol_files; i++) {
1452 MonoDebuggerSymbolFile *symfile = mono_debugger_symbol_table->symbol_files [i];
1454 if (!strcmp (symfile->image_file, name)) {
1455 mono_debugger_unlock ();
1460 assembly = mono_assembly_open (name, &status);
1462 if (status != MONO_IMAGE_OK) {
1463 g_warning (G_STRLOC ": Cannot open image `%s'", name);
1464 mono_debugger_unlock ();
1468 must_reload_symtabs = TRUE;
1473 mono_debugger_add_wrapper (MonoMethod *wrapper, MonoDebugMethodJitInfo *jit, gpointer addr)
1475 guint32 size, offset;
1478 if (!mono_debugger_symbol_table)
1481 size = strlen (wrapper->name) + 5 + 5 * sizeof (gpointer);
1483 offset = allocate_misc_entry (mono_debugger_symbol_table, size, &ptr);
1485 WRITE_UINT32 (ptr, MONO_DEBUGGER_MISC_ENTRY_TYPE_WRAPPER);
1486 WRITE_STRING (ptr, wrapper->name);
1487 WRITE_POINTER (ptr, jit->code_start);
1488 WRITE_POINTER (ptr, jit->code_start + jit->code_size);
1489 WRITE_POINTER (ptr, addr);
1490 WRITE_POINTER (ptr, jit->code_start + jit->prologue_end);
1491 WRITE_POINTER (ptr, jit->code_start + jit->epilogue_begin);