* (C) 2002 Ximian, Inc.
* Copyright 2003-2011 Novell, Inc.
* Copyright 2011 Xamarin, Inc.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "config.h"
}
static MonoMethod*
-decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf);
+decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error);
static MonoClass*
decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error);
if (is_method) {
MonoMethod *method_def;
g_assert (type == MONO_TYPE_MVAR);
- method_def = decode_resolve_method_ref (module, p, &p);
- if (!method_def) {
- mono_error_set_bad_image_name (error, module->aot_name, "Could not decode methodref when computing owned method typeref var");
+ method_def = decode_resolve_method_ref (module, p, &p, error);
+ if (!method_def)
return NULL;
- }
container = mono_method_get_generic_container (method_def);
} else {
* that the method reference matches a given method. This is normally not a problem
* as these wrappers only occur in the extra_methods table, where we already have
* a method we want to lookup.
+ *
+ * If there was a decoding error, we return FALSE and set @error
*/
static gboolean
-decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod *target, guint8 *buf, guint8 **endbuf)
+decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod *target, guint8 *buf, guint8 **endbuf, MonoError *error)
{
- MonoError error;
guint32 image_index, value;
MonoImage *image = NULL;
guint8 *p = buf;
memset (ref, 0, sizeof (MethodRef));
+ mono_error_init (error);
value = decode_value (p, &p);
image_index = value >> 24;
}
if (image_index < MONO_AOT_METHODREF_MIN || image_index == MONO_AOT_METHODREF_METHODSPEC || image_index == MONO_AOT_METHODREF_GINST) {
- if (target && target->wrapper_type)
+ if (target && target->wrapper_type) {
return FALSE;
+ }
}
if (image_index == MONO_AOT_METHODREF_WRAPPER) {
switch (wrapper_type) {
#ifndef DISABLE_REMOTING
case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK: {
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
mono_class_init (m->klass);
break;
}
case MONO_WRAPPER_PROXY_ISINST: {
- MonoClass *klass = decode_klass_ref (module, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ MonoClass *klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
ref->method = mono_marshal_get_proxy_cancast (klass);
case MONO_WRAPPER_LDFLDA:
case MONO_WRAPPER_STFLD:
case MONO_WRAPPER_ISINST: {
- MonoClass *klass = decode_klass_ref (module, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ MonoClass *klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
if (wrapper_type == MONO_WRAPPER_LDFLD)
ref->method = mono_marshal_get_stfld_wrapper (&klass->byval_arg);
else if (wrapper_type == MONO_WRAPPER_ISINST)
ref->method = mono_marshal_get_isinst (klass);
- else
- g_assert_not_reached ();
+ else {
+ mono_error_set_bad_image_name (error, module->aot_name, "Unknown AOT wrapper type %d", wrapper_type);
+ return FALSE;
+ }
break;
}
case MONO_WRAPPER_LDFLD_REMOTE:
int atype = decode_value (p, &p);
ref->method = mono_gc_get_managed_allocator_by_type (atype, !!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS));
- if (!ref->method)
- g_error ("Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
+ if (!ref->method) {
+ mono_error_set_bad_image_name (error, module->aot_name, "Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
+ return FALSE;
+ }
break;
}
case MONO_WRAPPER_WRITE_BARRIER: {
return FALSE;
}
} else {
- g_assert_not_reached ();
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid STELEMREF subtype %d", subtype);
+ return FALSE;
}
break;
}
case MONO_WRAPPER_SYNCHRONIZED: {
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_synchronized_wrapper (m);
int subtype = decode_value (p, &p);
if (subtype == WRAPPER_SUBTYPE_PTR_TO_STRUCTURE || subtype == WRAPPER_SUBTYPE_STRUCTURE_TO_PTR) {
- MonoClass *klass = decode_klass_ref (module, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
-
+ MonoClass *klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
ref->method = mono_marshal_get_struct_to_ptr (klass);
}
} else if (subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER) {
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_synchronized_inner_wrapper (m);
} else if (subtype == WRAPPER_SUBTYPE_ARRAY_ACCESSOR) {
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_array_accessor_wrapper (m);
return FALSE;
ref->method = mini_get_gsharedvt_out_sig_wrapper (sig);
} else {
- g_assert_not_reached ();
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid UNKNOWN wrapper subtype %d", subtype);
+ return FALSE;
}
break;
}
} else if (subtype == WRAPPER_SUBTYPE_STRING_CTOR) {
MonoMethod *m;
- m = decode_resolve_method_ref (module, p, &p);
+ m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
return FALSE;
ref->method = target;
} else {
- m = decode_resolve_method_ref (module, p, &p);
-
+ m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_castclass_with_cache ();
else if (subtype == WRAPPER_SUBTYPE_ISINST_WITH_CACHE)
ref->method = mono_marshal_get_isinst_with_cache ();
- else
- g_assert_not_reached ();
+ else {
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid CASTCLASS wrapper subtype %d", subtype);
+ return FALSE;
+ }
break;
}
case MONO_WRAPPER_RUNTIME_INVOKE: {
ref->method = target;
} else if (subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT) {
/* Direct wrapper */
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_runtime_invoke (m, FALSE);
} else if (subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL) {
/* Virtual direct wrapper */
- MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+ MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
ref->method = mono_marshal_get_runtime_invoke (m, TRUE);
MonoClass *klass;
MonoMethod *invoke, *wrapper;
- klass = decode_klass_ref (module, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
MonoMethod *m;
MonoClass *klass;
- m = decode_resolve_method_ref (module, p, &p);
+ m = decode_resolve_method_ref (module, p, &p, error);
if (!m)
return FALSE;
- klass = decode_klass_ref (module, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
ref->method = mono_marshal_get_managed_wrapper (m, klass, 0);
image_index = decode_value (p, &p);
ref->token = decode_value (p, &p);
- image = load_image (module, image_index, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ image = load_image (module, image_index, error);
if (!image)
return FALSE;
} else if (image_index == MONO_AOT_METHODREF_GINST) {
- MonoError error;
MonoClass *klass;
MonoGenericContext ctx;
* These methods do not have a token which resolves them, so we
* resolve them immediately.
*/
- klass = decode_klass_ref (module, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
image_index = decode_value (p, &p);
ref->token = decode_value (p, &p);
- image = load_image (module, image_index, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ image = load_image (module, image_index, error);
if (!image)
return FALSE;
- ref->method = mono_get_method_checked (image, ref->token, NULL, NULL, &error);
- if (!ref->method) {
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ ref->method = mono_get_method_checked (image, ref->token, NULL, NULL, error);
+ if (!ref->method)
return FALSE;
- }
+
memset (&ctx, 0, sizeof (ctx));
ctx.class_inst = klass->generic_class->context.class_inst;
ctx.method_inst = NULL;
- ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, &error);
+ ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, error);
if (!ref->method)
- g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+ return FALSE;
}
memset (&ctx, 0, sizeof (ctx));
- if (!decode_generic_context (module, &ctx, p, &p, &error)) {
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ if (!decode_generic_context (module, &ctx, p, &p, error))
return FALSE;
- }
- ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, &error);
+ ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, error);
if (!ref->method)
- g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+ return FALSE;
} else if (image_index == MONO_AOT_METHODREF_ARRAY) {
MonoClass *klass;
int method_type;
- klass = decode_klass_ref (module, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ klass = decode_klass_ref (module, p, &p, error);
if (!klass)
return FALSE;
method_type = decode_value (p, &p);
ref->method = mono_class_get_method_from_name (klass, "Set", -1);
break;
default:
- g_assert_not_reached ();
+ mono_error_set_bad_image_name (error, module->aot_name, "Invalid METHODREF_ARRAY method type %d", method_type);
+ return FALSE;
}
} else {
if (image_index == MONO_AOT_METHODREF_LARGE_IMAGE_INDEX) {
ref->token = MONO_TOKEN_METHOD_DEF | (value & 0xffffff);
- image = load_image (module, image_index, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ image = load_image (module, image_index, error);
if (!image)
return FALSE;
}
}
static gboolean
-decode_method_ref (MonoAotModule *module, MethodRef *ref, guint8 *buf, guint8 **endbuf)
+decode_method_ref (MonoAotModule *module, MethodRef *ref, guint8 *buf, guint8 **endbuf, MonoError *error)
{
- return decode_method_ref_with_target (module, ref, NULL, buf, endbuf);
+ return decode_method_ref_with_target (module, ref, NULL, buf, endbuf, error);
}
/*
* Similar to decode_method_ref, but resolve and return the method itself.
*/
static MonoMethod*
-decode_resolve_method_ref_with_target (MonoAotModule *module, MonoMethod *target, guint8 *buf, guint8 **endbuf)
+decode_resolve_method_ref_with_target (MonoAotModule *module, MonoMethod *target, guint8 *buf, guint8 **endbuf, MonoError *error)
{
- MonoError error;
MethodRef ref;
- gboolean res;
- MonoMethod *result;
- res = decode_method_ref_with_target (module, &ref, target, buf, endbuf);
- if (!res)
+ mono_error_init (error);
+
+ if (!decode_method_ref_with_target (module, &ref, target, buf, endbuf, error))
return NULL;
if (ref.method)
return ref.method;
- if (!ref.image)
+ if (!ref.image) {
+ mono_error_set_bad_image_name (error, module->aot_name, "No image found for methodref with target");
return NULL;
- result = mono_get_method_checked (ref.image, ref.token, NULL, NULL, &error);
- if (!result)
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
- return result;
+ }
+ return mono_get_method_checked (ref.image, ref.token, NULL, NULL, error);
}
static MonoMethod*
-decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error)
{
- return decode_resolve_method_ref_with_target (module, NULL, buf, endbuf);
+ return decode_resolve_method_ref_with_target (module, NULL, buf, endbuf, error);
}
#ifdef ENABLE_AOT_CACHE
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module '%s' not found: %s\n", aot_name, err);
g_free (err);
- aot_name = g_strdup_printf ("%s/mono/aot-cache/%s/%s%s", mono_assembly_getrootdir(), MONO_ARCHITECTURE, g_path_get_basename (assembly->image->name), MONO_SOLIB_EXT);
+ g_free (aot_name);
+ char *basename = g_path_get_basename (assembly->image->name);
+ aot_name = g_strdup_printf ("%s/mono/aot-cache/%s/%s%s", mono_assembly_getrootdir(), MONO_ARCHITECTURE, basename, MONO_SOLIB_EXT);
+ g_free (basename);
sofile = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
if (!sofile) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module '%s' not found: %s\n", aot_name, err);
static gboolean
decode_cached_class_info (MonoAotModule *module, MonoCachedClassInfo *info, guint8 *buf, guint8 **endbuf)
{
+ MonoError error;
guint32 flags;
MethodRef ref;
gboolean res;
info->is_generic_container = (flags >> 8) & 0x1;
if (info->has_cctor) {
- res = decode_method_ref (module, &ref, buf, &buf);
+ res = decode_method_ref (module, &ref, buf, &buf, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
if (!res)
return FALSE;
info->cctor_token = ref.token;
}
if (info->has_finalize) {
- res = decode_method_ref (module, &ref, buf, &buf);
+ res = decode_method_ref (module, &ref, buf, &buf, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
if (!res)
return FALSE;
info->finalize_image = ref.image;
gpointer
mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
{
+ MonoError error;
int i;
MonoClass *klass = vtable->klass;
MonoAotModule *amodule = (MonoAotModule *)klass->image->aot_module;
if (!err)
return NULL;
- for (i = 0; i < slot; ++i)
- decode_method_ref (amodule, &ref, p, &p);
+ for (i = 0; i < slot; ++i) {
+ decode_method_ref (amodule, &ref, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ }
- res = decode_method_ref (amodule, &ref, p, &p);
+ res = decode_method_ref (amodule, &ref, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!res)
return NULL;
if (ref.no_aot_trampoline)
}
len = decode_value (p, &p);
- if (async)
+ if (async) {
p += len;
- else
- jinfo->d.method = decode_resolve_method_ref (amodule, p, &p);
+ } else {
+ jinfo->d.method = decode_resolve_method_ref (amodule, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ }
- gi->generic_sharing_context = g_new0 (MonoGenericSharingContext, 1);
+ gi->generic_sharing_context = alloc0_jit_info_data (domain, sizeof (MonoGenericSharingContext), async);
if (decode_value (p, &p)) {
/* gsharedvt */
MonoGenericSharingContext *gsctx = gi->generic_sharing_context;
MonoJitInfo *
mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
{
+ MonoError error;
int pos, left, right, code_len;
int method_index, table_len;
guint32 token;
}
p = amodule->blob + table [(pos * 2) + 1];
- method = decode_resolve_method_ref (amodule, p, &p);
+ method = decode_resolve_method_ref (amodule, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!method)
/* Happens when a random address is passed in which matches a not-yey called wrapper encoded using its name */
return NULL;
MethodRef ref;
gboolean res;
- res = decode_method_ref (aot_module, &ref, p, &p);
+ res = decode_method_ref (aot_module, &ref, p, &p, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
if (!res)
goto cleanup;
}
case MONO_PATCH_INFO_METHODCONST:
/* Shared */
- ji->data.method = decode_resolve_method_ref (aot_module, p, &p);
+ ji->data.method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!ji->data.method)
goto cleanup;
break;
if (!ji->data.del_tramp->klass)
goto cleanup;
if (decode_value (p, &p)) {
- ji->data.del_tramp->method = decode_resolve_method_ref (aot_module, p, &p);
+ ji->data.del_tramp->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (!ji->data.del_tramp->method)
goto cleanup;
}
entry = (MonoJumpInfoRgctxEntry *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoRgctxEntry));
p2 = aot_module->blob + offset;
- entry->method = decode_resolve_method_ref (aot_module, p2, &p2);
+ entry->method = decode_resolve_method_ref (aot_module, p2, &p2, &error);
entry->in_mrgctx = ((val & 1) > 0) ? TRUE : FALSE;
entry->info_type = (MonoRgctxInfoType)((val >> 1) & 0xff);
entry->data = (MonoJumpInfo *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfo));
entry->data->type = (MonoJumpInfoType)((val >> 9) & 0xff);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
res = decode_patch (aot_module, mp, entry->data, p, &p);
if (!res)
MonoJumpInfoGSharedVtCall *info = (MonoJumpInfoGSharedVtCall *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoGSharedVtCall));
info->sig = decode_signature (aot_module, p, &p);
g_assert (info->sig);
- info->method = decode_resolve_method_ref (aot_module, p, &p);
- g_assert (info->method);
+ info->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
ji->data.target = info;
break;
MonoGSharedVtMethodInfo *info = (MonoGSharedVtMethodInfo *)mono_mempool_alloc0 (mp, sizeof (MonoGSharedVtMethodInfo));
int i;
- info->method = decode_resolve_method_ref (aot_module, p, &p);
- g_assert (info->method);
+ info->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
info->num_entries = decode_value (p, &p);
info->count_entries = info->num_entries;
info->entries = (MonoRuntimeGenericContextInfoTemplate *)mono_mempool_alloc0 (mp, sizeof (MonoRuntimeGenericContextInfoTemplate) * info->num_entries);
MonoJumpInfoVirtMethod *info = (MonoJumpInfoVirtMethod *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoVirtMethod));
info->klass = decode_klass_ref (aot_module, p, &p, &error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
- g_assert (info->klass);
- info->method = decode_resolve_method_ref (aot_module, p, &p);
- g_assert (info->method);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
+ info->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
ji->data.target = info;
break;
static guint32
find_aot_method_in_amodule (MonoAotModule *amodule, MonoMethod *method, guint32 hash_full)
{
+ MonoError error;
guint32 table_size, entry_size, hash;
guint32 *table, *entry;
guint32 index;
m = (MonoMethod *)g_hash_table_lookup (amodule->method_ref_to_method, p);
amodule_unlock (amodule);
if (!m) {
- m = decode_resolve_method_ref_with_target (amodule, method, p, &p);
+ m = decode_resolve_method_ref_with_target (amodule, method, p, &p, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
/*
* Can't catche runtime invoke wrappers since it would break
* the check in decode_method_ref_with_target ().