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