Exemple #1
0
static int
dump_verify_info (MonoImage *image, int flags)
{
	GSList *errors, *tmp;
	int count = 0, verifiable = 0;
	const char* desc [] = {
		"Ok", "Error", "Warning", NULL, "CLS", NULL, NULL, NULL, "Not Verifiable"
	};

	if (verify_code) { /* verify code */
		int i;
		MonoTableInfo *m = &image->tables [MONO_TABLE_METHOD];

		for (i = 0; i < m->rows; ++i) {
			MonoMethod *method;
			MonoError error;

			method = mono_get_method_checked (image, MONO_TOKEN_METHOD_DEF | (i+1), NULL, NULL, &error);
			if (!method) {
				g_print ("Warning: Cannot lookup method with token 0x%08x due to %s\n", i + 1, mono_error_get_message (&error));
				mono_error_cleanup (&error);
				continue;
			}
			errors = mono_method_verify (method, flags);
			if (errors) {
				MonoClass *klass = mono_method_get_class (method);
				char *name = mono_type_full_name (&klass->byval_arg);
				if (mono_method_signature (method) == NULL) {
					g_print ("In method: %s::%s(ERROR)\n", name, mono_method_get_name (method));
				} else {
					char *sig;
					sig = mono_signature_get_desc (mono_method_signature (method), FALSE);	
					g_print ("In method: %s::%s(%s)\n", name, mono_method_get_name (method), sig);
					g_free (sig);
				}
				g_free (name);
			}

			for (tmp = errors; tmp; tmp = tmp->next) {
				MonoVerifyInfo *info = (MonoVerifyInfo *)tmp->data;
				g_print ("%s: %s\n", desc [info->status], info->message);
				if (info->status == MONO_VERIFY_ERROR) {
					count++;
					verifiable = 3;
				}
				if(info->status == MONO_VERIFY_NOT_VERIFIABLE) {
					if (verifiable < 2)
						verifiable = 2;	
				}
			}
			mono_free_verify_list (errors);
		}
	}

	if (count)
		g_print ("Error count: %d\n", count);
	return verifiable;
}
Exemple #2
0
/*监控需要hook的函数*/
static void profile_jit_result (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result) {
    if (result == MONO_PROFILE_FAILED) return;
    if (mono_method_get_token (method) == 0) return;                /*一般是动态生成的marshall*/
    uint32_t iflags;
    int flag = mono_method_get_flags (method, &iflags);
    if (iflags != 0) return;                                        /*iflags非0 一般是一些native和特殊的method实现*/
    if (mono_jit_info_get_code_size (jinfo) < 4) return;            /*代码段太小, 无法hook*/

    void *p = mono_jit_info_get_code_start (jinfo);
    if (p == 0) {
        LOGD ("function code size is null");
        return;
    }

        /*测试jit函数是否是mov r12, sp*/
    if (*(uint32_t*)p != 0xE1A0C00D)
         LOGD ("exception func : %s , %p", mono_method_get_name (method), p);

    /*TODO : 增加可配置的image和函数列表*/
    if (strcmp (get_method_image_name (method), "Assembly-CSharp") != 0) return;
    if (strcmp (mono_method_get_name (method), ".ctor") == 0) return;
    if (strcmp (mono_method_get_name (method), ".cctor") == 0) return;
    if (strcmp (mono_method_get_name (method), "set") == 0) return;
    if (strcmp (mono_method_get_name (method), "get") == 0) return;
    if (strcmp (mono_method_get_name (method), "Update") == 0) return;
    if (strcmp (mono_method_get_name (method), "LateUpdate") == 0) return;
    if (strcmp (mono_method_get_name (method), "OnGUI") == 0) return;

    /*TODO : 需要一个容器来存储还未编译, 但又想hook的函数*/

    bool donthook = false;
    pthread_mutex_lock (&replace_mutex);
    if (replace_method_dict.find (method) != replace_method_dict.end ())
        donthook = true;
    pthread_mutex_unlock (&replace_mutex);
    if (donthook) return;

    char *hook = specific_hook (p, method, (void*)func_trace);
    if (hook == 0) {
        /*将失败的hook也放到一个表里面*/
        LOGD ("hook err : %s", mono_method_get_name (method));
        return;
    }
    pthread_mutex_lock (&hooked_mutex);
    hooked_method_dict[method] = new HookInfo(jinfo, hook);
    pthread_mutex_unlock (&hooked_mutex);
    LOGD ("hook func : %s , %p", mono_method_get_name (method), p);
    return;
}
Exemple #3
0
MonoMethod *CScriptClass::GetMonoMethod(const char *methodName, int numParams)
{
	MonoMethodSignature *pSignature = nullptr;

	void *pIterator = 0;

	MonoClass *pClass = (MonoClass *)m_pObject;
	MonoType *pClassType = mono_class_get_type(pClass);
	MonoMethod *pCurMethod = nullptr;

	while (pClass != nullptr)
	{
		pCurMethod = mono_class_get_methods(pClass, &pIterator);
		if(pCurMethod == nullptr)
		{
			pClass = mono_class_get_parent(pClass);
			if(pClass == mono_get_object_class())
				break;

			pIterator = 0;
			continue;
		}

		pSignature = mono_method_signature(pCurMethod);
		int signatureParamCount = mono_signature_get_param_count(pSignature);

		bool bCorrectName = !strcmp(mono_method_get_name(pCurMethod), methodName);
		if(bCorrectName && signatureParamCount == numParams)
			return pCurMethod;
	}

	return nullptr;
}
Exemple #4
0
/**
 * mono_get_exception_type_initialization:
 * @type_name: the name of the type that failed to initialize.
 * @inner: the inner exception.
 *
 * Returns: a new instance of the System.TypeInitializationException
 */
