static CRITICAL_SECTION aot_mutex;
-static guint32 mono_aot_verbose = 0;
+static guint32 mono_aot_verbose = 1;
/*
* Disabling this will make a copy of the loaded code and use the copy instead
memcpy (code, minfo->info->code_start, minfo->info->code_size);
if (mono_aot_verbose > 1)
- printf ("REUSE METHOD: %s %p - %p.\n", mono_method_full_name (method, TRUE), code, (char*)code + code_len);
+ printf ("REUSE METHOD: %s %p - %p.\n", mono_method_full_name (method, TRUE), code, (char*)code + minfo->info->code_size);
/* Do this outside the lock to avoid deadlocks */
LeaveCriticalSection (&aot_mutex);
gpointer *table;
int pages;
int i, err;
- guint32 last_offset;
+ guint32 last_offset, buf_len;
if (aot_module->opts & MONO_OPT_SHARED)
mp = mono_mempool_new ();
patch_info = ji;
}
+ info = (gpointer)((guint8*)info + 4);
+ buf_len = *(guint32*)info;
+ info = (gpointer)((guint8*)info + 4);
+ mono_debug_add_aot_method (domain, method, code, (guint8*)info, buf_len);
+
if (use_loaded_code) {
/* disable write protection */
#ifndef PLATFORM_WIN32
/* NULL terminated array */
fprintf (tmpfp, "\t.long 0\n");
+ {
+ guint8 *buf;
+ guint32 buf_len;
+
+ mono_debug_serialize_debug_info (cfg, &buf, &buf_len);
+
+ fprintf (tmpfp, "\t.long %d\n", buf_len);
+
+ for (i = 0; i < buf_len; ++i)
+ fprintf (tmpfp, ".byte %d\n", (unsigned int) buf [i]);
+
+ if (buf_len > 0)
+ g_free (buf);
+ }
+
/* fixme: save the rest of the required infos */
g_free (mname);
record_line_number (info->jit, address, offset);
}
+static inline void
+encode_value (guint32 value, char *buf, char **endbuf)
+{
+ char *p = buf;
+
+ //printf ("ENCODE: %d 0x%x.\n", value, value);
+
+ /*
+ * Same encoding as the one used in the metadata, extended to handle values
+ * greater than 0x1fffffff.
+ */
+ if (value <= 127)
+ *p++ = value;
+ else if (value <= 16384) {
+ p [0] = 0x80 | (value >> 8);
+ p [1] = value & 0xff;
+ p += 2;
+ } else if (value <= 0x1fffffff) {
+ p [0] = (value >> 24) | 0xc0;
+ p [1] = (value >> 16) & 0xff;
+ p [2] = (value >> 8) & 0xff;
+ p [3] = value & 0xff;
+ p += 4;
+ }
+ else {
+ p [0] = 0xff;
+ p [1] = (value >> 24) & 0xff;
+ p [2] = (value >> 16) & 0xff;
+ p [3] = (value >> 8) & 0xff;
+ p [4] = value & 0xff;
+ p += 5;
+ }
+ if (endbuf)
+ *endbuf = p;
+}
+
+static inline guint32
+decode_value (char *_ptr, char **rptr)
+{
+ unsigned char *ptr = (unsigned char *) _ptr;
+ unsigned char b = *ptr;
+ guint32 len;
+
+ if ((b & 0x80) == 0){
+ len = b;
+ ++ptr;
+ } else if ((b & 0x40) == 0){
+ len = ((b & 0x3f) << 8 | ptr [1]);
+ ptr += 2;
+ } else if (b != 0xff) {
+ len = ((b & 0x1f) << 24) |
+ (ptr [1] << 16) |
+ (ptr [2] << 8) |
+ ptr [3];
+ ptr += 4;
+ }
+ else {
+ len = (ptr [0] << 24) | (ptr [1] << 16) | (ptr [2] << 8) | ptr [3];
+ ptr += 5;
+ }
+ if (rptr)
+ *rptr = ptr;
+
+ //printf ("DECODE: %d.\n", len);
+ return len;
+}
+
+static void
+serialize_variable (MonoDebugVarInfo *var, char *p, char **endbuf)
+{
+ guint32 flags = var->index & MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
+
+ switch (flags) {
+ case MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER:
+ encode_value (var->index, p, &p);
+ break;
+ case MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET:
+ encode_value (var->index, p, &p);
+ encode_value (var->offset, p, &p);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ *endbuf = p;
+}
+
+void
+mono_debug_serialize_debug_info (MonoCompile *cfg,
+ guint8 **out_buf, guint32 *buf_len)
+{
+ MiniDebugMethodInfo *info;
+ MonoDebugMethodJitInfo *jit;
+ guint32 size, prev_offset, prev_native_offset;
+ char *buf;
+ char *p;
+ int i;
+
+ info = (MiniDebugMethodInfo *) cfg->debug_info;
+ if (!info || !info->jit) {
+ *buf_len = 0;
+ return;
+ }
+ jit = info->jit;
+
+ size = ((jit->num_params + jit->num_locals + 1) * 10) + (jit->line_numbers->len * 10) + 64;
+ p = buf = g_malloc (size);
+ encode_value (jit->epilogue_begin, p, &p);
+ encode_value (jit->prologue_end, p, &p);
+ encode_value (jit->code_size, p, &p);
+
+ for (i = 0; i < jit->num_params; ++i)
+ serialize_variable (&jit->params [i], p, &p);
+
+ if (cfg->method->signature->hasthis)
+ serialize_variable (jit->this_var, p, &p);
+
+ for (i = 0; i < jit->num_locals; i++)
+ serialize_variable (&jit->locals [i], p, &p);
+
+ encode_value (jit->line_numbers->len, p, &p);
+
+ prev_offset = 0;
+ prev_native_offset = 0;
+ for (i = 0; i < jit->line_numbers->len; ++i) {
+ MonoDebugLineNumberEntry *lne = &g_array_index (jit->line_numbers,
+ MonoDebugLineNumberEntry,
+ i);
+ encode_value (lne->offset - prev_offset, p, &p);
+ encode_value (lne->address - prev_native_offset, p, &p);
+ prev_offset = lne->offset;
+ prev_native_offset = lne->address;
+ }
+
+ g_assert (p - buf < size);
+
+ *out_buf = buf;
+ *buf_len = p - buf;
+}
+
+static void
+deserialize_variable (MonoDebugVarInfo *var, char *p, char **endbuf)
+{
+ guint32 flags;
+
+ var->index = decode_value (p, &p);
+
+ flags = var->index & MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
+
+ switch (flags) {
+ case MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER:
+ break;
+ case MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET:
+ var->offset = decode_value (p, &p);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ *endbuf = p;
+}
+
+static MonoDebugMethodJitInfo *
+deserialize_debug_info (MonoMethod *method,
+ guint8 *code_start,
+ guint8 *buf, guint32 buf_len)
+{
+ MonoMethodHeader *header;
+ MonoDebugMethodJitInfo *jit;
+ guint32 offset, native_offset, prev_offset, prev_native_offset, len;
+ char *p;
+ int i;
+
+ g_assert (((MonoMethodNormal*)method)->header);
+ header = ((MonoMethodNormal*)method)->header;
+
+ jit = g_new0 (MonoDebugMethodJitInfo, 1);
+ jit->code_start = code_start;
+ jit->line_numbers = g_array_new (FALSE, TRUE, sizeof (MonoDebugLineNumberEntry));
+ jit->num_locals = header->num_locals;
+ jit->locals = g_new0 (MonoDebugVarInfo, jit->num_locals);
+ jit->num_params = method->signature->param_count;
+ jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);
+
+ p = buf;
+ jit->epilogue_begin = decode_value (p, &p);
+ jit->prologue_end = decode_value (p, &p);
+ jit->code_size = decode_value (p, &p);
+
+ for (i = 0; i < jit->num_params; ++i)
+ deserialize_variable (&jit->params [i], p, &p);
+
+ if (method->signature->hasthis) {
+ jit->this_var = g_new0 (MonoDebugVarInfo, 1);
+ deserialize_variable (jit->this_var, p, &p);
+ }
+
+ for (i = 0; i < jit->num_locals; i++)
+ deserialize_variable (&jit->locals [i], p, &p);
+
+ len = decode_value (p, &p);
+
+ prev_offset = 0;
+ prev_native_offset = 0;
+ for (i = 0; i < len; ++i) {
+ offset = prev_offset + decode_value (p, &p);
+ native_offset = prev_native_offset + decode_value (p, &p);
+ record_line_number (jit, native_offset, offset);
+ prev_offset = offset;
+ prev_native_offset = native_offset;
+ }
+
+ return jit;
+}
+
+void
+mono_debug_add_aot_method (MonoDomain *domain,
+ MonoMethod *method, guint8 *code_start,
+ guint8 *debug_info, guint32 debug_info_len)
+{
+ MonoDebugMethodJitInfo *jit;
+
+ if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
+ return;
+
+ if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
+ (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
+ (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
+ (method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
+ (method->wrapper_type != MONO_WRAPPER_NONE))
+ return;
+
+ if (debug_info_len == 0)
+ return;
+
+ jit = deserialize_debug_info (method, code_start,
+ debug_info,
+ debug_info_len);
+
+ mono_debug_add_method (method, jit, domain);
+}
+
MonoDomain *
mono_init_debugger (const char *file, const char *opt_flags)
{