#include <errno.h>
#include <string.h>
#include <signal.h>
+#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
+#endif
#include <sys/stat.h>
#include <mono/metadata/metadata.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/debug-mono-symfile.h>
+#include <mono/metadata/mono-debug-debugger.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/class-internals.h>
#include <fcntl.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#define RANGE_TABLE_CHUNK_SIZE 256
#define CLASS_TABLE_CHUNK_SIZE 256
guint64 magic;
long version;
- ptr = start = symfile->raw_contents;
+ ptr = start = (const char*)symfile->raw_contents;
if (!ptr)
return FALSE;
version = read32(ptr);
ptr += sizeof(guint32);
- if (version != MONO_SYMBOL_FILE_VERSION) {
+ if ((version != MONO_SYMBOL_FILE_VERSION) && (version != MONO_SYMBOL_FILE_COMPATIBILITY_VERSION)) {
if (!in_the_debugger)
g_warning ("Symbol file %s has incorrect version "
"(expected %d, got %ld)", symfile->filename,
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;
}
+ symfile->version = version;
+
symfile->offset_table = (MonoSymbolFileOffsetTable *) ptr;
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;
mono_debugger_lock ();
symfile = g_new0 (MonoSymbolFile, 1);
- 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 (raw_contents != NULL) {
+ unsigned char *p;
+ symfile->raw_contents_size = size;
+ symfile->raw_contents = p = g_malloc (size);
+ memcpy (p, 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"))) {
+ 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)) {
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 ();
}
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;
+ const unsigned char *ptr;
+ 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)) +
(read32(&(minfo->entry->_source_index)) - 1) * sizeof (MonoSymbolFileSourceEntry);
MonoSymbolFileSourceEntry *se = (MonoSymbolFileSourceEntry *) (symfile->raw_contents + offset);
- source_file = read_string (symfile->raw_contents + read32(&(se->_name_offset)));
+ source_file = read_string ((const char*)symfile->raw_contents + read32(&(se->_name_offset)));
}
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 = count - 1; i >= 0; i--, lne--) {
+ MonoDebugSourceLocation *location;
- for (i = 0; i < read32(&(minfo->entry->_num_line_numbers)); i++, lne++) {
- if (read32(&(lne->_offset)) < offset)
+ 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 ();
for (i = jit->num_line_numbers - 1; i >= 0; i--) {
MonoDebugLineNumberEntry lne = jit->line_numbers [i];
+ if (lne.il_offset < 0)
+ continue;
if (lne.il_offset <= il_offset)
return lne.native_offset;
}
- return -1;
+ return 0;
}
static int
}
MonoDebugMethodInfo *
-mono_debug_find_method (MonoDebugHandle *handle, MonoMethod *method)
+mono_debug_symfile_lookup_method (MonoDebugHandle *handle, MonoMethod *method)
{
MonoSymbolFileMethodEntry *me;
MonoSymbolFileMethodIndexEntry *first_ie, *ie;
minfo->num_il_offsets = read32(&(me->_num_line_numbers));
minfo->il_offsets = (MonoSymbolFileLineNumberEntry *)
(symfile->raw_contents + read32(&(me->_line_number_table_offset)));
- minfo->num_lexical_blocks = read32(&(me->_num_lexical_blocks));
- minfo->lexical_blocks = (MonoSymbolFileLexicalBlockEntry *)
- (symfile->raw_contents + read32(&(me->_lexical_block_table_offset)));
+
minfo->entry = me;
g_hash_table_insert (symfile->method_hash, method, minfo);