MonoException *
mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner)
{
	MonoClass *klass;
	gpointer args [2];
	MonoObject *exc;
	MonoMethod *method;
	gpointer iter;

	klass = mono_class_from_name (mono_get_corlib (), "System", "TypeInitializationException");
	g_assert (klass);

	mono_class_init (klass);

	/* TypeInitializationException only has 1 ctor with 2 args */
	iter = NULL;
	while ((method = mono_class_get_methods (klass, &iter))) {
		if (!strcmp (".ctor", mono_method_get_name (method)) && mono_method_signature (method)->param_count == 2)
			break;
		method = NULL;
	}

	g_assert (method);

	args [0] = mono_string_new (mono_domain_get (), type_name);
	args [1] = inner;

	exc = mono_object_new (mono_domain_get (), klass);
	mono_runtime_invoke (method, exc, args, NULL);

	return (MonoException *) exc;
}
Exemple #5
0
MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class) {
	MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, p_class->get_mono_ptr());
	ERR_FAIL_NULL_V(mono_object, NULL);

	// Search constructor that takes a pointer as parameter
	MonoMethod *m;
	void *iter = NULL;
	while ((m = mono_class_get_methods(p_class->get_mono_ptr(), &iter))) {
		if (strcmp(mono_method_get_name(m), ".ctor") == 0) {
			MonoMethodSignature *sig = mono_method_signature(m);
			void *front = NULL;
			if (mono_signature_get_param_count(sig) == 1 &&
					mono_class_from_mono_type(mono_signature_get_params(sig, &front)) == CACHED_CLASS(IntPtr)->get_mono_ptr()) {
				break;
			}
		}
	}

	CRASH_COND(m == NULL);

	Dictionary *new_dict = memnew(Dictionary(p_from));
	void *args[1] = { &new_dict };

	MonoException *exc = NULL;
	GDMonoUtils::runtime_invoke(m, mono_object, args, &exc);
	UNLIKELY_UNHANDLED_EXCEPTION(exc);

	return mono_object;
}
static void
method_jit_result (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result) {
	if (result == MONO_PROFILE_OK) {
		int i;
		MonoDebugSourceLocation *sourceLoc;
		MonoDebugMethodJitInfo *dmji;
		MonoClass *klass = mono_method_get_class (method);
		char *signature = mono_signature_get_desc (mono_method_signature (method), TRUE);
		char *name = g_strdup_printf ("%s(%s)", mono_method_get_name (method), signature);
		char *classname = g_strdup_printf ("%s%s%s", mono_class_get_namespace (klass), mono_class_get_namespace (klass)[0] != 0 ? "::" : "", mono_class_get_name (klass));
		gpointer code_start = mono_jit_info_get_code_start (jinfo);
		int code_size = mono_jit_info_get_code_size (jinfo);
		
		iJIT_Method_Load vtuneMethod;
		memset(&vtuneMethod, 0, sizeof(vtuneMethod));
		vtuneMethod.method_id = iJIT_GetNewMethodID();
		vtuneMethod.method_name = name;
		vtuneMethod.method_load_address = code_start;
		vtuneMethod.method_size = code_size;
		vtuneMethod.class_file_name = classname;

		dmji = mono_debug_find_method (method, mono_domain_get());

		if (dmji != NULL)
		{
			vtuneMethod.line_number_size = dmji->num_line_numbers;
			vtuneMethod.line_number_table = (vtuneMethod.line_number_size != 0) ?
				(LineNumberInfo*)malloc(sizeof(LineNumberInfo) * vtuneMethod.line_number_size) : NULL;

			for (i = 0; i < dmji->num_line_numbers; ++i)
			{
				sourceLoc = mono_debug_lookup_source_location (method, dmji->line_numbers[i].native_offset, mono_domain_get());
				if (sourceLoc == NULL)
				{
					g_free (vtuneMethod.line_number_table);
					vtuneMethod.line_number_table = NULL;
					vtuneMethod.line_number_size = 0;
					break;
				}
				if (i == 0)
					vtuneMethod.source_file_name = strdup(sourceLoc->source_file);
				vtuneMethod.line_number_table[i].Offset = dmji->line_numbers[i].native_offset;
				vtuneMethod.line_number_table[i].LineNumber = sourceLoc->row;
				mono_debug_free_source_location (sourceLoc);
			}
			mono_debug_free_method_jit_info (dmji);
		}

		iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &vtuneMethod);

		if (vtuneMethod.source_file_name != NULL)
			g_free (vtuneMethod.source_file_name);
		if (vtuneMethod.line_number_table != NULL)
			g_free (vtuneMethod.line_number_table);
	
		g_free (signature);
		g_free (name);
		g_free (classname);
	}
}
Exemple #7
0
void CPipeServer::GetMethodName()
{
	void *method=(void *)ReadQword();
	char *methodname=mono_method_get_name(method);

	WriteWord(strlen(methodname));
	Write(methodname, strlen(methodname));	
}
Exemple #8
0
GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method) {

	MonoMethodSignature *sig = mono_method_signature(p_raw_method);

	int params_count = mono_signature_get_param_count(sig);
	StringName method_name = mono_method_get_name(p_raw_method);

	return get_method(p_raw_method, method_name, params_count);
}
Exemple #9
0
const Vector<GDMonoMethod *> &GDMonoClass::get_all_methods() {

	if (!method_list_fetched) {
		void *iter = NULL;
		MonoMethod *raw_method = NULL;
		while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != NULL) {
			method_list.push_back(memnew(GDMonoMethod(mono_method_get_name(raw_method), raw_method)));
		}

		method_list_fetched = true;
	}

	return method_list;
}
Exemple #10
0
IMonoMethod *CScriptClass::GetMethod(const char *name, int numParams, bool throwOnFail)
{
	MonoMethodSignature *pSignature = nullptr;

	void *pIterator = 0;

	MonoClass *pClass = (MonoClass *)m_pObject;
	MonoType *pClassType = mono_class_get_type(pClass);
	MonoMethod *pCurMethod = nullptr;

	while (pClass != nullptr)
	{
		pCurMethod = mono_class_get_methods(pClass, &pIterator);
		if(pCurMethod == nullptr)
		{
			pClass = mono_class_get_parent(pClass);
			if(pClass == mono_get_object_class())
				break;

			pIterator = 0;
			continue;
		}

		pSignature = mono_method_signature(pCurMethod);
		int signatureParamCount = mono_signature_get_param_count(pSignature);

		bool bCorrectName = !strcmp(mono_method_get_name(pCurMethod), name);
		if(bCorrectName && signatureParamCount == numParams)
			return new CScriptMethod(pCurMethod);
	}

	if(throwOnFail)
	{
		if(!GetMonoScriptSystem()->IsInitialized())
		{
			CryLogAlways("Failed to locate method %s in class %s", name, GetName());
		}
		else if(IMonoAssembly *pCorlibAssembly = GetMonoScriptSystem()->GetCorlibAssembly())
		{
			if(IMonoException *pException = GetMonoScriptSystem()->GetCorlibAssembly()->GetException("System", "MissingMethodException", "Failed to locate method %s in class %s", name, GetName()))
				pException->Throw();
		}
	}
	
	return nullptr;
}
Exemple #11
0
static MonoException *
create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2)
{
	MonoError error;
	MonoDomain *domain = mono_domain_get ();
	MonoMethod *method = NULL;
	MonoObject *o;
	int count = 1;
	gpointer args [2];
	gpointer iter;
	MonoMethod *m;

	if (a2 != NULL)
		count++;
	
	o = mono_object_new_checked (domain, klass, &error);
	mono_error_assert_ok (&error);

	iter = NULL;
	while ((m = mono_class_get_methods (klass, &iter))) {
		MonoMethodSignature *sig;
		
		if (strcmp (".ctor", mono_method_get_name (m)))
			continue;
		sig = mono_method_signature (m);
		if (sig->param_count != count)
			continue;

		if (sig->params [0]->type != MONO_TYPE_STRING)
			continue;
		if (count == 2 && sig->params [1]->type != MONO_TYPE_STRING)
			continue;
		method = m;
		break;
	}

	args [0] = a1;
	args [1] = a2;

	mono_runtime_invoke_checked (method, o, args, &error);
	mono_error_raise_exception (&error); /* FIXME don't raise here */

	return (MonoException *) o;
}
Exemple #12
0
MonoExceptionHandle
mono_get_exception_type_initialization_handle (const gchar *type_name, MonoExceptionHandle inner, MonoError *error)
{
	HANDLE_FUNCTION_ENTER ();

	MonoClass *klass;
	MonoMethod *method;
	gpointer iter;

	error_init (error);

	klass = mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException");

	mono_class_init_internal (klass);

	iter = NULL;
	while ((method = mono_class_get_methods (klass, &iter))) {
		if (!strcmp (".ctor", mono_method_get_name (method))) {
			MonoMethodSignature *sig = mono_method_signature_internal (method);

			if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_STRING && mono_class_from_mono_type_internal (sig->params [1]) == mono_defaults.exception_class)
				break;
		}
		method = NULL;
	}
	g_assert (method);

	MonoDomain * const domain = mono_domain_get ();
	MonoStringHandle type_name_str = mono_string_new_handle (domain, type_name, error);
	mono_error_assert_ok (error);
	gpointer args [ ] = { MONO_HANDLE_RAW (type_name_str), MONO_HANDLE_RAW (inner) };

	MonoObjectHandle exc = mono_object_new_handle (domain, klass, error);
	mono_error_assert_ok (error);

	mono_runtime_invoke_handle (method, exc, args, error);
	goto_if_nok (error, return_null);
	goto exit;
