X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fdebug-mono-symfile.c;h=686468c30adee2528e823014f89ea41e017538b3;hb=0be4b9d8f775612c61487226ba0f1a721b9779fa;hp=db9235cf2a11be11e72b1a18453813dd3d973b0b;hpb=6104bf41a4b2212faa76cd17fea208cf27920059;p=mono.git diff --git a/mono/metadata/debug-mono-symfile.c b/mono/metadata/debug-mono-symfile.c index db9235cf2a1..686468c30ad 100644 --- a/mono/metadata/debug-mono-symfile.c +++ b/mono/metadata/debug-mono-symfile.c @@ -1,3 +1,12 @@ +/* + * debug-mono-symfile.c: + * + * Author: + * Mono Project (http://www.mono-project.com) + * + * Copyright (C) 2005-2008 Novell, Inc. (http://www.novell.com) + */ + #include #include #include @@ -10,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -21,6 +29,7 @@ #include #include #include +#include #include #ifdef HAVE_UNISTD_H @@ -38,23 +47,6 @@ free_method_info (MonoDebugMethodInfo *minfo) g_free (minfo); } -static gchar * -get_class_name (MonoClass *klass) -{ - MonoClass *nested_in = mono_class_get_nesting_type (klass); - const char *name_space; - if (nested_in) { - gchar *parent_name = get_class_name (nested_in); - gchar *name = g_strdup_printf ("%s.%s", parent_name, mono_class_get_name (klass)); - g_free (parent_name); - return name; - } - - name_space = mono_class_get_namespace (klass); - return g_strdup_printf ("%s%s%s", name_space, - name_space [0] ? "." : "", mono_class_get_name (klass)); -} - static int load_symfile (MonoDebugHandle *handle, MonoSymbolFile *symfile, gboolean in_the_debugger) { @@ -80,6 +72,11 @@ load_symfile (MonoDebugHandle *handle, MonoSymbolFile *symfile, gboolean in_the_ minor = read32(ptr); ptr += sizeof(guint32); + /* + * 50.0 is the frozen version for Mono 2.0. + * + * Nobody except me (Martin) is allowed to check the minor version. + */ if (major != MONO_SYMBOL_FILE_MAJOR_VERSION) { if (!in_the_debugger) g_warning ("Symbol file %s has incorrect version (expected %d.%d, got %d)", @@ -88,15 +85,6 @@ load_symfile (MonoDebugHandle *handle, MonoSymbolFile *symfile, gboolean in_the_ return FALSE; } - if (minor != MONO_SYMBOL_FILE_MINOR_VERSION) { - if (!in_the_debugger) - g_warning ("Symbol file %s has incorrect version " - "(expected %d.%d, got %d.%d)", symfile->filename, - MONO_SYMBOL_FILE_MAJOR_VERSION, MONO_SYMBOL_FILE_MINOR_VERSION, - major, minor); - return FALSE; - } - guid = mono_guid_to_string ((const guint8 *) ptr); ptr += 16; @@ -126,7 +114,6 @@ mono_debug_open_mono_symbols (MonoDebugHandle *handle, const guint8 *raw_content int size, gboolean in_the_debugger) { MonoSymbolFile *symfile; - FILE* f; mono_debugger_lock (); symfile = g_new0 (MonoSymbolFile, 1); @@ -138,21 +125,20 @@ mono_debug_open_mono_symbols (MonoDebugHandle *handle, const guint8 *raw_content memcpy (p, raw_contents, size); symfile->filename = g_strdup_printf ("LoadedFromMemory"); } else { + MonoFileMap *f; symfile->filename = g_strdup_printf ("%s.mdb", mono_image_get_filename (handle->image)); - if ((f = fopen (symfile->filename, "rb"))) { - struct stat stat_buf; - - if (fstat (fileno (f), &stat_buf) < 0) { + if ((f = mono_file_map_open (symfile->filename))) { + symfile->raw_contents_size = mono_file_map_size (f); + if (symfile->raw_contents_size == 0) { if (!in_the_debugger) g_warning ("stat of %s failed: %s", symfile->filename, g_strerror (errno)); } else { - symfile->raw_contents_size = stat_buf.st_size; - symfile->raw_contents = mono_raw_buffer_load (fileno (f), FALSE, 0, stat_buf.st_size); + symfile->raw_contents = mono_file_map (symfile->raw_contents_size, MONO_MMAP_READ|MONO_MMAP_PRIVATE, mono_file_map_fd (f), 0, &symfile->raw_contents_handle); } - fclose (f); + mono_file_map_close (f); } } @@ -180,7 +166,7 @@ mono_debug_close_mono_symbol_file (MonoSymbolFile *symfile) g_hash_table_destroy (symfile->method_hash); if (symfile->raw_contents) - mono_raw_buffer_free ((gpointer) symfile->raw_contents); + mono_file_unmap ((gpointer) symfile->raw_contents, symfile->raw_contents_handle); if (symfile->filename) g_free (symfile->filename); @@ -245,6 +231,15 @@ check_line (StatementMachine *stm, int offset, MonoDebugSourceLocation **locatio source_file = read_string (stm->symfile->raw_contents + read32(&(se->_data_offset))); } + if (stm->last_line == 0) { + /* + * The IL offset is less than the first IL offset which has a corresponding + * source line. + */ + *location = NULL; + return TRUE; + } + *location = g_new0 (MonoDebugSourceLocation, 1); (*location)->source_file = source_file; (*location)->row = stm->last_line; @@ -282,9 +277,9 @@ mono_debug_symfile_lookup_location (MonoDebugMethodInfo *minfo, guint32 offset) if ((symfile = minfo->handle->symfile) == NULL) return NULL; - stm.line_base = symfile->offset_table->_line_number_table_line_base; - stm.line_range = symfile->offset_table->_line_number_table_line_range; - stm.opcode_base = (guint8) symfile->offset_table->_line_number_table_opcode_base; + stm.line_base = read32 (&symfile->offset_table->_line_number_table_line_base); + stm.line_range = read32 (&symfile->offset_table->_line_number_table_line_range); + stm.opcode_base = (guint8) read32 (&symfile->offset_table->_line_number_table_opcode_base); stm.max_address_incr = (255 - stm.opcode_base) / stm.line_range; mono_debugger_lock (); @@ -293,8 +288,10 @@ mono_debug_symfile_lookup_location (MonoDebugMethodInfo *minfo, guint32 offset) stm.symfile = symfile; stm.offset = stm.last_offset = 0; - stm.file = stm.last_file = 1; - stm.line = stm.last_line = 1; + stm.last_file = 0; + stm.last_line = 0; + stm.file = 1; + stm.line = 1; while (TRUE) { guint8 opcode = *ptr++; @@ -402,6 +399,13 @@ mono_debug_symfile_lookup_method (MonoDebugHandle *handle, MonoMethod *method) return NULL; mono_debugger_lock (); + + minfo = g_hash_table_lookup (symfile->method_hash, method); + if (minfo) { + mono_debugger_unlock (); + return minfo; + } + first_ie = (MonoSymbolFileMethodEntry *) (symfile->raw_contents + read32(&(symfile->offset_table->_method_table_offset))); @@ -427,3 +431,51 @@ mono_debug_symfile_lookup_method (MonoDebugHandle *handle, MonoMethod *method) mono_debugger_unlock (); return minfo; } + +/* + * mono_debug_symfile_lookup_locals: + * + * Return information about the local variables of MINFO from the symbol file. + * NAMES and INDEXES are set to g_malloc-ed arrays containing the local names and + * their IL indexes. + * Returns: the number of elements placed into the arrays, or -1 if there is no + * local variable info. + */ +int +mono_debug_symfile_lookup_locals (MonoDebugMethodInfo *minfo, char ***names, int **indexes) +{ + MonoSymbolFile *symfile = minfo->handle->symfile; + const guint8 *p; + int i, len, compile_unit_index, locals_offset, num_locals, index, block_index; + + *names = NULL; + *indexes = NULL; + + if (!symfile) + return -1; + + p = symfile->raw_contents + minfo->data_offset; + + compile_unit_index = read_leb128 (p, &p); + locals_offset = read_leb128 (p, &p); + + p = symfile->raw_contents + locals_offset; + num_locals = read_leb128 (p, &p); + + *names = g_new0 (char*, num_locals); + *indexes = g_new0 (int, num_locals); + + for (i = 0; i < num_locals; ++i) { + index = read_leb128 (p, &p); + (*indexes) [i] = index; + len = read_leb128 (p, &p); + (*names) [i] = g_malloc (len + 1); + memcpy ((*names) [i], p, len); + (*names) [i][len] = '\0'; + p += len; + block_index = read_leb128 (p, &p); + } + + return num_locals; +} +