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