return_null:
	exc = mono_new_null ();
exit:
	HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, exc));
}
Exemple #13
0
MonoExceptionHandle
mono_get_exception_reflection_type_load_checked (MonoArrayHandle types, MonoArrayHandle exceptions, MonoError *error)
{
	HANDLE_FUNCTION_ENTER ();

	MonoClass *klass;
	MonoMethod *method;
	gpointer iter;

	error_init (error);

	klass = mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");

	mono_class_init_internal (klass);

	/* Find the Type[], Exception[] ctor */
	iter = NULL;
	while ((method = mono_class_get_methods (klass, &iter))) {
		if (!strcmp (".ctor", mono_method_get_name (method))) {
			MonoMethodSignature *sig = mono_method_signature_internal (method);

			if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_SZARRAY && sig->params [1]->type == MONO_TYPE_SZARRAY)
				break;
		}
		method = NULL;
	}
	g_assert (method);

	MonoExceptionHandle exc = MONO_HANDLE_CAST (MonoException, MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (mono_domain_get (), klass, error)));
	mono_error_assert_ok (error);

	gpointer args [ ] = { MONO_HANDLE_RAW (types), MONO_HANDLE_RAW (exceptions) };

	mono_runtime_invoke_checked (method, MONO_HANDLE_RAW (exc), args, error);
	goto_if_nok (error, return_null);
	goto exit;
