2007-06-28 Martin Baulig <martin@ximian.com>
[mono.git] / mono / metadata / mono-debug.c
1 #include <config.h>
2 #include <mono/metadata/assembly.h>
3 #include <mono/metadata/tabledefs.h>
4 #include <mono/metadata/tokentype.h>
5 #include <mono/metadata/appdomain.h>
6 #include <mono/metadata/class-internals.h>
7 #include <mono/metadata/mono-debug.h>
8 #include <mono/metadata/mono-debug-debugger.h>
9 #include <mono/metadata/mono-endian.h>
10 #include <string.h>
11
12 #define SYMFILE_TABLE_CHUNK_SIZE        16
13 #define DATA_TABLE_PTR_CHUNK_SIZE       256
14 #define DATA_TABLE_CHUNK_SIZE           32768
15
16 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
17
18 #if NO_UNALIGNED_ACCESS
19 #define RETURN_UNALIGNED(type, addr) \
20         { \
21                 type val; \
22                 memcpy(&val, p + offset, sizeof(val)); \
23                 return val; \
24         }
25 #define WRITE_UNALIGNED(type, addr, val) \
26         memcpy(addr, &val, sizeof(type))
27 #else
28 #define RETURN_UNALIGNED(type, addr) \
29         return *(type*)(p + offset);
30 #define WRITE_UNALIGNED(type, addr, val) \
31         (*(type *)(addr) = (val))
32 #endif
33
34 MonoSymbolTable *mono_symbol_table = NULL;
35 MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
36 guint32 mono_debug_debugger_version = -1;
37
38 static gboolean in_the_mono_debugger = FALSE;
39 static gboolean mono_debug_initialized = FALSE;
40 GHashTable *mono_debug_handles = NULL;
41
42 static GHashTable *method_hash = NULL;
43
44 static MonoDebugHandle     *mono_debug_open_image      (MonoImage *image, const guint8 *raw_contents, int size);
45
46 static void                 mono_debug_close_image     (MonoDebugHandle *debug);
47
48 static MonoDebugHandle     *_mono_debug_get_image      (MonoImage *image);
49 static void                 mono_debug_add_assembly    (MonoAssembly *assembly,
50                                                         gpointer user_data);
51 static void                 mono_debug_start_add_type  (MonoClass *klass);
52 static void                 mono_debug_add_type        (MonoClass *klass);
53
54 extern void (*mono_debugger_class_init_func) (MonoClass *klass);
55 extern void (*mono_debugger_start_class_init_func) (MonoClass *klass);
56
57 typedef struct {
58         guint32 symfile_id;
59         guint32 domain_id;
60         guint32 method_id;
61 } MethodHashEntry;
62
63 static guint
64 method_hash_hash (gconstpointer data)
65 {
66         const MethodHashEntry *entry = (const MethodHashEntry *) data;
67         return entry->symfile_id | (entry->domain_id << 16);
68 }
69
70 static gint
71 method_hash_equal (gconstpointer ka, gconstpointer kb)
72 {
73         const MethodHashEntry *a = (const MethodHashEntry *) ka;
74         const MethodHashEntry *b = (const MethodHashEntry *) kb;
75
76         if ((a->symfile_id != b->symfile_id) || (a->method_id != b->method_id) || (a->domain_id != b->domain_id))
77                 return 0;
78         return 1;
79 }
80
81 /*
82  * Initialize debugging support.
83  *
84  * This method must be called after loading corlib,
85  * but before opening the application's main assembly because we need to set some
86  * callbacks here.
87  */
88 void
89 mono_debug_init (MonoDebugFormat format)
90 {
91         g_assert (!mono_debug_initialized);
92
93         mono_debug_initialized = TRUE;
94         mono_debug_format = format;
95         in_the_mono_debugger = format == MONO_DEBUG_FORMAT_DEBUGGER;
96
97         mono_debugger_initialize (in_the_mono_debugger);
98
99         mono_debugger_lock ();
100
101         mono_symbol_table = g_new0 (MonoSymbolTable, 1);
102         mono_symbol_table->magic = MONO_DEBUGGER_MAGIC;
103         mono_symbol_table->version = MONO_DEBUGGER_VERSION;
104         mono_symbol_table->total_size = sizeof (MonoSymbolTable);
105
106         mono_debug_handles = g_hash_table_new_full
107                 (NULL, NULL, NULL, (GDestroyNotify) mono_debug_close_image);
108         method_hash = g_hash_table_new (method_hash_hash, method_hash_equal);
109
110         mono_debugger_start_class_init_func = mono_debug_start_add_type;
111         mono_debugger_class_init_func = mono_debug_add_type;
112         mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
113
114         if (!in_the_mono_debugger)
115                 mono_debugger_unlock ();
116 }
117
118 void
119 mono_debug_init_1 (MonoDomain *domain)
120 {
121         MonoDebugHandle *handle = mono_debug_open_image (mono_get_corlib (), NULL, 0);
122
123         mono_symbol_table->corlib = handle;
124 }
125
126 /*
127  * Initialize debugging support - part 2.
128  *
129  * This method must be called after loading the application's main assembly.
130  */
131 void
132 mono_debug_init_2 (MonoAssembly *assembly)
133 {
134         mono_debug_open_image (mono_assembly_get_image (assembly), NULL, 0);
135 }
136
137 /*
138  * Initialize debugging support - part 2.
139  *
140  * This method must be called between loading the image and loading the assembly.
141  */
142 void
143 mono_debug_init_2_memory (MonoImage *image, const guint8 *raw_contents, int size)
144 {
145         mono_debug_open_image (image, raw_contents, size);
146 }
147
148
149 gboolean
150 mono_debug_using_mono_debugger (void)
151 {
152         return in_the_mono_debugger;
153 }
154
155 void
156 mono_debug_cleanup (void)
157 {
158         mono_debugger_cleanup ();
159
160         if (mono_debug_handles)
161                 g_hash_table_destroy (mono_debug_handles);
162         mono_debug_handles = NULL;
163 }
164
165 static MonoDebugHandle *
166 _mono_debug_get_image (MonoImage *image)
167 {
168         return g_hash_table_lookup (mono_debug_handles, image);
169 }
170
171 static MonoDebugHandle *
172 allocate_debug_handle (MonoSymbolTable *table)
173 {
174         MonoDebugHandle *handle;
175
176         if (!table->symbol_files)
177                 table->symbol_files = g_new0 (MonoDebugHandle *, SYMFILE_TABLE_CHUNK_SIZE);
178         else if (!((table->num_symbol_files + 1) % SYMFILE_TABLE_CHUNK_SIZE)) {
179                 guint32 chunks = (table->num_symbol_files + 1) / SYMFILE_TABLE_CHUNK_SIZE;
180                 guint32 size = sizeof (MonoDebugHandle *) * SYMFILE_TABLE_CHUNK_SIZE * (chunks + 1);
181
182                 table->symbol_files = g_realloc (table->symbol_files, size);
183         }
184
185         handle = g_new0 (MonoDebugHandle, 1);
186         handle->index = table->num_symbol_files;
187         table->symbol_files [table->num_symbol_files++] = handle;
188         return handle;
189 }
190
191 static MonoDebugHandle *
192 mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
193 {
194         MonoDebugHandle *handle;
195
196         if (mono_image_is_dynamic (image))
197                 return NULL;
198
199         handle = _mono_debug_get_image (image);
200         if (handle != NULL)
201                 return handle;
202
203         handle = allocate_debug_handle (mono_symbol_table);
204
205         handle->image = image;
206         mono_image_addref (image);
207         handle->image_file = g_strdup (mono_image_get_filename (image));
208
209         g_hash_table_insert (mono_debug_handles, image, handle);
210
211         handle->symfile = mono_debug_open_mono_symbols (handle, raw_contents, size, in_the_mono_debugger);
212         if (in_the_mono_debugger)
213                 mono_debugger_add_symbol_file (handle);
214
215         return handle;
216 }
217
218 static void
219 mono_debug_close_image (MonoDebugHandle *handle)
220 {
221         if (handle->symfile)
222                 mono_debug_close_mono_symbol_file (handle->symfile);
223         /* decrease the refcount added with mono_image_addref () */
224         mono_image_close (handle->image);
225         g_free (handle->image_file);
226         g_free (handle->_priv);
227         g_free (handle);
228 }
229
230 static void
231 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
232 {
233         mono_debugger_lock ();
234         mono_debug_open_image (mono_assembly_get_image (assembly), NULL, 0);
235         mono_debugger_unlock ();
236 }
237
238 /*
239  * Allocate a new data item of size `size'.
240  * Returns the global offset which is to be used to reference this data item and
241  * a pointer (in the `ptr' argument) which is to be used to write it.
242  */
243 static guint8 *
244 allocate_data_item (MonoDebugDataItemType type, guint32 size)
245 {
246         guint32 chunk_size;
247         guint8 *data;
248
249         g_assert (mono_symbol_table);
250
251         size = ALIGN_TO (size, sizeof (gpointer));
252
253         if (size + 16 < DATA_TABLE_CHUNK_SIZE)
254                 chunk_size = DATA_TABLE_CHUNK_SIZE;
255         else
256                 chunk_size = size + 16;
257
258         /* Initialize things if necessary. */
259         if (!mono_symbol_table->current_data_table) {
260                 mono_symbol_table->current_data_table = g_malloc0 (chunk_size);
261                 mono_symbol_table->current_data_table_size = chunk_size;
262                 mono_symbol_table->current_data_table_offset = sizeof (gpointer);
263
264                 * ((guint32 *) mono_symbol_table->current_data_table) = chunk_size;
265         }
266
267  again:
268         /* First let's check whether there's still enough room in the current_data_table. */
269         if (mono_symbol_table->current_data_table_offset + size + 8 < mono_symbol_table->current_data_table_size) {
270                 data = ((guint8 *) mono_symbol_table->current_data_table) + mono_symbol_table->current_data_table_offset;
271                 mono_symbol_table->current_data_table_offset += size + 8;
272
273                 * ((guint32 *) data) = size;
274                 data += 4;
275                 * ((guint32 *) data) = type;
276                 data += 4;
277                 return data;
278         }
279
280         /* Add the current_data_table to the data_tables vector and ... */
281         if (!mono_symbol_table->data_tables) {
282                 guint32 tsize = sizeof (gpointer) * DATA_TABLE_PTR_CHUNK_SIZE;
283                 mono_symbol_table->data_tables = g_malloc0 (tsize);
284         }
285
286         if (!((mono_symbol_table->num_data_tables + 1) % DATA_TABLE_PTR_CHUNK_SIZE)) {
287                 guint32 chunks = (mono_symbol_table->num_data_tables + 1) / DATA_TABLE_PTR_CHUNK_SIZE;
288                 guint32 tsize = sizeof (gpointer) * DATA_TABLE_PTR_CHUNK_SIZE * (chunks + 1);
289
290                 mono_symbol_table->data_tables = g_realloc (mono_symbol_table->data_tables, tsize);
291         }
292
293         mono_symbol_table->data_tables [mono_symbol_table->num_data_tables++] = mono_symbol_table->current_data_table;
294
295         /* .... allocate a new current_data_table. */
296         mono_symbol_table->current_data_table = g_malloc0 (chunk_size);
297         mono_symbol_table->current_data_table_size = chunk_size;
298         mono_symbol_table->current_data_table_offset = sizeof (gpointer);
299         * ((guint32 *) mono_symbol_table->current_data_table) = chunk_size;
300
301         goto again;
302 }
303
304 struct LookupMethodData
305 {
306         MonoDebugMethodInfo *minfo;
307         MonoMethod *method;
308 };
309
310 static void
311 lookup_method_func (gpointer key, gpointer value, gpointer user_data)
312 {
313         MonoDebugHandle *handle = (MonoDebugHandle *) value;
314         struct LookupMethodData *data = (struct LookupMethodData *) user_data;
315
316         if (data->minfo)
317                 return;
318
319         if (handle->symfile)
320                 data->minfo = mono_debug_symfile_lookup_method (handle, data->method);
321 }
322
323 static MonoDebugMethodInfo *
324 _mono_debug_lookup_method (MonoMethod *method)
325 {
326         struct LookupMethodData data;
327
328         data.minfo = NULL;
329         data.method = method;
330
331         if (!mono_debug_handles)
332                 return NULL;
333
334         g_hash_table_foreach (mono_debug_handles, lookup_method_func, &data);
335         return data.minfo;
336 }
337
338 /**
339  * mono_debug_lookup_method:
340  *
341  * Lookup symbol file information for the method @method.  The returned
342  * `MonoDebugMethodInfo' is a private structure, but it can be passed to
343  * mono_debug_symfile_lookup_location().
344  */
345 MonoDebugMethodInfo *
346 mono_debug_lookup_method (MonoMethod *method)
347 {
348         MonoDebugMethodInfo *minfo;
349
350         mono_debugger_lock ();
351         minfo = _mono_debug_lookup_method (method);
352         mono_debugger_unlock ();
353         return minfo;
354 }
355
356 static inline void
357 write_leb128 (guint32 value, guint8 *ptr, guint8 **rptr)
358 {
359         do {
360                 guint8 byte = value & 0x7f;
361                 value >>= 7;
362                 if (value)
363                         byte |= 0x80;
364                 *ptr++ = byte;
365         } while (value);
366
367         *rptr = ptr;
368 }
369
370 static inline void
371 write_sleb128 (gint32 value, guint8 *ptr, guint8 **rptr)
372 {
373         gboolean more = 1;
374
375         while (more) {
376                 guint8 byte = value & 0x7f;
377                 value >>= 7;
378
379                 if (((value == 0) && ((byte & 0x40) == 0)) || ((value == -1) && (byte & 0x40)))
380                         more = 0;
381                 else
382                         byte |= 0x80;
383                 *ptr++ = byte;
384         }
385
386         *rptr = ptr;
387 }
388
389 static void
390 write_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
391 {
392         write_leb128 (var->index, ptr, &ptr);
393         write_sleb128 (var->offset, ptr, &ptr);
394         write_leb128 (var->size, ptr, &ptr);
395         write_leb128 (var->begin_scope, ptr, &ptr);
396         write_leb128 (var->end_scope, ptr, &ptr);
397         *rptr = ptr;
398 }
399
400 static MonoDebugWrapperData *
401 mono_debug_add_wrapper (MonoMethod *method, MonoDebugMethodJitInfo *jit)
402 {
403         MonoMethodHeader *header;
404         MonoDebugWrapperData *wrapper;
405         guint8 buffer [BUFSIZ];
406         guint8 *ptr, *oldptr;
407         guint32 i, size, total_size, max_size;
408         gint32 last_il_offset = 0, last_native_offset = 0;
409         const unsigned char* il_code;
410         guint32 il_codesize;
411
412         if (!in_the_mono_debugger)
413                 return NULL;
414
415         mono_debugger_lock ();
416
417         header = mono_method_get_header (method);
418
419         max_size = 28 * jit->num_line_numbers;
420         if (max_size > BUFSIZ)
421                 ptr = oldptr = g_malloc (max_size);
422         else
423                 ptr = oldptr = buffer;
424
425         write_leb128 (jit->prologue_end, ptr, &ptr);
426         write_leb128 (jit->epilogue_begin, ptr, &ptr);
427         write_leb128 (jit->num_line_numbers, ptr, &ptr);
428         for (i = 0; i < jit->num_line_numbers; i++) {
429                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
430
431                 write_sleb128 (lne->il_offset - last_il_offset, ptr, &ptr);
432                 write_sleb128 (lne->native_offset - last_native_offset, ptr, &ptr);
433
434                 last_il_offset = lne->il_offset;
435                 last_native_offset = lne->native_offset;
436         }
437
438         write_leb128 (method->wrapper_type, ptr, &ptr);
439
440         size = ptr - oldptr;
441         g_assert (size < max_size);
442         total_size = size + sizeof (MonoDebugWrapperData);
443
444         if (total_size + 9 >= DATA_TABLE_CHUNK_SIZE) {
445                 // FIXME: Maybe we should print a warning here.
446                 //        This should only happen for very big methods, for instance
447                 //        with more than 40.000 line numbers and more than 5.000
448                 //        local variables.
449                 mono_debugger_unlock ();
450                 return NULL;
451         }
452
453         wrapper = (MonoDebugWrapperData *) allocate_data_item (MONO_DEBUG_DATA_ITEM_WRAPPER, total_size);
454
455         wrapper->method = method;
456         wrapper->size = total_size;
457         wrapper->code_start = jit->code_start;
458         wrapper->code_size = jit->code_size;
459         wrapper->name = mono_method_full_name (method, TRUE);
460
461         il_code = mono_method_header_get_code (header, &il_codesize, NULL);
462         wrapper->cil_code = mono_disasm_code (
463                 NULL, method, il_code, il_code + il_codesize);
464
465         memcpy (&wrapper->data, oldptr, size);
466
467         if (max_size > BUFSIZ)
468                 g_free (oldptr);
469
470         mono_debugger_unlock ();
471
472         return wrapper;
473 }
474
475 /*
476  * This is called by the JIT to tell the debugging code about a newly
477  * compiled method.
478  */
479 MonoDebugMethodAddress *
480 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
481 {
482         MonoDebugMethodAddress *address;
483         guint8 buffer [BUFSIZ];
484         guint8 *ptr, *oldptr;
485         guint32 i, size, total_size, max_size;
486         gint32 last_il_offset = 0, last_native_offset = 0;
487         MonoDebugHandle *handle;
488         MonoDebugMethodInfo *minfo;
489         MethodHashEntry *hash;
490
491         if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
492             (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
493             (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
494             (method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
495             (method->wrapper_type != MONO_WRAPPER_NONE)) {
496                 mono_debug_add_wrapper (method, jit);
497                 return NULL;
498         }
499
500         mono_debugger_lock ();
501
502         handle = _mono_debug_get_image (method->klass->image);
503         if (!handle || !handle->symfile || !handle->symfile->offset_table) {
504                 mono_debug_add_wrapper (method, jit);
505                 mono_debugger_unlock ();
506                 return NULL;
507         }
508
509         minfo = _mono_debug_lookup_method (method);
510         if (!minfo) {
511                 mono_debugger_unlock ();
512                 return NULL;
513         }
514
515         max_size = 24 + 8 * jit->num_line_numbers + 16 * minfo->num_lexical_blocks + 20 * (1 + jit->num_params + jit->num_locals);
516         if (max_size > BUFSIZ)
517                 ptr = oldptr = g_malloc (max_size);
518         else
519                 ptr = oldptr = buffer;
520
521         write_leb128 (jit->prologue_end, ptr, &ptr);
522         write_leb128 (jit->epilogue_begin, ptr, &ptr);
523
524         write_leb128 (jit->num_line_numbers, ptr, &ptr);
525         for (i = 0; i < jit->num_line_numbers; i++) {
526                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
527
528                 write_sleb128 (lne->il_offset - last_il_offset, ptr, &ptr);
529                 write_sleb128 (lne->native_offset - last_native_offset, ptr, &ptr);
530
531                 last_il_offset = lne->il_offset;
532                 last_native_offset = lne->native_offset;
533         }
534
535         jit->num_lexical_blocks = minfo->num_lexical_blocks;
536         jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks);
537         for (i = 0; i < jit->num_lexical_blocks; i ++) {
538                 MonoDebugLexicalBlockEntry *jit_lbe = &jit->lexical_blocks [i];
539                 MonoSymbolFileLexicalBlockEntry *minfo_lbe = &minfo->lexical_blocks [i];
540                 jit_lbe->il_start_offset = read32 (&(minfo_lbe->_start_offset));
541                 jit_lbe->native_start_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_start_offset);
542
543                 jit_lbe->il_end_offset = read32 (&(minfo_lbe->_end_offset));
544                 jit_lbe->native_end_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_end_offset);
545         }
546
547         last_il_offset = 0;
548         last_native_offset = 0;
549         write_leb128 (jit->num_lexical_blocks, ptr, &ptr);
550         for (i = 0; i < jit->num_lexical_blocks; i++) {
551                 MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i];
552
553                 write_sleb128 (lbe->il_start_offset - last_il_offset, ptr, &ptr);
554                 write_sleb128 (lbe->native_start_offset - last_native_offset, ptr, &ptr);
555
556                 last_il_offset = lbe->il_start_offset;
557                 last_native_offset = lbe->native_start_offset;
558
559                 write_sleb128 (lbe->il_end_offset - last_il_offset, ptr, &ptr);
560                 write_sleb128 (lbe->native_end_offset - last_native_offset, ptr, &ptr);
561
562                 last_il_offset = lbe->il_end_offset;
563                 last_native_offset = lbe->native_end_offset;
564         }
565
566         *ptr++ = jit->this_var ? 1 : 0;
567         if (jit->this_var)
568                 write_variable (jit->this_var, ptr, &ptr);
569
570         write_leb128 (jit->num_params, ptr, &ptr);
571         for (i = 0; i < jit->num_params; i++)
572                 write_variable (&jit->params [i], ptr, &ptr);
573
574         write_leb128 (jit->num_locals, ptr, &ptr);
575         for (i = 0; i < jit->num_locals; i++)
576                 write_variable (&jit->locals [i], ptr, &ptr);
577
578         size = ptr - oldptr;
579         g_assert (size < max_size);
580         total_size = size + sizeof (MonoDebugMethodAddress);
581
582         if (total_size + 9 >= DATA_TABLE_CHUNK_SIZE) {
583                 // FIXME: Maybe we should print a warning here.
584                 //        This should only happen for very big methods, for instance
585                 //        with more than 40.000 line numbers and more than 5.000
586                 //        local variables.
587                 mono_debugger_unlock ();
588                 return NULL;
589         }
590
591         address = (MonoDebugMethodAddress *) allocate_data_item (MONO_DEBUG_DATA_ITEM_METHOD, total_size);
592
593         address->size = total_size;
594         address->symfile_id = handle->index;
595         address->domain_id = mono_domain_get_id (domain);
596         address->method_id = minfo->index;
597         address->code_start = jit->code_start;
598         address->code_size = jit->code_size;
599         address->wrapper_addr = jit->wrapper_addr;
600
601         memcpy (&address->data, oldptr, size);
602
603         if (max_size > BUFSIZ)
604                 g_free (oldptr);
605
606         hash = g_new0 (MethodHashEntry, 1);
607         hash->symfile_id = address->symfile_id;
608         hash->domain_id = address->domain_id;
609         hash->method_id = address->method_id;
610
611         g_hash_table_insert (method_hash, hash, address);
612
613         mono_debugger_unlock ();
614
615         return address;
616 }
617
618 static inline guint32
619 read_leb128 (guint8 *ptr, guint8 **rptr)
620 {
621         guint32 result = 0, shift = 0;
622
623         while (TRUE) {
624                 guint8 byte = *ptr++;
625
626                 result |= (byte & 0x7f) << shift;
627                 if ((byte & 0x80) == 0)
628                         break;
629                 shift += 7;
630         }
631
632         *rptr = ptr;
633         return result;
634 }
635
636 static inline gint32
637 read_sleb128 (guint8 *ptr, guint8 **rptr)
638 {
639         gint32 result = 0;
640         guint32 shift = 0;
641
642         while (TRUE) {
643                 guint8 byte = *ptr++;
644
645                 result |= (byte & 0x7f) << shift;
646                 shift += 7;
647
648                 if (byte & 0x80)
649                         continue;
650
651                 if ((shift < 32) && (byte & 0x40))
652                         result |= - (1 << shift);
653                 break;
654         }
655
656         *rptr = ptr;
657         return result;
658 }
659
660 static void
661 read_variable (MonoDebugVarInfo *var, guint8 *ptr, guint8 **rptr)
662 {
663         var->index = read_leb128 (ptr, &ptr);
664         var->offset = read_sleb128 (ptr, &ptr);
665         var->size = read_leb128 (ptr, &ptr);
666         var->begin_scope = read_leb128 (ptr, &ptr);
667         var->end_scope = read_leb128 (ptr, &ptr);
668         *rptr = ptr;
669 }
670
671 MonoDebugMethodJitInfo *
672 mono_debug_read_method (MonoDebugMethodAddress *address)
673 {
674         MonoDebugMethodJitInfo *jit;
675         guint32 i, il_offset = 0, native_offset = 0;
676         guint8 *ptr;
677
678         if (address->jit)
679                 return address->jit;
680
681         jit = address->jit = g_new0 (MonoDebugMethodJitInfo, 1);
682         jit->code_start = address->code_start;
683         jit->code_size = address->code_size;
684         jit->wrapper_addr = address->wrapper_addr;
685
686         ptr = (guint8 *) &address->data;
687
688         jit->prologue_end = read_leb128 (ptr, &ptr);
689         jit->epilogue_begin = read_leb128 (ptr, &ptr);
690
691         jit->num_line_numbers = read_leb128 (ptr, &ptr);
692         jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);
693         for (i = 0; i < jit->num_line_numbers; i++) {
694                 MonoDebugLineNumberEntry *lne = &jit->line_numbers [i];
695
696                 il_offset += read_sleb128 (ptr, &ptr);
697                 native_offset += read_sleb128 (ptr, &ptr);
698
699                 lne->il_offset = il_offset;
700                 lne->native_offset = native_offset;
701         }
702
703         il_offset = 0;
704         native_offset = 0;
705         jit->num_lexical_blocks = read_leb128 (ptr, &ptr);
706         jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks);
707         for (i = 0; i < jit->num_lexical_blocks; i ++) {
708                 MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i];
709
710                 il_offset += read_sleb128 (ptr, &ptr);
711                 native_offset += read_sleb128 (ptr, &ptr);
712
713                 lbe->il_start_offset = il_offset;
714                 lbe->native_start_offset = native_offset;
715
716                 il_offset += read_sleb128 (ptr, &ptr);
717                 native_offset += read_sleb128 (ptr, &ptr);
718
719                 lbe->il_end_offset = il_offset;
720                 lbe->native_end_offset = native_offset;
721         }
722
723         if (*ptr++) {
724                 jit->this_var = g_new0 (MonoDebugVarInfo, 1);
725                 read_variable (jit->this_var, ptr, &ptr);
726         }
727
728         jit->num_params = read_leb128 (ptr, &ptr);
729         jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
730         for (i = 0; i < jit->num_params; i++)
731                 read_variable (&jit->params [i], ptr, &ptr);
732
733         jit->num_locals = read_leb128 (ptr, &ptr);
734         jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
735         for (i = 0; i < jit->num_locals; i++)
736                 read_variable (&jit->locals [i], ptr, &ptr);
737
738         return jit;
739 }
740
741 void
742 mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
743 {
744         if (jit->address)
745                 jit->address->jit = NULL;
746
747         g_free (jit->line_numbers);
748         g_free (jit->this_var);
749         g_free (jit->params);
750         g_free (jit->locals);
751         g_free (jit);
752 }
753
754 /*
755  * This is called via the `mono_debugger_class_init_func' from mono_class_init() each time
756  * a new class is initialized.
757  */
758 static void
759 mono_debug_start_add_type (MonoClass *klass)
760 {
761         MonoDebugHandle *handle;
762
763         handle = _mono_debug_get_image (klass->image);
764         if (!handle)
765                 return;
766 }
767
768 static void
769 mono_debug_add_type (MonoClass *klass)
770 {
771         MonoDebugHandle *handle;
772         MonoDebugClassEntry *entry;
773         guint8 buffer [BUFSIZ];
774         guint8 *ptr, *oldptr;
775         guint32 size, total_size, max_size;
776         int base_offset = 0;
777
778         handle = _mono_debug_get_image (klass->image);
779         if (!handle)
780                 return;
781
782         if (klass->generic_class || klass->rank ||
783             (klass->byval_arg.type == MONO_TYPE_VAR) || (klass->byval_arg.type == MONO_TYPE_MVAR))
784                 return;
785
786         max_size = 12 + sizeof (gpointer);
787         if (max_size > BUFSIZ)
788                 ptr = oldptr = g_malloc (max_size);
789         else
790                 ptr = oldptr = buffer;
791
792         if (klass->valuetype)
793                 base_offset = - (int)(sizeof (MonoObject));
794
795         write_leb128 (klass->type_token, ptr, &ptr);
796         write_leb128 (klass->instance_size + base_offset, ptr, &ptr);
797         WRITE_UNALIGNED (gpointer, ptr, klass);
798         ptr += sizeof (gpointer);
799
800         size = ptr - oldptr;
801         g_assert (size < max_size);
802         total_size = size + sizeof (MonoDebugClassEntry);
803
804         g_assert (total_size + 9 < DATA_TABLE_CHUNK_SIZE);
805
806         entry = (MonoDebugClassEntry *) allocate_data_item (MONO_DEBUG_DATA_ITEM_CLASS, total_size);
807
808         entry->size = total_size;
809         entry->symfile_id = handle->index;
810
811         memcpy (&entry->data, oldptr, size);
812
813         if (max_size > BUFSIZ)
814                 g_free (oldptr);
815
816         mono_debugger_add_type (handle, klass);
817 }
818
819 static MonoDebugMethodJitInfo *
820 find_method (MonoDebugMethodInfo *minfo, MonoDomain *domain)
821 {
822         MethodHashEntry lookup;
823         MonoDebugMethodAddress *address;
824
825         lookup.symfile_id = minfo->handle->index;
826         lookup.domain_id = mono_domain_get_id (domain);
827         lookup.method_id = minfo->index;
828
829         address = g_hash_table_lookup (method_hash, &lookup);
830         if (!address)
831                 return NULL;
832
833         return mono_debug_read_method (address);
834 }
835
836 MonoDebugMethodJitInfo *
837 mono_debug_find_method (MonoDebugMethodInfo *minfo, MonoDomain *domain)
838 {
839         MonoDebugMethodJitInfo *res;
840         mono_debugger_lock ();
841         res = find_method (minfo, domain);
842         mono_debugger_unlock ();
843         return res;
844 }
845
846 static gint32
847 il_offset_from_address (MonoDebugMethodInfo *minfo, MonoDomain *domain, guint32 native_offset)
848 {
849         MonoDebugMethodJitInfo *jit;
850         int i;
851
852         jit = find_method (minfo, domain);
853         if (!jit || !jit->line_numbers)
854                 return -1;
855
856         for (i = jit->num_line_numbers - 1; i >= 0; i--) {
857                 MonoDebugLineNumberEntry lne = jit->line_numbers [i];
858
859                 if (lne.native_offset <= native_offset)
860                         return lne.il_offset;
861         }
862
863         return -1;
864 }
865
866 /**
867  * mono_debug_lookup_source_location:
868  * @address: Native offset within the @method's machine code.
869  *
870  * Lookup the source code corresponding to the machine instruction located at
871  * native offset @address within @method.
872  *
873  * The returned `MonoDebugSourceLocation' contains both file / line number
874  * information and the corresponding IL offset.  It must be freed by
875  * mono_debug_free_source_location().
876  */
877 MonoDebugSourceLocation *
878 mono_debug_lookup_source_location (MonoMethod *method, guint32 address, MonoDomain *domain)
879 {
880         MonoDebugMethodInfo *minfo;
881         MonoDebugSourceLocation *location;
882         gint32 offset;
883
884         if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
885                 return NULL;
886
887         mono_debugger_lock ();
888         minfo = _mono_debug_lookup_method (method);
889         if (!minfo || !minfo->handle || !minfo->handle->symfile || !minfo->handle->symfile->offset_table) {
890                 mono_debugger_unlock ();
891                 return NULL;
892         }
893
894         offset = il_offset_from_address (minfo, domain, address);
895         if (offset < 0) {
896                 mono_debugger_unlock ();
897                 return NULL;
898         }
899
900         location = mono_debug_symfile_lookup_location (minfo, offset);
901         mono_debugger_unlock ();
902         return location;
903 }
904
905 /**
906  * mono_debug_free_source_location:
907  * @location: A `MonoDebugSourceLocation'.
908  *
909  * Frees the @location.
910  */
911 void
912 mono_debug_free_source_location (MonoDebugSourceLocation *location)
913 {
914         if (location) {
915                 g_free (location->source_file);
916                 g_free (location);
917         }
918 }
919
920 /**
921  * mono_debug_print_stack_frame:
922  * @native_offset: Native offset within the @method's machine code.
923  *
924  * Conventient wrapper around mono_debug_lookup_source_location() which can be
925  * used if you only want to use the location to print a stack frame.
926  */
927 gchar *
928 mono_debug_print_stack_frame (MonoMethod *method, guint32 native_offset, MonoDomain *domain)
929 {
930         MonoDebugSourceLocation *location;
931         gchar *fname, *ptr, *res;
932
933         fname = mono_method_full_name (method, TRUE);
934         for (ptr = fname; *ptr; ptr++) {
935                 if (*ptr == ':') *ptr = '.';
936         }
937
938         location = mono_debug_lookup_source_location (method, native_offset, domain);
939
940         if (!location) {
941                 res = g_strdup_printf ("at %s <0x%05x>", fname, native_offset);
942                 g_free (fname);
943                 return res;
944         }
945
946         res = g_strdup_printf ("at %s [0x%05x] in %s:%d", fname, location->il_offset,
947                                location->source_file, location->row);
948
949         g_free (fname);
950         mono_debug_free_source_location (location);
951         return res;
952 }
953