5 #include <mono/metadata/metadata.h>
6 #include <mono/metadata/rawbuffer.h>
7 #include <mono/metadata/tokentype.h>
8 #include <mono/metadata/appdomain.h>
9 #include <mono/metadata/exception.h>
10 #include <mono/metadata/debug-mono-symfile.h>
17 load_symfile (MonoSymbolFile *symfile)
19 MonoSymbolFileMethodEntry *me, *me_end;
20 const char *ptr, *start, *end;
24 ptr = start = symfile->raw_contents;
26 magic = *((guint64 *) ptr)++;
27 if (magic != MONO_SYMBOL_FILE_MAGIC) {
28 g_warning ("Symbol file %s has is not a mono symbol file", symfile->file_name);
32 version = *((guint32 *) ptr)++;
33 if (version != MONO_SYMBOL_FILE_VERSION) {
34 g_warning ("Symbol file %s has incorrect line number table version "
35 "(expected %d, got %ld)", symfile->file_name,
36 MONO_SYMBOL_FILE_VERSION, version);
40 symfile->offset_table = (MonoSymbolFileOffsetTable *) ptr;
47 symfile->method_table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
48 NULL, (GDestroyNotify) g_free);
50 ptr = symfile->raw_contents + symfile->offset_table->method_table_offset;
51 end = ptr + symfile->offset_table->method_table_size;
53 me = (MonoSymbolFileMethodEntry *) ptr;
54 me_end = ((MonoSymbolFileMethodEntry *) end);
56 for (; me < me_end; me++) {
57 MonoMethod *method = mono_get_method (symfile->image, me->token, NULL);
62 g_hash_table_insert (symfile->method_table, method, me);
69 mono_debug_open_mono_symbol_file (MonoImage *image, const char *filename, gboolean emit_warnings)
71 MonoSymbolFile *symfile;
76 fd = open (filename, O_RDONLY);
79 g_warning ("Can't open symbol file: %s", filename);
83 file_size = lseek (fd, 0, SEEK_END);
84 lseek (fd, 0, SEEK_SET);
86 if (file_size == (off_t) -1) {
88 g_warning ("Can't get size of symbol file: %s", filename);
92 ptr = mono_raw_buffer_load (fd, TRUE, FALSE, 0, file_size);
95 g_warning ("Can't read symbol file: %s", filename);
99 symfile = g_new0 (MonoSymbolFile, 1);
101 symfile->file_name = g_strdup (filename);
102 symfile->image = image;
103 symfile->raw_contents = ptr;
104 symfile->raw_contents_size = file_size;
106 if (!load_symfile (symfile)) {
107 mono_debug_close_mono_symbol_file (symfile);
115 mono_debug_close_mono_symbol_file (MonoSymbolFile *symfile)
120 if (symfile->raw_contents)
121 mono_raw_buffer_free (symfile->raw_contents);
125 g_free (symfile->file_name);
130 mono_debug_find_source_location (MonoSymbolFile *symfile, MonoMethod *method, guint32 offset,
131 guint32 *line_number)
133 MonoSymbolFileMethodEntry *me;
134 MonoSymbolFileLineNumberEntry *lne, *lne_end;
135 const char *ptr, *end, *source_file;
137 if (!symfile->method_table)
140 me = g_hash_table_lookup (symfile->method_table, method);
144 source_file = symfile->raw_contents + me->source_file_offset;
146 ptr = symfile->raw_contents + me->line_number_table_offset;
147 end = symfile->raw_contents + symfile->offset_table->line_number_table_offset +
148 symfile->offset_table->line_number_table_size;
150 lne = (MonoSymbolFileLineNumberEntry *) ptr;
151 lne_end = ((MonoSymbolFileLineNumberEntry *) end);
153 for (; (lne < lne_end) && lne->row; lne++) {
154 if (lne->offset < offset)
158 *line_number = lne->row;
159 return g_strdup (source_file);
161 return g_strdup_printf ("%s:%d", source_file, lne->row);
169 MonoSymbolFile *symfile;
170 MonoDebugGetMethodFunc get_method_func;
175 update_method_func (gpointer key, gpointer value, gpointer user_data)
177 struct MyData *mydata = (struct MyData *) user_data;
178 MonoSymbolFileMethodEntry *me = (MonoSymbolFileMethodEntry *) value;
179 MonoMethod *method = (MonoMethod *) key;
180 MonoSymbolFileLineNumberEntry *lne, *lne_end;
181 const char *ptr, *end;
184 MonoDebugMethodInfo *minfo = mydata->get_method_func
185 (mydata->symfile, method, mydata->user_data);
190 me->start_address = minfo->code_start;
191 me->end_address = minfo->code_start + minfo->code_size;
193 ptr = mydata->symfile->raw_contents + me->line_number_table_offset;
194 end = mydata->symfile->raw_contents + mydata->symfile->offset_table->line_number_table_offset +
195 mydata->symfile->offset_table->line_number_table_size;
197 lne = (MonoSymbolFileLineNumberEntry *) ptr;
198 lne_end = ((MonoSymbolFileLineNumberEntry *) end);
200 for (; (lne < lne_end) && lne->row; lne++) {
208 } else if (lne->offset == 0) {
209 lne->address = minfo->prologue_end;
213 address = minfo->code_size;
215 for (i = 0; i < minfo->num_il_offsets; i++) {
216 MonoDebugILOffsetInfo *il = &minfo->il_offsets [i];
218 if (il->offset >= lne->offset) {
219 address = il->address;
224 lne->address = address;
230 mono_debug_update_mono_symbol_file (MonoSymbolFile *symfile,
231 MonoDebugGetMethodFunc get_method_func,
234 if (symfile->method_table) {
235 struct MyData mydata = { symfile, get_method_func, user_data };
236 g_hash_table_foreach (symfile->method_table, update_method_func, &mydata);
239 mono_raw_buffer_update (symfile->raw_contents, symfile->raw_contents_size);