return_null:
	exc = MONO_HANDLE_CAST (MonoException, mono_new_null ());
exit:
	HANDLE_FUNCTION_RETURN_REF (MonoException, exc);
}
Exemple #14
0
int CScriptClass::GetMethods(const char *name, int numParams, IMonoMethod ***pMethodsOut, int maxMethods, bool throwOnFail)
{
	MonoMethodSignature *pSignature = nullptr;

	void *pIterator = 0;
	int i = 0;

	MonoClass *pClass = (MonoClass *)m_pObject;
	MonoType *pClassType = mono_class_get_type(pClass);
	MonoMethod *pCurMethod = nullptr;

	while (pClass != nullptr)
	{
		pCurMethod = mono_class_get_methods(pClass, &pIterator);
		if(pCurMethod == nullptr)
		{
			pClass = mono_class_get_parent(pClass);
			if(pClass == mono_get_object_class())
				break;

			pIterator = 0;
			continue;
		}

		pSignature = mono_method_signature(pCurMethod);
		int signatureParamCount = mono_signature_get_param_count(pSignature);

		bool bCorrectName = !strcmp(mono_method_get_name(pCurMethod), name);
		if(bCorrectName && signatureParamCount == numParams)
		{
			*pMethodsOut[i] = new CScriptMethod(pCurMethod);
			i++;

			if(i == maxMethods)
				return i + 1;
		}
	}

	return i + 1;
}
Exemple #15
0
static void
output_method (MonoMethod *method, gpointer dummy, MonoProfiler *prof)
{
	MonoMethodHeader *header;
	char *classname;
	char *tmpsig;
	char *tmpname;
	FILE *outfile;
	MonoClass *klass;
	MonoImage *image;

	outfile = prof->outfile;
	header = mono_method_get_header (method);

	tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
	tmpsig = g_markup_escape_text (tmpsig, strlen (tmpsig));

	klass = mono_method_get_class (method);
	classname = mono_type_get_name (mono_class_get_type (klass));
	image = mono_class_get_image (klass);

	tmpname = mono_method_get_name (method);
	tmpname = g_markup_escape_text (tmpname, strlen (tmpname));

	fprintf (outfile, "\t<method assembly=\"%s\" class=\"%s\" name=\"%s (%s)\" token=\"%d\">\n",
			 mono_image_get_name (image),
			 classname, tmpname,
			 tmpsig, mono_method_get_token (method));

	g_free (tmpsig);
	g_free (tmpname);
	fprintf (outfile, "\t\t");
	count = 0;
	prev_offset = 0;

	mono_profiler_coverage_get (prof, method, output_entry);

	fprintf (outfile, "\n");
	fprintf (outfile, "\t</method>\n");
}
Exemple #16
0
/*
 * mono_method_find
 *
 *     Get method by its name and argument types
 */
