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