Beispiel #1
0
void CPipeServer::DisassembleMethod()
{
	void *method=(void *)ReadQword();
	void *methodheader=mono_method_get_header(method);
	UINT32 codesize, maxstack;
	void *ilcode=mono_method_header_get_code(methodheader, &codesize, &maxstack);
	char *disassembly=mono_disasm_code(NULL, method, ilcode, (void *)((UINT_PTR)ilcode+codesize));

	WriteWord(strlen(disassembly));
	Write(disassembly, strlen(disassembly));
	g_free(disassembly);
}
Beispiel #2
0
MonoDebugMethodAddress *
mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain)
{
    MonoMethod *declaring;
    MonoDebugDataTable *table;
    MonoDebugMethodHeader *header;
    MonoDebugMethodAddress *address;
    MonoDebugMethodInfo *minfo;
    MonoDebugHandle *handle;
    guint8 buffer [BUFSIZ];
    guint8 *ptr, *oldptr;
    guint32 i, size, total_size, max_size;
    gboolean is_wrapper = FALSE;

    mono_debugger_lock ();

    table = lookup_data_table (domain);

    handle = _mono_debug_get_image (method->klass->image);
    minfo = _mono_debug_lookup_method (method);

    if (!minfo || (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)) {
        is_wrapper = TRUE;
    }

    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 = 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);
    }

    *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);

    size = ptr - oldptr;
    g_assert (size < max_size);
    total_size = size + sizeof (MonoDebugMethodAddress);

    address = (MonoDebugMethodAddress *) allocate_data_item (
                  table, MONO_DEBUG_DATA_ITEM_METHOD, total_size);

    address->header.size = total_size;
    address->header.symfile_id = handle ? handle->index : 0;
    address->header.domain_id = mono_domain_get_id (domain);
    address->header.method_id = is_wrapper ? 0 : minfo->index;
    address->header.method = method;

    address->code_start = jit->code_start;
    address->code_size = jit->code_size;

    memcpy (&address->data, oldptr, size);
    if (max_size > BUFSIZ)
        g_free (oldptr);

    declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
    header = g_hash_table_lookup (table->method_hash, declaring);

    if (!header) {
        header = &address->header;
        g_hash_table_insert (table->method_hash, declaring, header);

        if (is_wrapper) {
            const unsigned char* il_code;
            MonoMethodHeader *mheader;
            MonoDebugWrapperData *wrapper;
            guint32 il_codesize;

            mheader = mono_method_get_header (declaring);
            il_code = mono_method_header_get_code (mheader, &il_codesize, NULL);

            header->wrapper_data = wrapper = g_new0 (MonoDebugWrapperData, 1);

            wrapper->wrapper_type = method->wrapper_type;
            wrapper->method_name = mono_method_full_name (declaring, TRUE);
            wrapper->cil_code = mono_disasm_code (
                                    NULL, declaring, il_code, il_code + il_codesize);
        }
    } else {
        address->header.wrapper_data = header->wrapper_data;
        header->address_list = g_slist_prepend (header->address_list, address);
    }

    g_hash_table_insert (table->method_address_hash, method, address);

    write_data_item (table, (guint8 *) address);

    mono_debugger_unlock ();
    return address;
}
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
/*反汇编method的IL*/
static char const *disil_method (MonoMethod *method) {
    MonoMethodHeader *header = mono_method_get_header (method);
    uint32_t len = 0;
    uint8_t const *code = mono_method_header_get_code (header, &len, 0);
    return mono_disasm_code (0, method, code, code + len);
}