MonoMethod*
mono_method_find(MonoClass *klass, char *name, MonoType **params, int nparams)
{
	MonoMethod *method = NULL;
	MonoType *param_type;
	MonoMethodSignature *sig;
	gpointer method_iter = NULL;
	gpointer param_iter = NULL;
	int i;

	while ((method = mono_class_get_methods(klass, &method_iter)))
	{
		if (strcmp(mono_method_get_name(method), name))
			continue;

		sig = mono_method_signature(method);

		if (mono_signature_get_param_count(sig) != nparams)
			continue;

		i = 0;
		while ((param_type = mono_signature_get_params(sig, &param_iter)))
		{
			if (mono_class_from_mono_type(param_type) != mono_class_from_mono_type(params[i]))
				break;

			if (mono_type_is_byref(param_type) != mono_type_is_byref(params[i]))
				break;

			i++;
		}
		
		if (i == nparams)
		{
			return method;
		}
	}

	return NULL;
}
Exemple #17
0
void CPipeServer::EnumMethodsInClass()
{
	void *c=(void *)ReadQword();
	void *iter=NULL;
	void *method;

	do
	{
		method=mono_class_get_methods(c, &iter);
		WriteQword((UINT_PTR)method);

		if (method)
		{
			char *name;

			name=mono_method_get_name(method);
			WriteWord(strlen(name));
			Write(name, strlen(name));			
		}
	} while (method);

}
Exemple #18
0
static MonoExceptionHandle
create_exception_two_strings (MonoClass *klass, MonoStringHandle a1, MonoStringHandle a2, MonoError *error)
{
	HANDLE_FUNCTION_ENTER ();

	MonoMethod *method = NULL;
	int const count = 1 + !MONO_HANDLE_IS_NULL (a2);
	gpointer iter;
	MonoMethod *m;
	
	MonoObjectHandle o = mono_object_new_handle (mono_domain_get (), klass, error);
	mono_error_assert_ok (error);

	iter = NULL;
	while ((m = mono_class_get_methods (klass, &iter))) {
		MonoMethodSignature *sig;
		
		if (strcmp (".ctor", mono_method_get_name (m)))
			continue;
		sig = mono_method_signature_internal (m);
		if (sig->param_count != count)
			continue;

		if (sig->params [0]->type != MONO_TYPE_STRING)
			continue;
		if (count == 2 && sig->params [1]->type != MONO_TYPE_STRING)
			continue;
		method = m;
		break;
	}

	gpointer args [ ] = { MONO_HANDLE_RAW (a1), MONO_HANDLE_RAW (a2) };

	mono_runtime_invoke_handle (method, o, args, error);
	if (!is_ok (error))
		o = mono_new_null ();

	HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, o));
}
Exemple #19
0
/**
 * mono_get_exception_reflection_type_load:
 * @types: an array of types that were defined in the moduled loaded.
 * @exceptions: an array of exceptions that were thrown during the type loading.
 *
 * Returns: a new instance of the `System.Reflection.ReflectionTypeLoadException`
 */
