Mon Mar 25 13:04:56 CET 2002 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / debug-symfile.c
index 74c3193e5437b96d9dde8b81fee11b4e80a59cb5..8556d970a717c98e1b3df751db1dc74fbad57871 100644 (file)
@@ -1,10 +1,12 @@
+#include <config.h>
 #include <stdlib.h>
 #include <string.h>
 #include <mono/metadata/metadata.h>
 #include <mono/metadata/rawbuffer.h>
+#include <mono/metadata/appdomain.h>
+#include <mono/metadata/exception.h>
 #include <mono/metadata/debug-symfile.h>
 
-#include <elf.h>
 #include <fcntl.h>
 #include <unistd.h>
 
 #define MRT_il_offset                  0x02
 #define MRT_method_start_address       0x03
 #define MRT_method_end_address         0x04
+#define MRT_local_variable             0x05
+#define MRT_method_parameter           0x06
+#define MRT_type_sizeof                        0x07
+#define MRT_type_field_offset          0x08
 
 #define MRS_debug_info                 0x01
 #define MRS_debug_abbrev               0x02
@@ -152,6 +158,7 @@ mono_debug_open_symbol_file (MonoImage *image, const char *filename, gboolean em
        symfile->file_name = g_strdup (filename);
        symfile->image = image;
        symfile->raw_contents = ptr;
+       symfile->raw_contents_size = file_size;
 
        if (!get_sections (symfile, emit_warnings)) {
                mono_debug_close_symbol_file (symfile);
@@ -250,7 +257,9 @@ mono_debug_update_symbol_file (MonoDebugSymbolFile *symfile,
                                continue;
                        }
 
+#if 0
                        g_message ("Start of `%s' relocated to %p", minfo->method->name, minfo->code_start);
+#endif
 
                        * (void **) base_ptr = minfo->code_start;
 
@@ -296,18 +305,177 @@ mono_debug_update_symbol_file (MonoDebugSymbolFile *symfile,
                                }
                        }
 
+#if 0
                        g_message ("Relocating IL offset %d in `%s' to %d (%p)",
                                   original, minfo->method->name, address,
                                   minfo->code_start + address);
+#endif
 
                        * (void **) base_ptr = minfo->code_start + address;
 
                        break;
                }
+               case MRT_local_variable: {
+                       guint32 token = *((guint32 *) tmp_ptr)++;
+                       guint32 original = *((guint32 *) tmp_ptr)++;
+                       MonoDebugMethodInfo *minfo;
+                       gint32 address;
+
+                       minfo = method_info_func (symfile, token, user_data);
+
+                       if (!minfo) {
+                               * (void **) base_ptr = 0;
+                               continue;
+                       }
+
+                       if (original > minfo->num_locals) {
+                               g_warning ("Symbol file %s contains relocation entry for non-existing "
+                                          "local variable %d, but method %s only has %d local variables.",
+                                          symfile->file_name, original, minfo->method->name,
+                                          minfo->num_locals);
+                               continue;
+                       }
+
+                       address = minfo->local_offsets [original];
+
+#if 0
+                       g_message ("Relocating local variable %d (%s) to stack offset %d",
+                                  original, minfo->method->name, address);
+#endif
+
+                       * (gint32 *) base_ptr = address;
+
+                       break;
+               }
+               case MRT_method_parameter: {
+                       guint32 token = *((guint32 *) tmp_ptr)++;
+                       guint32 original = *((guint32 *) tmp_ptr)++;
+                       MonoDebugMethodInfo *minfo;
+                       gint32 address;
+
+                       minfo = method_info_func (symfile, token, user_data);
+
+                       if (!minfo) {
+                               * (void **) base_ptr = 0;
+                               continue;
+                       }
+
+                       if (original > minfo->num_params) {
+                               g_warning ("Symbol file %s contains relocation entry for non-existing "
+                                          "parameter %d, but method %s only has %d parameters.",
+                                          symfile->file_name, original, minfo->method->name,
+                                          minfo->num_params);
+                               continue;
+                       }
+
+                       address = minfo->param_offsets [original];
+
+#if 0
+                       g_message ("Relocating parameter %d (%s) to stack offset %d",
+                                  original, minfo->method->name, address);
+#endif
+
+                       * (gint32 *) base_ptr = address;
+
+                       break;
+               }
+               case MRT_type_sizeof: {
+                       guint32 token = *((guint32 *) tmp_ptr)++;
+                       MonoClass *klass = mono_class_get (symfile->image, token);
+
+                       g_message ("Setting size of type %u to %d", token, klass->instance_size);
+
+                       * (gint8 *) base_ptr = klass->instance_size;
+
+                       break;
+               }
+               case MRT_type_field_offset: {
+                       guint32 token = *((guint32 *) tmp_ptr)++;
+                       guint32 original = *((guint32 *) tmp_ptr)++;
+                       MonoClass *klass = mono_class_get (symfile->image, token);
+                       guint32 offset;
+
+                       if (original > klass->field.count) {
+                               g_warning ("Symbol file %s contains invalid field offset entry.",
+                                          symfile->file_name);
+                               continue;
+                       }
+
+                       offset = klass->fields [original].offset;
+                       if (klass->byval_arg.type == MONO_TYPE_VALUETYPE)
+                               offset -= sizeof (MonoObject);
+
+                       g_message ("Setting field %d of type %u to offset %d", original,
+                                  token, offset);
+
+                       * (guint32 *) base_ptr = offset;
+
+                       break;
+               }
                default:
                        g_warning ("Symbol file %s contains unknown relocation entry %d",
                                   symfile->file_name, type);
                        break;
                }
        }
+
+       mono_raw_buffer_update (symfile->raw_contents, symfile->raw_contents_size);
+}
+
+MonoReflectionType *
+ves_icall_Debugger_MonoSymbolWriter_get_local_type_from_sig (MonoReflectionAssembly *assembly,
+                                                            MonoArray *signature)
+{
+       MonoDomain *domain; 
+       MonoImage *image;
+       MonoClass *klass;
+       MonoType *type;
+       const char *ptr;
+       int len = 0;
+
+       MONO_CHECK_ARG_NULL (assembly);
+       MONO_CHECK_ARG_NULL (signature);
+
+       domain = mono_domain_get();
+       image = assembly->assembly->image;
+
+       ptr = mono_array_addr (signature, char, 0);
+       g_assert (*ptr++ == 0x07);
+       len = mono_metadata_decode_value (ptr, &ptr);
+       g_assert (len == 1);
+
+       type = mono_metadata_parse_type (image, MONO_PARSE_LOCAL, 0, ptr, &ptr);
+
+       klass = mono_class_from_mono_type (type);
+
+       mono_class_init (klass);
+
+       return mono_type_get_object (domain, type);
+}
+
+MonoReflectionMethod *
+ves_icall_Debugger_MonoSymbolWriter_method_from_token (MonoReflectionAssembly *assembly, guint32 token)
+{
+       MonoDomain *domain; 
+       MonoImage *image;
+       MonoMethod *method;
+
+       MONO_CHECK_ARG_NULL (assembly);
+
+       domain = mono_domain_get();
+       image = assembly->assembly->image;
+
+       method = mono_get_method (image, token, NULL);
+
+       return mono_method_get_object (domain, method);
+}
+
+guint32
+ves_icall_Debugger_DwarfFileWriter_get_type_token (MonoReflectionType *type)
+{
+    MonoClass *klass = mono_class_from_mono_type (type->type);
+
+    mono_class_init (klass);
+
+    return klass->type_token;
 }