void mono_debug_remove_method (MonoMethod *method, MonoDomain *domain) { MonoDebugDataTable *table; MonoDebugMethodAddress *address; if (!mono_debug_initialized) return; g_assert (method_is_dynamic (method)); mono_debugger_lock (); table = lookup_data_table (domain); address = (MonoDebugMethodAddress *)g_hash_table_lookup (table->method_address_hash, method); if (address) g_free (address); g_hash_table_remove (table->method_address_hash, method); mono_debugger_unlock (); }
static const unsigned char* dis_one (GString *str, MonoDisHelper *dh, MonoMethod *method, const unsigned char *ip, const unsigned char *end) { MonoMethodHeader *header = mono_method_get_header (method); const MonoOpcode *opcode; guint32 label, token; gint32 sval; int i; char *tmp; const unsigned char* il_code = mono_method_header_get_code (header, NULL, NULL); label = ip - il_code; if (dh->indenter) { tmp = dh->indenter (dh, method, label); g_string_append (str, tmp); g_free (tmp); } if (dh->label_format) g_string_append_printf (str, dh->label_format, label); i = mono_opcode_value (&ip, end); ip++; opcode = &mono_opcodes [i]; g_string_append_printf (str, "%-10s", mono_opcode_name (i)); switch (opcode->argument) { case MonoInlineNone: break; case MonoInlineType: case MonoInlineField: case MonoInlineMethod: case MonoInlineTok: case MonoInlineSig: token = read32 (ip); if (dh->tokener) { tmp = dh->tokener (dh, method, token); g_string_append (str, tmp); g_free (tmp); } else { g_string_append_printf (str, "0x%08x", token); } ip += 4; break; case MonoInlineString: { const char *blob; char *s; size_t len2; char *blob2 = NULL; if (!image_is_dynamic (method->klass->image) && !method_is_dynamic (method)) { token = read32 (ip); blob = mono_metadata_user_string (method->klass->image, mono_metadata_token_index (token)); len2 = mono_metadata_decode_blob_size (blob, &blob); len2 >>= 1; #ifdef NO_UNALIGNED_ACCESS /* The blob might not be 2 byte aligned */ blob2 = g_malloc ((len2 * 2) + 1); memcpy (blob2, blob, len2 * 2); #else blob2 = (char*)blob; #endif #if G_BYTE_ORDER != G_LITTLE_ENDIAN { guint16 *buf = g_new (guint16, len2 + 1); int i; for (i = 0; i < len2; ++i) buf [i] = GUINT16_FROM_LE (((guint16*)blob2) [i]); s = g_utf16_to_utf8 (buf, len2, NULL, NULL, NULL); g_free (buf); } #else s = g_utf16_to_utf8 ((gunichar2*)blob2, len2, NULL, NULL, NULL); #endif g_string_append_printf (str, "\"%s\"", s); g_free (s); if (blob != blob2) g_free (blob2); } ip += 4; break; } case MonoInlineVar: g_string_append_printf (str, "%d", read16 (ip)); ip += 2; break; case MonoShortInlineVar: g_string_append_printf (str, "%d", (*ip)); ip ++; break; case MonoInlineBrTarget: sval = read32 (ip); ip += 4; if (dh->label_target) g_string_append_printf (str, dh->label_target, ip + sval - il_code); else g_string_append_printf (str, "%d", sval); break; case MonoShortInlineBrTarget: sval = *(const signed char*)ip; ip ++; if (dh->label_target) g_string_append_printf (str, dh->label_target, ip + sval - il_code); else g_string_append_printf (str, "%d", sval); break; case MonoInlineSwitch: { const unsigned char *end; sval = read32 (ip); ip += 4; end = ip + sval * 4; g_string_append_c (str, '('); for (i = 0; i < sval; ++i) { if (i > 0) g_string_append (str, ", "); label = read32 (ip); if (dh->label_target) g_string_append_printf (str, dh->label_target, end + label - il_code); else g_string_append_printf (str, "%d", label); ip += 4; } g_string_append_c (str, ')'); break; } case MonoInlineR: { double r; readr8 (ip, &r); g_string_append_printf (str, "%g", r); ip += 8; break; } case MonoShortInlineR: { float r; readr4 (ip, &r); g_string_append_printf (str, "%g", r); ip += 4; break; } case MonoInlineI: g_string_append_printf (str, "%d", (gint32)read32 (ip)); ip += 4; break; case MonoShortInlineI: g_string_append_printf (str, "%d", *(const signed char*)ip); ip ++; break; case MonoInlineI8: ip += 8; break; default: g_assert_not_reached (); }
static MonoMethod * create_method_ilgen (MonoMethodBuilder *mb, MonoMethodSignature *signature, int max_stack) { MonoMethodHeader *header; MonoMethodWrapper *mw; MonoImage *image; MonoMethod *method; GList *l; int i; g_assert (mb != NULL); image = m_class_get_image (mb->method->klass); if (mb->dynamic) { method = mb->method; mw = (MonoMethodWrapper*)method; method->name = mb->name; method->dynamic = TRUE; mw->header = header = (MonoMethodHeader *) g_malloc0 (MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *)); header->code = mb->code; for (i = 0, l = mb->locals_list; l; l = l->next, i++) { header->locals [i] = (MonoType*)l->data; } } else { /* Realloc the method info into a mempool */ method = (MonoMethod *)mono_image_alloc0 (image, sizeof (MonoMethodWrapper)); memcpy (method, mb->method, sizeof (MonoMethodWrapper)); mw = (MonoMethodWrapper*) method; if (mb->no_dup_name) method->name = mb->name; else method->name = mono_image_strdup (image, mb->name); mw->header = header = (MonoMethodHeader *) mono_image_alloc0 (image, MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *)); header->code = (const unsigned char *)mono_image_alloc (image, mb->pos); memcpy ((char*)header->code, mb->code, mb->pos); for (i = 0, l = mb->locals_list; l; l = l->next, i++) { header->locals [i] = (MonoType*)l->data; } } /* Free the locals list so mono_mb_free () doesn't free the types twice */ g_list_free (mb->locals_list); mb->locals_list = NULL; method->signature = signature; if (!signature->hasthis) method->flags |= METHOD_ATTRIBUTE_STATIC; if (max_stack < 8) max_stack = 8; header->max_stack = max_stack; header->code_size = mb->pos; header->num_locals = mb->locals; header->init_locals = mb->init_locals; header->volatile_args = mb->volatile_args; header->volatile_locals = mb->volatile_locals; mb->volatile_args = NULL; mb->volatile_locals = NULL; header->num_clauses = mb->num_clauses; header->clauses = mb->clauses; method->skip_visibility = mb->skip_visibility; i = g_list_length ((GList *)mw->method_data); if (i) { GList *tmp; void **data; l = g_list_reverse ((GList *)mw->method_data); if (method_is_dynamic (method)) data = (void **)g_malloc (sizeof (gpointer) * (i + 1)); else data = (void **)mono_image_alloc (image, sizeof (gpointer) * (i + 1)); /* store the size in the first element */ data [0] = GUINT_TO_POINTER (i); i = 1; for (tmp = l; tmp; tmp = tmp->next) { data [i++] = tmp->data; } g_list_free (l); mw->method_data = data; } /*{ static int total_code = 0; static int total_alloc = 0; total_code += mb->pos; total_alloc += mb->code_size; g_print ("code size: %d of %d (allocated: %d)\n", mb->pos, total_code, total_alloc); }*/ #ifdef DEBUG_RUNTIME_CODE printf ("RUNTIME CODE FOR %s\n", mono_method_full_name (method, TRUE)); printf ("%s\n", mono_disasm_code (&marshal_dh, method, mb->code, mb->code + mb->pos)); #endif if (mb->param_names) { char **param_names = (char **)mono_image_alloc0 (image, signature->param_count * sizeof (gpointer)); for (i = 0; i < signature->param_count; ++i) param_names [i] = mono_image_strdup (image, mb->param_names [i]); mono_image_lock (image); if (!image->wrapper_param_names) image->wrapper_param_names = g_hash_table_new (NULL, NULL); g_hash_table_insert (image->wrapper_param_names, method, param_names); mono_image_unlock (image); } return method; }
/** * mono_debug_add_method: */ MonoDebugMethodAddress * mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain) { MonoDebugDataTable *table; MonoDebugMethodAddress *address; guint8 buffer [BUFSIZ]; guint8 *ptr, *oldptr; guint32 i, size, total_size, max_size; mono_debugger_lock (); table = lookup_data_table (domain); max_size = (5 * 5) + 1 + (10 * jit->num_line_numbers) + (25 + sizeof (gpointer)) * (1 + jit->num_params + jit->num_locals); if (max_size > BUFSIZ) ptr = oldptr = (guint8 *)g_malloc (max_size); else ptr = oldptr = buffer; write_leb128 (jit->prologue_end, ptr, &ptr); write_leb128 (jit->epilogue_begin, ptr, &ptr); write_leb128 (jit->num_line_numbers, ptr, &ptr); for (i = 0; i < jit->num_line_numbers; i++) { MonoDebugLineNumberEntry *lne = &jit->line_numbers [i]; write_sleb128 (lne->il_offset, ptr, &ptr); write_sleb128 (lne->native_offset, ptr, &ptr); } write_leb128 (jit->has_var_info, ptr, &ptr); if (jit->has_var_info) { *ptr++ = jit->this_var ? 1 : 0; if (jit->this_var) write_variable (jit->this_var, ptr, &ptr); write_leb128 (jit->num_params, ptr, &ptr); for (i = 0; i < jit->num_params; i++) write_variable (&jit->params [i], ptr, &ptr); write_leb128 (jit->num_locals, ptr, &ptr); for (i = 0; i < jit->num_locals; i++) write_variable (&jit->locals [i], ptr, &ptr); *ptr++ = jit->gsharedvt_info_var ? 1 : 0; if (jit->gsharedvt_info_var) { write_variable (jit->gsharedvt_info_var, ptr, &ptr); write_variable (jit->gsharedvt_locals_var, ptr, &ptr); } } size = ptr - oldptr; g_assert (size < max_size); total_size = size + sizeof (MonoDebugMethodAddress); if (method_is_dynamic (method)) { address = (MonoDebugMethodAddress *)g_malloc0 (total_size); } else { address = (MonoDebugMethodAddress *)mono_mempool_alloc (table->mp, total_size); } address->code_start = jit->code_start; address->code_size = jit->code_size; memcpy (&address->data, oldptr, size); if (max_size > BUFSIZ) g_free (oldptr); g_hash_table_insert (table->method_address_hash, method, address); mono_debugger_unlock (); return address; }