MonoException *
mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions)
{
	MonoError error;
	MonoClass *klass;
	gpointer args [2];
	MonoObject *exc;
	MonoMethod *method;
	gpointer iter;

	klass = mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");

	mono_class_init (klass);

	/* Find the Type[], Exception[] ctor */
	iter = NULL;
	while ((method = mono_class_get_methods (klass, &iter))) {
		if (!strcmp (".ctor", mono_method_get_name (method))) {
			MonoMethodSignature *sig = mono_method_signature (method);

			if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_SZARRAY && sig->params [1]->type == MONO_TYPE_SZARRAY)
				break;
		}
		method = NULL;
	}
	g_assert (method);

	args [0] = types;
	args [1] = exceptions;

	exc = mono_object_new_checked (mono_domain_get (), klass, &error);
	mono_error_assert_ok (&error);

	mono_runtime_invoke_checked (method, exc, args, &error);
	mono_error_raise_exception (&error); /* FIXME don't raise here */

	return (MonoException *) exc;
}
Exemple #20
0
/**
 * mono_get_exception_type_initialization:
 * @type_name: the name of the type that failed to initialize.
 * @inner: the inner exception.
 *
 * Returns: a new instance of the `System.TypeInitializationException`
 */
MonoException *
mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner)
{
	MonoError error;
	MonoClass *klass;
	gpointer args [2];
	MonoObject *exc;
	MonoMethod *method;
	gpointer iter;

	klass = mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException");

	mono_class_init (klass);

	iter = NULL;
	while ((method = mono_class_get_methods (klass, &iter))) {
		if (!strcmp (".ctor", mono_method_get_name (method))) {
			MonoMethodSignature *sig = mono_method_signature (method);

			if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_STRING && mono_class_from_mono_type (sig->params [1]) == mono_defaults.exception_class)
				break;
		}
		method = NULL;
	}
	g_assert (method);

	args [0] = mono_string_new (mono_domain_get (), type_name);
	args [1] = inner;

	exc = mono_object_new_checked (mono_domain_get (), klass, &error);
	mono_error_assert_ok (&error);
	mono_runtime_invoke_checked (method, exc, args, &error);
	mono_error_raise_exception (&error); /* FIXME don't raise here */

	return (MonoException *) exc;
}
Exemple #21
0
void
virt_mono_throw_unhandled_exception (MonoObject *exc)
{
  caddr_t err;
  char *message = (char *) "";
  const char *name = (const char *) "";
  MonoString *str;
  MonoMethod *method;
  MonoClass *klass;
  gboolean free_message = FALSE;
  gint i;

  if (mono_object_isinst (exc, mono_get_exception_class ()))
    {
      klass = mono_object_get_class (exc);
      method = NULL;
      while (klass && method == NULL)
	{
	  gpointer m_iter = NULL;
	  for (method = mono_class_get_methods (klass, &m_iter); method != NULL;
	      method = mono_class_get_methods (klass, &m_iter))
	    {
	      MonoMethodSignature *sig = mono_method_signature (method);
	      guint32 flags = 0;
	      const char *name = mono_method_get_name (method);

	      mono_method_get_flags (method, &flags);
	      if (!strcmp ("ToString", name) &&
		  sig->param_count == 0
#ifdef OLD_KIT_1_1_5
		  && (flags & METHOD_ATTRIBUTE_VIRTUAL)
		  && (flags & METHOD_ATTRIBUTE_PUBLIC)
#endif
		  )
		{
		  break;
		}
	      method = NULL;
	    }

	  if (method == NULL)
	    klass = mono_class_get_parent (klass);
	}

      g_assert (method);

      str = (MonoString *) mono_runtime_invoke (method, exc, NULL, NULL);
      if (str) {
	message = mono_string_to_utf8 (str);
	free_message = TRUE;
	name = mono_class_get_name (klass);
      }
    }

  /*
   * g_printerr ("\nUnhandled Exception: %s.%s: %s\n", exc->vtable->klass->name_space,
   *	   exc->vtable->klass->name, message);
   */
  g_printerr ("\nUnhandled Exception: %s\n", message);


  err = srv_make_new_error ("42000", "MN001", "Unhandled Mono Exception [%.200s]: %.200s",
      name, message);
  if (free_message)
    g_free (message);
  sqlr_resignal (err);
}
Exemple #22
0
static gboolean
collect_coverage_for (MonoProfiler *prof, MonoMethod *method)
{
	int i;
	char *classname;
	char *fqn;
	MonoMethodHeader *header;
	gboolean has_positive, found;
	guint32 iflags, flags, code_size;
	MonoClass *klass;
	MonoImage *image;

	flags = mono_method_get_flags (method, &iflags);
	if ((iflags & 0x1000 /*METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL*/) ||
	    (flags & 0x2000 /*METHOD_ATTRIBUTE_PINVOKE_IMPL*/))
		return FALSE;

	//if (method->wrapper_type != MONO_WRAPPER_NONE)
	//	return FALSE;

	klass = mono_method_get_class (method);
	image = mono_class_get_image (klass);
	/* Hacky way of determining the executing assembly */
	if (! prof->outfile_name && (strcmp (mono_method_get_name (method), "Main") == 0)) {
		prof->outfile_name = g_strdup_printf ("%s.cov", mono_image_get_filename (image));
	}

	/* Check filters */
	if (prof->filters) {
		/* Check already filtered classes first */
		if (g_hash_table_lookup (prof->filtered_classes, klass))
			return FALSE;

		classname = mono_type_get_name (mono_class_get_type (klass));

		fqn = g_strdup_printf ("[%s]%s", mono_image_get_name (image), classname);

		// Check positive filters first
		has_positive = FALSE;
		found = FALSE;
		for (i = 0; i < prof->filters->len; ++i) {
			char *filter = g_ptr_array_index (prof->filters_as_str, i);
			if (filter [0] == '+') {
				filter = &filter [1];
				if (strstr (fqn, filter) != NULL)
					found = TRUE;
				has_positive = TRUE;
			}
		}
		if (has_positive && !found)
			return FALSE;

		for (i = 0; i < prof->filters->len; ++i) {
			// Is substring search suffices ???
//			GPatternSpec *spec = g_ptr_array_index (filters, i);
//			if (g_pattern_match_string (spec, classname)) {
			char *filter = g_ptr_array_index (prof->filters_as_str, i);
			if (filter [0] == '+')
				continue;

			// Skip '-'
			filter = &filter [1];
			if (strstr (fqn, filter) != NULL) {
				g_hash_table_insert (prof->filtered_classes, klass, klass);
				return FALSE;
			}
		}
		g_free (fqn);
		g_free (classname);
	}

	header = mono_method_get_header (method);

	mono_method_header_get_code (header, &code_size, NULL);
	if (code_size > 20000) {
		exit (1);
		g_warning ("Unable to instrument method %s:%s since it is too complex.", mono_class_get_name (klass), mono_method_get_name (method));
		return FALSE;
	}

	g_hash_table_insert (prof->methods, method, method);

	g_hash_table_insert (prof->classes, klass, klass);

	g_hash_table_insert (prof->assemblies, mono_image_get_assembly (image), mono_image_get_assembly (image));

	return TRUE;
}
Exemple #23
0
const char* mioMethod::getName() const
{
    if (!mmethod) { return nullptr; }
    return mono_method_get_name(mmethod);
}
	String MonoMethod::getName() const
	{
		return String(mono_method_get_name(mMethod));
	}
