Merged into single file, added assertions
[mono.git] / mono / metadata / mono-debug.c
1 /*
2  * mono-debug.c: 
3  *
4  * Author:
5  *      Mono Project (http://www.mono-project.com)
6  *
7  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
8  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
9  * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
10  */
11
12 #include <config.h>
13 #include <mono/metadata/assembly.h>
14 #include <mono/metadata/tabledefs.h>
15 #include <mono/metadata/tokentype.h>
16 #include <mono/metadata/appdomain.h>
17 #include <mono/metadata/class-internals.h>
18 #include <mono/metadata/mono-debug.h>
19 #include <mono/metadata/mono-debug-debugger.h>
20 #include <mono/metadata/mono-endian.h>
21 #include <mono/metadata/gc-internal.h>
22 #include <string.h>
23
24 #define DATA_TABLE_CHUNK_SIZE           (16384-sizeof (MonoDebugDataChunk))
25
26 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
27
28 #if NO_UNALIGNED_ACCESS
29 #define RETURN_UNALIGNED(type, addr) \
30         { \
31                 type val; \
32                 memcpy(&val, p + offset, sizeof(val)); \
33                 return val; \
34         }
35 #define WRITE_UNALIGNED(type, addr, val) \
36         memcpy(addr, &val, sizeof(type))
37 #define READ_UNALIGNED(type, addr, val) \
38         memcpy(&val, addr, sizeof(type))
39 #else
40 #define RETURN_UNALIGNED(type, addr) \
41         return *(type*)(p + offset);
42 #define WRITE_UNALIGNED(type, addr, val) \
43         (*(type *)(addr) = (val))
44 #define READ_UNALIGNED(type, addr, val) \
45         val = (*(type *)(addr))
46 #endif
47
48 typedef enum {
49         MONO_DEBUG_DATA_ITEM_UNKNOWN            = 0,
50         MONO_DEBUG_DATA_ITEM_CLASS,
51         MONO_DEBUG_DATA_ITEM_METHOD,
52         MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE
53 } MonoDebugDataItemType;
54
55 typedef struct _MonoDebugDataChunk MonoDebugDataChunk;
56
57 struct _MonoDebugDataChunk {
58         guint32 total_size;
59         guint32 allocated_size;
60         guint32 current_offset;
61         guint32 dummy;
62         MonoDebugDataChunk *next;
63         guint8 data [MONO_ZERO_LEN_ARRAY];
64 };
65
66 struct _MonoDebugDataTable {
67         gint32 domain;
68         gint32 _dummy; /* alignment for next field. */
69         MonoDebugDataChunk *first_chunk;
70         MonoDebugDataChunk *current_chunk;
71         GHashTable *method_hash;
72         GHashTable *method_address_hash;
73 };
74
75 typedef struct {
76         const gchar *method_name;
77         const gchar *obsolete_cil_code;
78         guint32 wrapper_type;
79 } MonoDebugWrapperData;
80
81 typedef struct {
82         guint32 size;
83         guint32 symfile_id;
84         guint32 domain_id;
85         guint32 method_id;
86         MonoDebugWrapperData *wrapper_data;
87         MonoMethod *method;
88         GSList *address_list;
89 } MonoDebugMethodHeader;
90
91 struct _MonoDebugMethodAddress {
92         MonoDebugMethodHeader header;
93         const guint8 *code_start;
94         const guint8 *wrapper_addr;
95         guint32 code_size;
96         guint8 data [MONO_ZERO_LEN_ARRAY];
97 };
98
99 struct _MonoDebugClassEntry {
100         guint32 size;
101         guint8 data [MONO_ZERO_LEN_ARRAY];
102 };
103
104 typedef struct {
105         gpointer code;
106         guint32 size;
107 } MonoDebugDelegateTrampolineEntry;
108
109 MonoSymbolTable *mono_symbol_table = NULL;
110 MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
111 gint32 mono_debug_debugger_version = 5;
112 gint32 _mono_debug_using_mono_debugger = 0;
113
114 static gboolean mono_debug_initialized = FALSE;
115 static GHashTable *mono_debug_handles = NULL;
116
117 static GHashTable *data_table_hash = NULL;
118 static int next_symbol_file_id = 0;
119
120 static MonoDebugHandle     *mono_debug_open_image      (MonoImage *image, const guint8 *raw_contents, int size);
121
122 static MonoDebugHandle     *_mono_debug_get_image      (MonoImage *image);
123 static void                 mono_debug_add_assembly    (MonoAssembly *assembly,
124                                                         gpointer user_data);
125 static void                 mono_debug_add_type        (MonoClass *klass);
126
127 static MonoDebugHandle     *open_symfile_from_bundle   (MonoImage *image);
128
129 void _mono_debug_init_corlib (MonoDomain *domain);
130
131 extern void (*mono_debugger_class_init_func) (MonoClass *klass);
132 extern void (*mono_debugger_class_loaded_methods_func) (MonoClass *klass);
133
134 static MonoDebugDataTable *
135 create_data_table (MonoDomain *domain)
136 {
137         MonoDebugDataTable *table;
138         MonoDebugDataChunk *chunk;
139
140         table = g_new0 (MonoDebugDataTable, 1);
141         table->domain = domain ? mono_domain_get_id (domain) : -1;
142
143         table->method_address_hash = g_hash_table_new (NULL, NULL);
144         table->method_hash = g_hash_table_new (NULL, NULL);
145
146         chunk = g_malloc0 (sizeof (MonoDebugDataChunk) + DATA_TABLE_CHUNK_SIZE);
147         chunk->total_size = DATA_TABLE_CHUNK_SIZE;
148
149         table->first_chunk = table->current_chunk = chunk;
150
151         if (domain) {
152                 mono_debug_list_add (&mono_symbol_table->data_tables, table);
153                 g_hash_table_insert (data_table_hash, domain, table);
154         }
155
156         return table;
157 }
158
159 static void
160 free_header_data (gpointer key, gpointer value, gpointer user_data)
161 {
162         MonoDebugMethodHeader *header = (MonoDebugMethodHeader*)value;
163
164         if (header->wrapper_data) {
165                 g_free ((gpointer)header->wrapper_data->method_name);
166                 g_free (header->wrapper_data);
167         }
168         g_slist_free (header->address_list);
169 }
170
171 static void
172 free_data_table (MonoDebugDataTable *table)
173 {
174         MonoDebugDataChunk *chunk, *next_chunk;
175
176         g_hash_table_foreach (table->method_hash, free_header_data, NULL);
177         g_hash_table_destroy (table->method_hash);
178         g_hash_table_destroy (table->method_address_hash);
179
180         table->method_hash = NULL;
181         table->method_address_hash = NULL;
182
183         chunk = table->first_chunk;
184         while (chunk) {
185                 next_chunk = chunk->next;
186                 g_free (chunk);
187                 chunk = next_chunk;
188         }
189
190         table->first_chunk = table->current_chunk = NULL;
191         mono_debug_list_remove (&mono_symbol_table->data_tables, table);
192         g_free (table);
193 }
194
195 static MonoDebugDataTable *
196 lookup_data_table (MonoDomain *domain)
197 {
198         MonoDebugDataTable *table;
199
200         table = g_hash_table_lookup (data_table_hash, domain);
201         g_assert (table);
202         return table;
203 }
204
205 static void
206 free_debug_handle (MonoDebugHandle *handle)
207 {
208         if (handle->symfile)
209                 mono_debug_close_mono_symbol_file (handle->symfile);
210         /* decrease the refcount added with mono_image_addref () */
211         free_data_table (handle->type_table);
212         mono_image_close (handle->image);
213         g_free (handle->image_file);
214         g_free (handle);
215 }
216
217 /*
218  * Initialize debugging support.
219  *
220  * This method must be called after loading corlib,
221  * but before opening the application's main assembly because we need to set some
222  * callbacks here.
223  */
224 void
225 mono_debug_init (MonoDebugFormat format)
226 {
227         g_assert (!mono_debug_initialized);
228
229         if (_mono_debug_using_mono_debugger)
230                 format = MONO_DEBUG_FORMAT_DEBUGGER;
231
232         mono_debug_initialized = TRUE;
233         mono_debug_format = format;
234
235         /*
236          * This must be called before mono_debugger_initialize(), because the
237          * latter registers GC roots.
238          */
239         mono_gc_base_init ();
240
241         mono_debugger_initialize (_mono_debug_using_mono_debugger);
242
243         mono_debugger_lock ();
244
245         mono_symbol_table = g_new0 (MonoSymbolTable, 1);
246         mono_symbol_table->magic = MONO_DEBUGGER_MAGIC;
247         mono_symbol_table->version = MONO_DEBUGGER_MAJOR_VERSION;
248         mono_symbol_table->total_size = sizeof (MonoSymbolTable);
249
250         mono_debug_handles = g_hash_table_new_full
251                 (NULL, NULL, NULL, (GDestroyNotify) free_debug_handle);
252
253         data_table_hash = g_hash_table_new_full (
254                 NULL, NULL, NULL, (GDestroyNotify) free_data_table);
255
256         mono_debugger_class_init_func = mono_debug_add_type;
257         mono_debugger_class_loaded_methods_func = mono_debugger_class_initialized;
258         mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
259
260         mono_symbol_table->global_data_table = create_data_table (NULL);
261
262         mono_debugger_unlock ();
263 }
264
265 /*
266  * INTERNAL USE ONLY !
267  */
268 void
269 _mono_debug_init_corlib (MonoDomain *domain)
270 {
271         if (!mono_debug_initialized)
272                 return;
273
274         mono_symbol_table->corlib = mono_debug_open_image (mono_defaults.corlib, NULL, 0);
275         mono_debugger_event (MONO_DEBUGGER_EVENT_INITIALIZE_CORLIB,
276                              (guint64) (gsize) mono_symbol_table->corlib, 0);
277 }
278
279 void
280 mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents, int size)
281 {
282         if (!mono_debug_initialized)
283                 return;
284
285         mono_debug_open_image (image, raw_contents, size);
286 }
287
288
289 gboolean
290 mono_debug_using_mono_debugger (void)
291 {
292         return _mono_debug_using_mono_debugger;
293 }
294
295 void
296 mono_debug_cleanup (void)
297 {
298         if (mono_debug_handles)
299                 g_hash_table_destroy (mono_debug_handles);
300         mono_debug_handles = NULL;
301
302         if (data_table_hash) {
303                 g_hash_table_destroy (data_table_hash);
304                 data_table_hash = NULL;
305         }
306
307         if (mono_symbol_table) {
308                 if (mono_symbol_table->global_data_table)
309                         free_data_table (mono_symbol_table->global_data_table);
310
311                 g_free (mono_symbol_table);
312                 mono_symbol_table = NULL;
313         }
314 }
315
316 void
317 mono_debug_domain_create (MonoDomain *domain)
318 {
319         MonoDebugDataTable *table;
320
321         if (!mono_debug_initialized)
322                 return;
323
324         mono_debugger_lock ();
325
326         table = create_data_table (domain);
327
328         mono_debugger_event (MONO_DEBUGGER_EVENT_DOMAIN_CREATE, (guint64) (gsize) table,
329                              mono_domain_get_id (domain));
330
331         mono_debugger_unlock ();
332 }
333
334 void
335 mono_debug_domain_unload (MonoDomain *domain)
336 {
337         MonoDebugDataTable *table;
338
339         if (!mono_debug_initialized)
340                 return;
341
342         mono_debugger_lock ();
343
344         table = g_hash_table_lookup (data_table_hash, domain);
345         if (!table) {
346                 g_warning (G_STRLOC ": unloading unknown domain %p / %d",
347                            domain, mono_domain_get_id (domain));
348                 mono_debugger_unlock ();
349                 return;
350         }
351
352         mono_debugger_event (MONO_DEBUGGER_EVENT_DOMAIN_UNLOAD, (guint64) (gsize) table,
353                              mono_domain_get_id (domain));
354
355         g_hash_table_remove (data_table_hash, domain);
356
357         mono_debugger_unlock ();
358 }
359
360 /*
361  * LOCKING: Assumes the debug lock is held.
362  */
363 static MonoDebugHandle *
364 _mono_debug_get_image (MonoImage *image)
365 {
366         return g_hash_table_lookup (mono_debug_handles, image);
367 }
368
369 void
370 mono_debug_close_image (MonoImage *image)
371 {
372         MonoDebugHandle *handle;
373
374         if (!mono_debug_initialized)
375                 return;
376
377         mono_debugger_lock ();
378
379         handle = _mono_debug_get_image (image);
380         if (!handle) {
381                 mono_debugger_unlock ();
382                 return;
383         }
384
385         mono_debugger_event (MONO_DEBUGGER_EVENT_UNLOAD_MODULE, (guint64) (gsize) handle,
386                              handle->index);
387
388         mono_debug_list_remove (&mono_symbol_table->symbol_files, handle);
389         g_hash_table_remove (mono_debug_handles, image);
390
391         mono_debugger_unlock ();
392 }
393
394 static MonoDebugHandle *
395 mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
396 {
397         MonoDebugHandle *handle;
398
399         if (mono_image_is_dynamic (image))
400                 return NULL;
401
402         mono_debugger_lock ();
403
404         handle = _mono_debug_get_image (image);
405         if (handle != NULL) {
406                 mono_debugger_unlock ();
407                 return handle;
408         }
409
410         handle = g_new0 (MonoDebugHandle, 1);
411         handle->index = ++next_symbol_file_id;
412
413         handle->image = image;
414         mono_image_addref (image);
415         handle->image_file = g_strdup (mono_image_get_filename (image));
416
417         handle->type_table = create_data_table (NULL);
418
419         handle->symfile = mono_debug_open_mono_symbols (
420                 handle, raw_contents, size, _mono_debug_using_mono_debugger);
421
422         mono_debug_list_add (&mono_symbol_table->symbol_files, handle);
423
424         g_hash_table_insert (mono_debug_handles, image, handle);
425
426         if (mono_symbol_table->corlib)
427                 mono_debugger_event (MONO_DEBUGGER_EVENT_LOAD_MODULE,
428                                      (guint64) (gsize) handle, 0);
429
430         mono_debugger_unlock ();
431
432         return handle;
433 }
434
435 static void
436 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
437 {
438         MonoDebugHandle *handle;
439         MonoImage *image;
440
441         mono_debugger_lock ();
442         image = mono_assembly_get_image (assembly);
443         handle = open_symfile_from_bundle (image);
444         if (!handle)
445                 mono_debug_open_image (image, NULL, 0);
446         mono_debugger_unlock ();
447 }
448
449 static guint8 *
450 allocate_data_item (MonoDebugDataTable *table, MonoDebugDataItemType type, guint32 size)
451 {
452         guint32 chunk_size;
453         guint8 *data;
454
455         size = ALIGN_TO (size, sizeof (gpointer));
456
457         if (size + 16 < DATA_TABLE_CHUNK_SIZE)
458                 chunk_size = DATA_TABLE_CHUNK_SIZE;
459         else
460                 chunk_size = size + 16;
461
462         g_assert (table->current_chunk->current_offset == table->current_chunk->allocated_size);
463
464         if (table->current_chunk->allocated_size + size + 8 >= table->current_chunk->total_size) {
465                 MonoDebugDataChunk *new_chunk;
466
467                 new_chunk = g_malloc0 (sizeof (MonoDebugDataChunk) + chunk_size);
468                 new_chunk->total_size = chunk_size;
469
470                 table->current_chunk->next = new_chunk;
471                 table->current_chunk = new_chunk;
472         }
473
474         data = &table->current_chunk->data [table->current_chunk->allocated_size];
475         table->current_chunk->allocated_size += size + 8;
476
477         * ((guint32 *) data) = size;
478         data += 4;
479         * ((guint32 *) data) = type;
480         data += 4;
481         return data;
482 }
483
484 static void
485 write_data_item (MonoDebugDataTable *table, const guint8 *data)
486 {
487         MonoDebugDataChunk *current_chunk = table->current_chunk;
488         guint32 size = * ((guint32 *) (data - 8));
489
490         g_assert (current_chunk->current_offset + size + 8 == current_chunk->allocated_size);
491         current_chunk->current_offset = current_chunk->allocated_size;
492 }
493
494 struct LookupMethodData
495 {
496         MonoDebugMethodInfo *minfo;
497         MonoMethod *method;
498 };
499
500 static void
501 lookup_method_func (gpointer key, gpointer value, gpointer user_data)
502 {
503         MonoDebugHandle *handle = (MonoDebugHandle *) value;
504         struct LookupMethodData *data = (struct LookupMethodData *) user_data;
505
506         if (data->minfo)
507                 return;
508
509         if (handle->symfile)
510                 data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
511 }
512
513 static MonoDebugMethodInfo *
514 _mono_debug_lookup_method (MonoMethod *method)
515 {
516         struct LookupMethodData data;
517
518         data.minfo = NULL;
519         data.method = method;
520
521         if (!mono_debug_handles)
522                 return NULL;
523
524         g_hash_table_foreach (mono_debug_handles, lookup_method_func, &data);
525         return data.minfo;
526 }
527
528 /**
529  * mono_debug_lookup_method:
530  *
531  * Lookup symbol file information for the method @method.  The returned
532  * `MonoDebugMethodInfo' is a private structure, but it can be passed to
533  * mono_debug_symfile_lookup_location().
534  */
535 MonoDebugMethodInfo *
536 mono_debug_lookup_method (MonoMethod *method)
537 {
538         MonoDebugMethodInfo *minfo;
539
540         mono_debugger_lock ();
541         minfo = _mono_debug_lookup_method (method);
542         mono_debugger_unlock ();
543         return minfo;
544 }
545
546 static inline void
547 write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
548 {
549         do {
550                 guint8 byte = value & 0x7f;
551                 value >>= 7;
552                 if (value)
553                         byte |= 0x80;
554                 *ptr++ = byte;
555         } while (value);
556
557         *rptr = ptr;
558 }
559
560 static inline void
561 write_sleb128 (gint32 value, guint8 *ptr, guint8 **rptr)
562 {
563         gboolean more = 1;
564
565         while (more) {
566                 guint8 byte = value & 0x7f;
567                 value >>= 7;
568
569                 if (((value == 0) && ((byte & 0x40) == 0)) || ((value == -1) && (byte & 0x40)))
570                         more = 0;
571                 else
572                         byte |= 0x80;
573                 *ptr++ = byte;
574         }
575
576         *rptr = ptr;
577 }
578
579 static void
580 write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
581 {
582         write_leb128 (var->index, ptr, &ptr);
583         write_sleb128 (var->offset, ptr, &ptr);
584         write_leb128 (var->size, ptr, &ptr);
585         write_leb128 (var->begin_scope, ptr, &ptr);
586         write_leb128 (var->end_scope, ptr, &ptr);
587         WRITE_UNALIGNED (gpointer, ptr, var->type);
588         ptr += sizeof (gpointer);
589         *rptr = ptr;
590 }
591
592 MonoDebugMethodAddress *
593 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
594 {
595         MonoMethod *declaring;
596         MonoDebugDataTable *table;
597         MonoDebugMethodHeader *header;
598         MonoDebugMethodAddress *address;
599         MonoDebugMethodInfo *minfo;
600         MonoDebugHandle *handle;
601         guint8 buffer [BUFSIZ];
602         guint8 *ptr, *oldptr;
603         guint32 i, size, total_size, max_size;
604         gboolean is_wrapper = FALSE;
605
606         mono_debugger_lock ();
607
608         table = lookup_data_table (domain);
609
610         handle = _mono_debug_get_image (method->klass->image);
611         minfo = _mono_debug_lookup_method (method);
612
613         if (!minfo || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
614             (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
615             (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
616             (method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
617             (method->wrapper_type != MONO_WRAPPER_NONE)) {
618                 is_wrapper = TRUE;
619         }
620
621         max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) +
622                 (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals);
623
624         if (max_size > BUFSIZ)
625                 ptr = oldptr = g_malloc (max_size);
626         else
627                 ptr = oldptr = buffer;
628
629         write_leb128 (jit->prologue_end, ptr, &ptr);
630         write_leb128 (jit->epilogue_begin, ptr, &ptr);
631
632         write_leb128 (jit->num_line_numbers, ptr, &ptr);
633         for (i = 0; i < jit->num_line_numbers; i++) {
634                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
635
636                 write_sleb128 (lne->il_offset, ptr, &ptr);
637                 write_sleb128 (lne->native_offset, ptr, &ptr);
638         }
639
640         *ptr++ = jit->this_var ? 1 : 0;
641         if (jit->this_var)
642                 write_variable (jit->this_var, ptr, &ptr);
643
644         write_leb128 (jit->num_params, ptr, &ptr);
645         for (i = 0; i < jit->num_params; i++)
646                 write_variable (&jit->params [i], ptr, &ptr);
647
648         write_leb128 (jit->num_locals, ptr, &ptr);
649         for (i = 0; i < jit->num_locals; i++)
650                 write_variable (&jit->locals [i], ptr, &ptr);
651
652         size = ptr - oldptr;
653         g_assert (size < max_size);
654         total_size = size + sizeof (MonoDebugMethodAddress);
655
656         if (method->dynamic) {
657                 address = g_malloc0 (total_size);
658         } else {
659                 address = (MonoDebugMethodAddress *) allocate_data_item (
660                                   table, MONO_DEBUG_DATA_ITEM_METHOD, total_size);
661         }
662
663         address->header.size = total_size;
664         address->header.symfile_id = handle ? handle->index : 0;
665         address->header.domain_id = mono_domain_get_id (domain);
666         address->header.method_id = is_wrapper ? 0 : minfo->index;
667         address->header.method = method;
668
669         address->code_start = jit->code_start;
670         address->code_size = jit->code_size;
671
672         memcpy (&address->data, oldptr, size);
673         if (max_size > BUFSIZ)
674                 g_free (oldptr);
675
676         declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
677         header = g_hash_table_lookup (table->method_hash, declaring);
678
679         if (!header) {
680                 header = &address->header;
681                 g_hash_table_insert (table->method_hash, declaring, header);
682
683                 if (is_wrapper) {
684                         MonoDebugWrapperData *wrapper;
685
686                         header->wrapper_data = wrapper = g_new0 (MonoDebugWrapperData, 1);
687
688                         wrapper->wrapper_type = method->wrapper_type;
689                         wrapper->method_name = mono_method_full_name (declaring, TRUE);
690                         wrapper->obsolete_cil_code = "";
691                 }
692         } else {
693                 address->header.wrapper_data = header->wrapper_data;
694                 header->address_list = g_slist_prepend (header->address_list, address);
695         }
696
697         g_hash_table_insert (table->method_address_hash, method, address);
698
699         if (!method->dynamic)
700                 write_data_item (table, (guint8 *) address);
701
702         mono_debugger_unlock ();
703         return address;
704 }
705
706 void
707 mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
708 {
709         MonoMethod *declaring;
710         MonoDebugDataTable *table;
711         MonoDebugMethodHeader *header;
712         MonoDebugMethodAddress *address;
713
714         if (!mono_debug_initialized)
715                 return;
716
717         g_assert (method->dynamic);
718
719         mono_debugger_lock ();
720
721         table = lookup_data_table (domain);
722
723         declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
724         g_hash_table_remove (table->method_hash, declaring);
725
726         address = g_hash_table_lookup (table->method_address_hash, method);
727         if (address) {
728                 header = &address->header;
729
730                 if (header->wrapper_data) {
731                         g_free ((char*)header->wrapper_data->method_name);
732                         g_free (header->wrapper_data);
733                 }
734                 g_free (address);
735         }
736
737         g_hash_table_remove (table->method_address_hash, method);
738
739         mono_debugger_unlock ();
740 }
741
742 void
743 mono_debug_add_delegate_trampoline (gpointer code, int size)
744 {
745         MonoDebugDelegateTrampolineEntry *entry;
746
747         if (!mono_debug_initialized)
748                 return;
749
750         mono_debugger_lock ();
751
752         entry = (MonoDebugDelegateTrampolineEntry *) allocate_data_item (
753                 mono_symbol_table->global_data_table, MONO_DEBUG_DATA_ITEM_DELEGATE_TRAMPOLINE,
754                 sizeof (MonoDebugDelegateTrampolineEntry));
755         entry->code = code;
756         entry->size = size;
757
758         write_data_item (mono_symbol_table->global_data_table, (guint8 *) entry);
759
760         mono_debugger_unlock ();
761 }
762
763 static inline guint32
764 read_leb128 (guint8 *ptr, guint8 **rptr)
765 {
766         guint32 result = 0, shift = 0;
767
768         while (TRUE) {
769                 guint8 byte = *ptr++;
770
771                 result |= (byte & 0x7f) << shift;
772                 if ((byte & 0x80) == 0)
773                         break;
774                 shift += 7;
775         }
776
777         *rptr = ptr;
778         return result;
779 }
780
781 static inline gint32
782 read_sleb128 (guint8 *ptr, guint8 **rptr)
783 {
784         gint32 result = 0;
785         guint32 shift = 0;
786
787         while (TRUE) {
788                 guint8 byte = *ptr++;
789
790                 result |= (byte & 0x7f) << shift;
791                 shift += 7;
792
793                 if (byte & 0x80)
794                         continue;
795
796                 if ((shift < 32) && (byte & 0x40))
797                         result |= - (1 << shift);
798                 break;
799         }
800
801         *rptr = ptr;
802         return result;
803 }
804
805 static void
806 read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
807 {
808         var->index = read_leb128 (ptr, &ptr);
809         var->offset = read_sleb128 (ptr, &ptr);
810         var->size = read_leb128 (ptr, &ptr);
811         var->begin_scope = read_leb128 (ptr, &ptr);
812         var->end_scope = read_leb128 (ptr, &ptr);
813         READ_UNALIGNED (gpointer, ptr, var->type);
814         ptr += sizeof (gpointer);
815         *rptr = ptr;
816 }
817
818 void
819 mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
820 {
821         if (!jit)
822                 return;
823         g_free (jit->line_numbers);
824         g_free (jit->this_var);
825         g_free (jit->params);
826         g_free (jit->locals);
827         g_free (jit);
828 }
829
830 static MonoDebugMethodJitInfo *
831 mono_debug_read_method (MonoDebugMethodAddress *address)
832 {
833         MonoDebugMethodJitInfo *jit;
834         guint32 i;
835         guint8 *ptr;
836
837         jit = g_new0 (MonoDebugMethodJitInfo, 1);
838         jit->code_start = address->code_start;
839         jit->code_size = address->code_size;
840         jit->wrapper_addr = address->wrapper_addr;
841
842         ptr = (guint8 *) &address->data;
843
844         jit->prologue_end = read_leb128 (ptr, &ptr);
845         jit->epilogue_begin = read_leb128 (ptr, &ptr);
846
847         jit->num_line_numbers = read_leb128 (ptr, &ptr);
848         jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
849         for (i = 0; i < jit->num_line_numbers; i++) {
850                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
851
852                 lne->il_offset = read_sleb128 (ptr, &ptr);
853                 lne->native_offset = read_sleb128 (ptr, &ptr);
854         }
855
856         if (*ptr++) {
857                 jit->this_var = g_new0 (MonoDebugVarInfo, 1);
858                 read_variable (jit->this_var, ptr, &ptr);
859         }
860
861         jit->num_params = read_leb128 (ptr, &ptr);
862         jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
863         for (i = 0; i < jit->num_params; i++)
864                 read_variable (&jit->params [i], ptr, &ptr);
865
866         jit->num_locals = read_leb128 (ptr, &ptr);
867         jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
868         for (i = 0; i < jit->num_locals; i++)
869                 read_variable (&jit->locals [i], ptr, &ptr);
870
871         return jit;
872 }
873
874 static void
875 mono_debug_add_type (MonoClass *klass)
876 {
877         MonoDebugHandle *handle;
878         MonoDebugClassEntry *entry;
879         guint8 buffer [BUFSIZ];
880         guint8 *ptr, *oldptr;
881         guint32 size, total_size, max_size;
882         int base_offset = 0;
883
884         if (klass->generic_class || klass->rank ||
885             (klass->byval_arg.type == MONO_TYPE_VAR) || (klass->byval_arg.type == MONO_TYPE_MVAR))
886                 return;
887
888         mono_debugger_lock ();
889
890         handle = _mono_debug_get_image (klass->image);
891         if (!handle) {
892                 mono_debugger_unlock ();
893                 return;
894         }
895
896         max_size = 12 + sizeof (gpointer);
897         if (max_size > BUFSIZ)
898                 ptr = oldptr = g_malloc (max_size);
899         else
900                 ptr = oldptr = buffer;
901
902         if (klass->valuetype)
903                 base_offset = - (int)(sizeof (MonoObject));
904
905         write_leb128 (klass->type_token, ptr, &ptr);
906         write_leb128 (klass->instance_size + base_offset, ptr, &ptr);
907         WRITE_UNALIGNED (gpointer, ptr, klass);
908         ptr += sizeof (gpointer);
909
910         size = ptr - oldptr;
911         g_assert (size < max_size);
912         total_size = size + sizeof (MonoDebugClassEntry);
913
914         g_assert (total_size + 9 < DATA_TABLE_CHUNK_SIZE);
915
916         entry = (MonoDebugClassEntry *) allocate_data_item (
917                 handle->type_table, MONO_DEBUG_DATA_ITEM_CLASS, total_size);
918
919         entry->size = total_size;
920
921         memcpy (&entry->data, oldptr, size);
922
923         write_data_item (handle->type_table, (guint8 *) entry);
924
925         if (max_size > BUFSIZ)
926                 g_free (oldptr);
927
928         mono_debugger_unlock ();
929 }
930
931 static MonoDebugMethodJitInfo *
932 find_method (MonoMethod *method, MonoDomain *domain)
933 {
934         MonoDebugDataTable *table;
935         MonoDebugMethodAddress *address;
936
937         table = lookup_data_table (domain);
938         address = g_hash_table_lookup (table->method_address_hash, method);
939
940         if (!address)
941                 return NULL;
942
943         return mono_debug_read_method (address);
944 }
945
946 MonoDebugMethodJitInfo *
947 mono_debug_find_method (MonoMethod *method, MonoDomain *domain)
948 {
949         MonoDebugMethodJitInfo *res;
950
951         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
952                 return NULL;
953
954         mono_debugger_lock ();
955         res = find_method (method, domain);
956         mono_debugger_unlock ();
957         return res;
958 }
959
960 struct LookupMethodAddressData
961 {
962         MonoMethod *method;
963         MonoDebugMethodHeader *result;
964 };
965
966 static void
967 lookup_method_address_func (gpointer key, gpointer value, gpointer user_data)
968 {
969         MonoDebugDataTable *table = (MonoDebugDataTable *) value;
970         struct LookupMethodAddressData *data = (struct LookupMethodAddressData *) user_data;
971         MonoDebugMethodHeader *header;
972
973         header = g_hash_table_lookup (table->method_hash, data->method);
974         if (header)
975                 data->result = header;
976 }
977
978 MonoDebugMethodAddressList *
979 mono_debug_lookup_method_addresses (MonoMethod *method)
980 {
981         MonoDebugMethodAddressList *info;
982         MonoDebugMethodHeader *header = NULL;
983         struct LookupMethodAddressData data;
984         MonoMethod *declaring;
985         int count, size;
986         GSList *list;
987         guint8 *ptr;
988
989         g_assert ((mono_debug_debugger_version == 4) || (mono_debug_debugger_version == 5));
990
991         mono_debugger_lock ();
992
993         declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
994
995         data.method = declaring;
996         data.result = NULL;
997
998         g_hash_table_foreach (data_table_hash, lookup_method_address_func, &data);
999         header = data.result;
1000
1001         if (!header) {
1002                 mono_debugger_unlock ();
1003                 return NULL;
1004         }
1005
1006         count = g_slist_length (header->address_list) + 1;
1007         size = sizeof (MonoDebugMethodAddressList) + count * sizeof (gpointer);
1008
1009         info = g_malloc0 (size);
1010         info->size = size;
1011         info->count = count;
1012
1013         ptr = info->data;
1014
1015         WRITE_UNALIGNED (gpointer, ptr, header);
1016         ptr += sizeof (gpointer);
1017
1018         for (list = header->address_list; list; list = list->next) {
1019                 WRITE_UNALIGNED (gpointer, ptr, list->data);
1020                 ptr += sizeof (gpointer);
1021         }
1022
1023         mono_debugger_unlock ();
1024         return info;
1025 }
1026
1027 static gint32
1028 il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
1029 {
1030         MonoDebugMethodJitInfo *jit;
1031         int i;
1032
1033         jit = find_method (method, domain);
1034         if (!jit || !jit->line_numbers)
1035                 goto cleanup_and_fail;
1036
1037         for (i = jit->num_line_numbers - 1; i >= 0; i--) {
1038                 MonoDebugLineNumberEntry lne = jit->line_numbers [i];
1039
1040                 if (lne.native_offset <= native_offset) {
1041                         mono_debug_free_method_jit_info (jit);
1042                         return lne.il_offset;
1043                 }
1044         }
1045
1046 cleanup_and_fail:
1047         mono_debug_free_method_jit_info (jit);
1048         return -1;
1049 }
1050
1051 /**
1052  * mono_debug_il_offset_from_address:
1053  *
1054  *   Compute the IL offset corresponding to NATIVE_OFFSET inside the native
1055  * code of METHOD in DOMAIN.
1056  */
1057 gint32
1058 mono_debug_il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
1059 {
1060         gint32 res;
1061
1062         mono_debugger_lock ();
1063
1064         res = il_offset_from_address (method, domain, native_offset);
1065
1066         mono_debugger_unlock ();
1067
1068         return res;
1069 }
1070
1071 /**
1072  * mono_debug_lookup_source_location:
1073  * @address: Native offset within the @method's machine code.
1074  *
1075  * Lookup the source code corresponding to the machine instruction located at
1076  * native offset @address within @method.
1077  *
1078  * The returned `MonoDebugSourceLocation' contains both file / line number
1079  * information and the corresponding IL offset.  It must be freed by
1080  * mono_debug_free_source_location().
1081  */
1082 MonoDebugSourceLocation *
1083 mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
1084 {
1085         MonoDebugMethodInfo *minfo;
1086         MonoDebugSourceLocation *location;
1087         gint32 offset;
1088
1089         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
1090                 return NULL;
1091
1092         mono_debugger_lock ();
1093         minfo = _mono_debug_lookup_method (method);
1094         if (!minfo || !minfo->handle || !minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile)) {
1095                 mono_debugger_unlock ();
1096                 return NULL;
1097         }
1098
1099         offset = il_offset_from_address (method, domain, address);
1100         if (offset < 0) {
1101                 mono_debugger_unlock ();
1102                 return NULL;
1103         }
1104
1105         location = mono_debug_symfile_lookup_location (minfo, offset);
1106         mono_debugger_unlock ();
1107         return location;
1108 }
1109
1110 /*
1111  * mono_debug_lookup_locals:
1112  *
1113  *   Return information about the local variables of MINFO.
1114  * The result should be freed using mono_debug_symfile_free_locals ().
1115  */
1116 MonoDebugLocalsInfo*
1117 mono_debug_lookup_locals (MonoMethod *method)
1118 {
1119         MonoDebugMethodInfo *minfo;
1120         MonoDebugLocalsInfo *res;
1121
1122         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
1123                 return NULL;
1124
1125         mono_debugger_lock ();
1126         minfo = _mono_debug_lookup_method (method);
1127         if (!minfo || !minfo->handle || !minfo->handle->symfile || !mono_debug_symfile_is_loaded (minfo->handle->symfile)) {
1128                 mono_debugger_unlock ();
1129                 return NULL;
1130         }
1131
1132         res = mono_debug_symfile_lookup_locals (minfo);
1133         mono_debugger_unlock ();
1134
1135         return res;
1136 }
1137
1138 /**
1139  * mono_debug_free_source_location:
1140  * @location: A `MonoDebugSourceLocation'.
1141  *
1142  * Frees the @location.
1143  */
1144 void
1145 mono_debug_free_source_location (MonoDebugSourceLocation *location)
1146 {
1147         if (location) {
1148                 g_free (location->source_file);
1149                 g_free (location);
1150         }
1151 }
1152
1153 /**
1154  * mono_debug_print_stack_frame:
1155  * @native_offset: Native offset within the @method's machine code.
1156  *
1157  * Conventient wrapper around mono_debug_lookup_source_location() which can be
1158  * used if you only want to use the location to print a stack frame.
1159  */
1160 gchar *
1161 mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
1162 {
1163         MonoDebugSourceLocation *location;
1164         gchar *fname, *ptr, *res;
1165         int offset;
1166
1167         fname = mono_method_full_name (method, TRUE);
1168         for (ptr = fname; *ptr; ptr++) {
1169                 if (*ptr == ':') *ptr = '.';
1170         }
1171
1172         location = mono_debug_lookup_source_location (method, native_offset, domain);
1173
1174         if (!location) {
1175                 if (mono_debug_initialized) {
1176                         mono_debugger_lock ();
1177                         offset = il_offset_from_address (method, domain, native_offset);
1178                         mono_debugger_unlock ();
1179                 } else {
1180                         offset = -1;
1181                 }
1182
1183                 if (offset < 0)
1184                         res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
1185                 else
1186                         res = g_strdup_printf ("at %s <IL 0x%05x, 0x%05x>", fname, offset, native_offset);
1187                 g_free (fname);
1188                 return res;
1189         }
1190
1191         res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
1192                                location->source_file, location->row);
1193
1194         g_free (fname);
1195         mono_debug_free_source_location (location);
1196         return res;
1197 }
1198
1199 void
1200 mono_debug_list_add (MonoDebugList **list, gconstpointer data)
1201 {
1202         MonoDebugList *element, **ptr;
1203
1204         element = g_new0 (MonoDebugList, 1);
1205         element->data = data;
1206
1207         for (ptr = list; *ptr; ptr = &(*ptr)->next)
1208                 ;
1209
1210         *ptr = element;
1211 }
1212
1213 void
1214 mono_debug_list_remove (MonoDebugList **list, gconstpointer data)
1215 {
1216         MonoDebugList **ptr;
1217         MonoDebugList *next;
1218
1219         for (ptr = list; *ptr; ptr = &(*ptr)->next) {
1220                 if ((*ptr)->data != data)
1221                         continue;
1222
1223                 next = (*ptr)->next;
1224                 g_free ((*ptr));
1225                 *ptr = next;
1226                 break;
1227         }
1228 }
1229
1230 static gboolean is_attached = FALSE;
1231
1232 void
1233 mono_set_is_debugger_attached (gboolean attached)
1234 {
1235         is_attached = attached;
1236 }
1237
1238 gboolean
1239 mono_is_debugger_attached (void)
1240 {
1241         return is_attached;
1242 }
1243
1244 /*
1245  * Bundles
1246  */
1247
1248 typedef struct _BundledSymfile BundledSymfile;
1249
1250 struct _BundledSymfile {
1251         BundledSymfile *next;
1252         const char *aname;
1253         const mono_byte *raw_contents;
1254         int size;
1255 };
1256
1257 static BundledSymfile *bundled_symfiles = NULL;
1258
1259 void
1260 mono_register_symfile_for_assembly (const char *assembly_name, const mono_byte *raw_contents, int size)
1261 {
1262         BundledSymfile *bsymfile;
1263
1264         bsymfile = g_new0 (BundledSymfile, 1);
1265         bsymfile->aname = assembly_name;
1266         bsymfile->raw_contents = raw_contents;
1267         bsymfile->size = size;
1268         bsymfile->next = bundled_symfiles;
1269         bundled_symfiles = bsymfile;
1270 }
1271
1272 static MonoDebugHandle *
1273 open_symfile_from_bundle (MonoImage *image)
1274 {
1275         BundledSymfile *bsymfile;
1276
1277         for (bsymfile = bundled_symfiles; bsymfile; bsymfile = bsymfile->next) {
1278                 if (strcmp (bsymfile->aname, image->module_name))
1279                         continue;
1280
1281                 return mono_debug_open_image (image, bsymfile->raw_contents, bsymfile->size);
1282         }
1283
1284         return NULL;
1285 }