Beispiel #1
0
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 ();
}
Beispiel #2
0
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 ();
	}
Beispiel #3
0
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;
}
Beispiel #4
0
/**
 * 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;
}