Exemple #25
0
IMonoMethod *CScriptClass::GetMethod(const char *name, IMonoArray *pArgs, bool throwOnFail)
{
	MonoMethodSignature *pSignature = nullptr;

	void *pIterator = 0;

	MonoClass *pClass = (MonoClass *)m_pObject;
	MonoType *pClassType = mono_class_get_type(pClass);
	MonoMethod *pCurMethod = nullptr;

	int suppliedArgsCount = pArgs ? pArgs->GetSize() : 0;

	while (pClass != nullptr)
	{
		pCurMethod = mono_class_get_methods(pClass, &pIterator);
		if(pCurMethod == nullptr)
		{
			pClass = mono_class_get_parent(pClass);
			if(pClass == mono_get_object_class())
				break;

			pIterator = 0;
			continue;
		}

		pSignature = mono_method_signature(pCurMethod);
		int signatureParamCount = mono_signature_get_param_count(pSignature);

		bool bCorrectName = !strcmp(mono_method_get_name(pCurMethod), name);
		if(bCorrectName && signatureParamCount == 0 && suppliedArgsCount == 0)
			return new CScriptMethod(pCurMethod);
		else if(bCorrectName && signatureParamCount >= suppliedArgsCount && suppliedArgsCount != 0)
		{
			//if(bStatic != (mono_method_get_flags(pCurMethod, nullptr) & METHOD_ATTRIBUTE_STATIC) > 0)
				//continue;

			void *pIter = nullptr;

			MonoType *pType = nullptr;
			for(int i = 0; i < signatureParamCount; i++)
			{
				pType = mono_signature_get_params(pSignature, &pIter);

				if(mono::object item = pArgs->GetItem(i))
				{
					MonoClass *pItemClass = mono_object_get_class((MonoObject *)item);
					MonoType *pItemType = mono_class_get_type(pItemClass);

					MonoTypeEnum itemMonoType = (MonoTypeEnum)mono_type_get_type(pItemType);

					MonoTypeEnum monoType = (MonoTypeEnum)mono_type_get_type(pType);

					if(itemMonoType != monoType)
					{
						// exceptions:
						// Anything can be treated as object.
						if(monoType == MONO_TYPE_OBJECT) {}
						// The runtime confuses things with value types a lot, so ignore parameters that appear with that type.
						else if(itemMonoType == MONO_TYPE_VALUETYPE || monoType == MONO_TYPE_VALUETYPE) {}
						else
						{
							if(MonoClass *pMethodParameterClass = mono_type_get_class(pType))
							{
								MonoWarning("Parameter mismatch when searching for method %s in class %s.%s, on parameter %i: Provided type %s.%s does not match expected parameter type %s.%s.", 
									name, mono_class_get_namespace(pClass), mono_class_get_name(pClass), i + 1, mono_class_get_namespace(pItemClass), mono_class_get_name(pItemClass), mono_class_get_namespace(pMethodParameterClass), mono_class_get_name(pMethodParameterClass));
							}
							else
							{
								MonoWarning("Parameter mismatch when searching for method %s in class %s.%s, on parameter %i: Provided type %s.%s does not match parameter type.", 
									name, mono_class_get_namespace(pClass), mono_class_get_name(pClass), i + 1, mono_class_get_namespace(pItemClass), mono_class_get_name(pItemClass));
							}
							break;
						}
					}
				}

				if(i + 1 == suppliedArgsCount)
					return new CScriptMethod(pCurMethod);
			}
		}
	}

	if(throwOnFail)
	{
		if(IMonoException *pException = GetMonoScriptSystem()->GetCorlibAssembly()->GetException("System", "MissingMethodException", "Failed to locate method %s in class %s", name, GetName()))
			pException->Throw();
	}

	return nullptr;
}
Exemple #26
0
void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base) {

	CRASH_COND(!CACHED_CLASS(GodotObject)->is_assignable_from(this));

	if (methods_fetched)
		return;

	void *iter = NULL;
	MonoMethod *raw_method = NULL;
	while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != NULL) {
		StringName name = mono_method_get_name(raw_method);

		// get_method implicitly fetches methods and adds them to this->methods
		GDMonoMethod *method = get_method(raw_method, name);
		ERR_CONTINUE(!method);

		if (method->get_name() != name) {

#ifdef DEBUG_ENABLED
			String fullname = method->get_ret_type_full_name() + " " + name + "(" + method->get_signature_desc(true) + ")";
			WARN_PRINTS("Method `" + fullname + "` is hidden by Godot API method. Should be `" +
						method->get_full_name_no_class() + "`. In class `" + namespace_name + "." + class_name + "`.");
#endif
			continue;
		}

#ifdef DEBUG_ENABLED
		// For debug builds, we also fetched from native base classes as well before if this is not a native base class.
		// This allows us to warn the user here if he is using snake_case by mistake.

		if (p_native_base != this) {

			GDMonoClass *native_top = p_native_base;
			while (native_top) {
				GDMonoMethod *m = native_top->get_method(name, method->get_parameters_count());

				if (m && m->get_name() != name) {
					// found
					String fullname = m->get_ret_type_full_name() + " " + name + "(" + m->get_signature_desc(true) + ")";
					WARN_PRINTS("Method `" + fullname + "` should be `" + m->get_full_name_no_class() +
								"`. In class `" + namespace_name + "." + class_name + "`.");
					break;
				}

				if (native_top == CACHED_CLASS(GodotObject))
					break;

				native_top = native_top->get_parent_class();
			}
		}
#endif

		uint32_t flags = mono_method_get_flags(method->mono_method, NULL);

		if (!(flags & MONO_METHOD_ATTR_VIRTUAL))
			continue;

		// Virtual method of Godot Object derived type, let's try to find GodotMethod attribute

		GDMonoClass *top = p_native_base;

		while (top) {
			GDMonoMethod *base_method = top->get_method(name, method->get_parameters_count());

			if (base_method && base_method->has_attribute(CACHED_CLASS(GodotMethodAttribute))) {
				// Found base method with GodotMethod attribute.
				// We get the original API method name from this attribute.
				// This name must point to the virtual method.

				MonoObject *attr = base_method->get_attribute(CACHED_CLASS(GodotMethodAttribute));

				StringName godot_method_name = CACHED_FIELD(GodotMethodAttribute, methodName)->get_string_value(attr);
#ifdef DEBUG_ENABLED
				CRASH_COND(godot_method_name == StringName());
#endif
				MethodKey key = MethodKey(godot_method_name, method->get_parameters_count());
				GDMonoMethod **existing_method = methods.getptr(key);
				if (existing_method)
					memdelete(*existing_method); // Must delete old one
				methods.set(key, method);

				break;
			}

			if (top == CACHED_CLASS(GodotObject))
				break;

			top = top->get_parent_class();
		}
	}

	methods_fetched = true;
}