2006-12-11 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mono / metadata / debug-mono-symfile.c
index 9178be1f48f520b44fb3b8d49f6ad7fd4eebe57d..6d703a57168f698a19bdb0e5905a209b27d18764 100644 (file)
@@ -88,6 +88,8 @@ load_symfile (MonoDebugHandle *handle, MonoSymbolFile *symfile, gboolean in_the_
                if (!in_the_debugger)
                        g_warning ("Symbol file %s doesn't match image %s", symfile->filename,
                                   handle->image_file);
+               if (guid)
+                       g_free (guid);
                return FALSE;
        }
 
@@ -96,11 +98,13 @@ load_symfile (MonoDebugHandle *handle, MonoSymbolFile *symfile, gboolean in_the_
        symfile->method_hash = g_hash_table_new_full (
                g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) free_method_info);
 
+       g_free (guid);
        return TRUE;
 }
 
 MonoSymbolFile *
-mono_debug_open_mono_symbol_file (MonoDebugHandle *handle, gboolean in_the_debugger)
+mono_debug_open_mono_symbols (MonoDebugHandle *handle, const guint8 *raw_contents,
+                             int size, gboolean in_the_debugger)
 {
        MonoSymbolFile *symfile;
        FILE* f;
@@ -108,21 +112,28 @@ mono_debug_open_mono_symbol_file (MonoDebugHandle *handle, gboolean in_the_debug
        mono_debugger_lock ();
        symfile = g_new0 (MonoSymbolFile, 1);
 
-       symfile->filename = g_strdup_printf ("%s.mdb", mono_image_get_filename (handle->image));
+       if (raw_contents != NULL) {
+               symfile->raw_contents_size = size;
+               symfile->raw_contents = g_malloc (size);
+               memcpy(symfile->raw_contents, raw_contents, size);
+               symfile->filename = g_strdup_printf ("LoadedFromMemory");
+       } else {
+               symfile->filename = g_strdup_printf ("%s.mdb", mono_image_get_filename (handle->image));
 
-       if ((f = fopen (symfile->filename, "rb")) > 0) {
-               struct stat stat_buf;
+               if ((f = fopen (symfile->filename, "rb"))) {
+                       struct stat stat_buf;
                        
-               if (fstat (fileno (f), &stat_buf) < 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);
+                       if (fstat (fileno (f), &stat_buf) < 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);
+                       }
+
+                       fclose (f);
                }
-               
-               fclose (f);
        }
        
        if (load_symfile (handle, symfile, in_the_debugger)) {
@@ -150,7 +161,9 @@ mono_debug_close_mono_symbol_file (MonoSymbolFile *symfile)
 
        if (symfile->raw_contents)
                mono_raw_buffer_free ((gpointer) symfile->raw_contents);
-       
+
+       if (symfile->filename)
+               g_free (symfile->filename);
        g_free (symfile);
        mono_debugger_unlock ();
 }
@@ -182,27 +195,29 @@ read_string (const char *ptr)
        return g_filename_from_utf8 (ptr, len, NULL, NULL, NULL);
 }
 
-gchar *
-mono_debug_find_source_location (MonoSymbolFile *symfile, MonoMethod *method, guint32 offset,
-                                guint32 *line_number)
+/**
+ * mono_debug_symfile_lookup_location:
+ * @minfo: A `MonoDebugMethodInfo' which can be retrieved by
+ *         mono_debug_lookup_method().
+ * @offset: IL offset within the corresponding method's CIL code.
+ *
+ * This function is similar to mono_debug_lookup_location(), but we
+ * already looked up the method and also already did the
+ * `native address -> IL offset' mapping.
+ */
+MonoDebugSourceLocation *
+mono_debug_symfile_lookup_location (MonoDebugMethodInfo *minfo, guint32 offset)
 {
        MonoSymbolFileLineNumberEntry *lne;
-       MonoDebugMethodInfo *minfo;
+       MonoSymbolFile *symfile;
        gchar *source_file = NULL;
        const char *ptr;
-       int i;
+       int count, i;
 
-       mono_debugger_lock ();
-       if (!symfile->method_hash) {
-               mono_debugger_unlock ();
+       if ((symfile = minfo->handle->symfile) == NULL)
                return NULL;
-       }
 
-       minfo = g_hash_table_lookup (symfile->method_hash, method);
-       if (!minfo) {
-               mono_debugger_unlock ();
-               return NULL;
-       }
+       mono_debugger_lock ();
 
        if (read32(&(minfo->entry->_source_index))) {
                int offset = read32(&(symfile->offset_table->_source_table_offset)) +
@@ -214,29 +229,22 @@ mono_debug_find_source_location (MonoSymbolFile *symfile, MonoMethod *method, gu
 
        ptr = symfile->raw_contents + read32(&(minfo->entry->_line_number_table_offset));
 
-       lne = (MonoSymbolFileLineNumberEntry *) ptr;
+       count = read32(&(minfo->entry->_num_line_numbers));
+       lne = ((MonoSymbolFileLineNumberEntry *) ptr) + count - 1;
 
-       for (i = 0; i < read32(&(minfo->entry->_num_line_numbers)); i++, lne++) {
-               if (read32(&(lne->_offset)) < offset)
+       for (i = count - 1; i >= 0; i--, lne--) {
+               MonoDebugSourceLocation *location;
+
+               if (read32(&(lne->_offset)) > offset)
                        continue;
 
-               if (line_number) {
-                       *line_number = read32(&(lne->_row));
-                       mono_debugger_unlock ();
-                       if (source_file)
-                               return source_file;
-                       else
-                               return NULL;
-               } else if (source_file) {
-                       gchar *retval = g_strdup_printf ("%s:%d", source_file, read32(&(lne->_row)));
-                       g_free (source_file);
-                       mono_debugger_unlock ();
-                       return retval;
-               } else {
-                       gchar* retval = g_strdup_printf ("%d", read32(&(lne->_row)));
-                       mono_debugger_unlock ();
-                       return retval;
-               }
+               location = g_new0 (MonoDebugSourceLocation, 1);
+               location->source_file = source_file;
+               location->row = read32(&(lne->_row));
+               location->il_offset = read32(&(lne->_offset));
+
+               mono_debugger_unlock ();
+               return location;
        }
 
        mono_debugger_unlock ();
@@ -271,7 +279,7 @@ compare_method (const void *key, const void *object)
 }
 
 MonoDebugMethodInfo *
-mono_debug_find_method (MonoDebugHandle *handle, MonoMethod *method)
+mono_debug_symfile_lookup_method (MonoDebugHandle *handle, MonoMethod *method)
 {
        MonoSymbolFileMethodEntry *me;
        MonoSymbolFileMethodIndexEntry *first_ie, *ie;