Merge pull request #2869 from BrzVlad/feature-mod-union-opt
[mono.git] / mono / mini / aot-runtime.c
index 1bbd796dc837f0900cc86883b2e2c832b10d946a..d3f3cf2e952c82b946e69b7a834082609d318d2e 100644 (file)
@@ -8,6 +8,7 @@
  * (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"
@@ -245,36 +246,36 @@ amodule_unlock (MonoAotModule *amodule)
  * load_image:
  *
  *   Load one of the images referenced by AMODULE. Returns NULL if the image is not
- * found, and sets the loader error if SET_ERROR is TRUE.
+ * found, and sets @error for what happened
  */
 static MonoImage *
-load_image (MonoAotModule *amodule, int index, gboolean set_error)
+load_image (MonoAotModule *amodule, int index, MonoError *error)
 {
        MonoAssembly *assembly;
        MonoImageOpenStatus status;
 
        g_assert (index < amodule->image_table_len);
 
+       mono_error_init (error);
+
        if (amodule->image_table [index])
                return amodule->image_table [index];
-       if (amodule->out_of_date)
+       if (amodule->out_of_date) {
+               mono_error_set_bad_image_name (error, amodule->aot_name, "Image out of date");
                return NULL;
+       }
 
        assembly = mono_assembly_load (&amodule->image_names [index], amodule->assembly->basedir, &status);
        if (!assembly) {
                mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable because dependency %s is not found.\n", amodule->aot_name, amodule->image_names [index].name);
+               mono_error_set_bad_image_name (error, amodule->aot_name, "module is unusable because dependency %s is not found (error %d).\n", amodule->image_names [index].name, status);
                amodule->out_of_date = TRUE;
-
-               if (set_error) {
-                       char *full_name = mono_stringify_assembly_name (&amodule->image_names [index]);
-                       mono_loader_set_error_assembly_load (full_name, FALSE);
-                       g_free (full_name);
-               }
                return NULL;
        }
 
        if (strcmp (assembly->image->guid, amodule->image_guids [index])) {
                mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable (GUID of dependent assembly %s doesn't match (expected '%s', got '%s').\n", amodule->aot_name, amodule->image_names [index].name, amodule->image_guids [index], assembly->image->guid);
+               mono_error_set_bad_image_name (error, amodule->aot_name, "module is unusable (GUID of dependent assembly %s doesn't match (expected '%s', got '%s').\n", amodule->image_names [index].name, amodule->image_guids [index], assembly->image->guid);
                amodule->out_of_date = TRUE;
                return NULL;
        }
@@ -356,27 +357,28 @@ mono_aot_get_offset (guint32 *table, int index)
 }
 
 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);
+decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error);
 
 static MonoType*
-decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf);
+decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error);
 
 static MonoGenericInst*
-decode_generic_inst (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_generic_inst (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error)
 {
        int type_argc, i;
        MonoType **type_argv;
        MonoGenericInst *inst;
        guint8 *p = buf;
 
+       mono_error_init (error);
        type_argc = decode_value (p, &p);
        type_argv = g_new0 (MonoType*, type_argc);
 
        for (i = 0; i < type_argc; ++i) {
-               MonoClass *pclass = decode_klass_ref (module, p, &p);
+               MonoClass *pclass = decode_klass_ref (module, p, &p, error);
                if (!pclass) {
                        g_free (type_argv);
                        return NULL;
@@ -393,17 +395,18 @@ decode_generic_inst (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
 }
 
 static gboolean
-decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *buf, guint8 **endbuf)
+decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *buf, guint8 **endbuf, MonoError *error)
 {
        guint8 *p = buf;
        guint8 *p2;
        int argc;
+       mono_error_init (error);
 
        p2 = p;
        argc = decode_value (p, &p);
        if (argc) {
                p = p2;
-               ctx->class_inst = decode_generic_inst (module, p, &p);
+               ctx->class_inst = decode_generic_inst (module, p, &p, error);
                if (!ctx->class_inst)
                        return FALSE;
        }
@@ -411,7 +414,7 @@ decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *
        argc = decode_value (p, &p);
        if (argc) {
                p = p2;
-               ctx->method_inst = decode_generic_inst (module, p, &p);
+               ctx->method_inst = decode_generic_inst (module, p, &p, error);
                if (!ctx->method_inst)
                        return FALSE;
        }
@@ -421,63 +424,63 @@ decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *
 }
 
 static MonoClass*
-decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error)
 {
-       MonoError error;
        MonoImage *image;
        MonoClass *klass = NULL, *eklass;
        guint32 token, rank, idx;
        guint8 *p = buf;
        int reftype;
 
+       mono_error_init (error);
        reftype = decode_value (p, &p);
        if (reftype == 0) {
                *endbuf = p;
+               mono_error_set_bad_image_name (error, module->aot_name, "Decoding a null class ref");
                return NULL;
        }
 
        switch (reftype) {
        case MONO_AOT_TYPEREF_TYPEDEF_INDEX:
                idx = decode_value (p, &p);
-               image = load_image (module, 0, TRUE);
+               image = load_image (module, 0, error);
                if (!image)
                        return NULL;
-               klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, &error);
-               g_assert (mono_error_ok (&error));
+               klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, error);
                break;
        case MONO_AOT_TYPEREF_TYPEDEF_INDEX_IMAGE:
                idx = decode_value (p, &p);
-               image = load_image (module, decode_value (p, &p), TRUE);
+               image = load_image (module, decode_value (p, &p), error);
                if (!image)
                        return NULL;
-               klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, &error);
-               g_assert (mono_error_ok (&error));
+               klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, error);
                break;
        case MONO_AOT_TYPEREF_TYPESPEC_TOKEN:
                token = decode_value (p, &p);
                image = module->assembly->image;
-               if (!image)
+               if (!image) {
+                       mono_error_set_bad_image_name (error, module->aot_name, "No image associated with the aot module");
                        return NULL;
-               klass = mono_class_get_checked (image, token, &error);
-               g_assert (mono_error_ok (&error));
+               }
+               klass = mono_class_get_checked (image, token, error);
                break;
        case MONO_AOT_TYPEREF_GINST: {
-               MonoError error;
                MonoClass *gclass;
                MonoGenericContext ctx;
                MonoType *type;
 
-               gclass = decode_klass_ref (module, p, &p);
+               gclass = decode_klass_ref (module, p, &p, error);
                if (!gclass)
                        return NULL;
                g_assert (gclass->generic_container);
 
                memset (&ctx, 0, sizeof (ctx));
-               ctx.class_inst = decode_generic_inst (module, p, &p);
+               ctx.class_inst = decode_generic_inst (module, p, &p, error);
                if (!ctx.class_inst)
                        return NULL;
-               type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, &error);
-               mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+               type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, error);
+               if (!type)
+                       return NULL;
                klass = mono_class_from_mono_type (type);
                mono_metadata_free_type (type);
                break;
@@ -491,11 +494,11 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
                        MonoClass *par_klass;
                        MonoType *gshared_constraint;
 
-                       gshared_constraint = decode_type (module, p, &p);
+                       gshared_constraint = decode_type (module, p, &p, error);
                        if (!gshared_constraint)
                                return NULL;
 
-                       par_klass = decode_klass_ref (module, p, &p);
+                       par_klass = decode_klass_ref (module, p, &p, error);
                        if (!par_klass)
                                return NULL;
 
@@ -512,7 +515,7 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
                                if (is_method) {
                                        MonoMethod *method_def;
                                        g_assert (type == MONO_TYPE_MVAR);
-                                       method_def = decode_resolve_method_ref (module, p, &p);
+                                       method_def = decode_resolve_method_ref (module, p, &p, error);
                                        if (!method_def)
                                                return NULL;
 
@@ -520,7 +523,7 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
                                } else {
                                        MonoClass *class_def;
                                        g_assert (type == MONO_TYPE_VAR);
-                                       class_def = decode_klass_ref (module, p, &p);
+                                       class_def = decode_klass_ref (module, p, &p, error);
                                        if (!class_def)
                                                return NULL;
 
@@ -554,13 +557,15 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
        case MONO_AOT_TYPEREF_ARRAY:
                /* Array */
                rank = decode_value (p, &p);
-               eklass = decode_klass_ref (module, p, &p);
+               eklass = decode_klass_ref (module, p, &p, error);
+               if (!eklass)
+                       return NULL;
                klass = mono_array_class_get (eklass, rank);
                break;
        case MONO_AOT_TYPEREF_PTR: {
                MonoType *t;
 
-               t = decode_type (module, p, &p);
+               t = decode_type (module, p, &p, error);
                if (!t)
                        return NULL;
                klass = mono_class_from_mono_type (t);
@@ -572,13 +577,13 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
                guint8 *p2;
 
                p2 = module->blob + offset;
-               klass = decode_klass_ref (module, p2, &p2);
+               klass = decode_klass_ref (module, p2, &p2, error);
                break;
        }
        default:
-               g_assert_not_reached ();
+               mono_error_set_bad_image_name (error, module->aot_name, "Invalid klass reftype %d", reftype);
        }
-       g_assert (klass);
+       //g_assert (klass);
        //printf ("BLA: %s\n", mono_type_full_name (&klass->byval_arg));
        *endbuf = p;
        return klass;
@@ -587,12 +592,15 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
 static MonoClassField*
 decode_field_info (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
 {
-       MonoClass *klass = decode_klass_ref (module, buf, &buf);
+       MonoError error;
+       MonoClass *klass = decode_klass_ref (module, buf, &buf, &error);
        guint32 token;
        guint8 *p = buf;
 
-       if (!klass)
+       if (!klass) {
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                return NULL;
+       }
 
        token = MONO_TOKEN_FIELD_DEF + decode_value (p, &p);
 
@@ -606,12 +614,13 @@ decode_field_info (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
  * memory.
  */
 static MonoType*
-decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error)
 {
        guint8 *p = buf;
        MonoType *t;
 
        t = (MonoType *)g_malloc0 (sizeof (MonoType));
+       mono_error_init (error);
 
        while (TRUE) {
                if (*p == MONO_TYPE_PINNED) {
@@ -650,36 +659,39 @@ decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
                break;
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_CLASS:
-               t->data.klass = decode_klass_ref (module, p, &p);
+               t->data.klass = decode_klass_ref (module, p, &p, error);
+               if (!t->data.klass)
+                       goto fail;
                break;
        case MONO_TYPE_SZARRAY:
-               t->data.klass = decode_klass_ref (module, p, &p);
+               t->data.klass = decode_klass_ref (module, p, &p, error);
 
                if (!t->data.klass)
-                       return NULL;
+                       goto fail;
                break;
        case MONO_TYPE_PTR:
-               t->data.type = decode_type (module, p, &p);
+               t->data.type = decode_type (module, p, &p, error);
+               if (!t->data.type)
+                       goto fail;
                break;
        case MONO_TYPE_GENERICINST: {
-               MonoError error;
                MonoClass *gclass;
                MonoGenericContext ctx;
                MonoType *type;
                MonoClass *klass;
 
-               gclass = decode_klass_ref (module, p, &p);
+               gclass = decode_klass_ref (module, p, &p, error);
                if (!gclass)
-                       return NULL;
+                       goto fail;
                g_assert (gclass->generic_container);
 
                memset (&ctx, 0, sizeof (ctx));
-               ctx.class_inst = decode_generic_inst (module, p, &p);
+               ctx.class_inst = decode_generic_inst (module, p, &p, error);
                if (!ctx.class_inst)
-                       return NULL;
-               type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, &error);
-               mono_error_assert_ok (&error); /* FIXME don't swallow the error */
-
+                       goto fail;
+               type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, error);
+               if (!type)
+                       goto fail;
                klass = mono_class_from_mono_type (type);
                t->data.generic_class = klass->generic_class;
                break;
@@ -690,9 +702,9 @@ decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
 
                // FIXME: memory management
                array = g_new0 (MonoArrayType, 1);
-               array->eklass = decode_klass_ref (module, p, &p);
+               array->eklass = decode_klass_ref (module, p, &p, error);
                if (!array->eklass)
-                       return NULL;
+                       goto fail;
                array->rank = decode_value (p, &p);
                array->numsizes = decode_value (p, &p);
 
@@ -711,19 +723,23 @@ decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
        }
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR: {
-               MonoClass *klass = decode_klass_ref (module, p, &p);
+               MonoClass *klass = decode_klass_ref (module, p, &p, error);
                if (!klass)
-                       return NULL;
+                       goto fail;
                t->data.generic_param = klass->byval_arg.data.generic_param;
                break;
        }
        default:
-               g_assert_not_reached ();
+               mono_error_set_bad_image_name (error, module->aot_name, "Invalid encoded type %d", t->type);
+               goto fail;
        }
 
        *endbuf = p;
 
        return t;
+fail:
+       g_free (t);
+       return NULL;
 }
 
 // FIXME: Error handling, memory management
@@ -731,6 +747,7 @@ decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
 static MonoMethodSignature*
 decode_signature_with_target (MonoAotModule *module, MonoMethodSignature *target, guint8 *buf, guint8 **endbuf)
 {
+       MonoError error;
        MonoMethodSignature *sig;
        guint32 flags;
        int i, gen_param_count = 0, param_count, call_conv;
@@ -756,14 +773,18 @@ decode_signature_with_target (MonoAotModule *module, MonoMethodSignature *target
        sig->explicit_this = explicit_this;
        sig->call_convention = call_conv;
        sig->generic_param_count = gen_param_count;
-       sig->ret = decode_type (module, p, &p);
+       sig->ret = decode_type (module, p, &p, &error);
+       if (!sig->ret)
+               goto fail;
        for (i = 0; i < param_count; ++i) {
                if (*p == MONO_TYPE_SENTINEL) {
                        g_assert (sig->call_convention == MONO_CALL_VARARG);
                        sig->sentinelpos = i;
                        p ++;
                }
-               sig->params [i] = decode_type (module, p, &p);
+               sig->params [i] = decode_type (module, p, &p, &error);
+               if (!sig->params [i])
+                       goto fail;
        }
 
        if (sig->call_convention == MONO_CALL_VARARG && sig->sentinelpos == -1)
@@ -772,6 +793,10 @@ decode_signature_with_target (MonoAotModule *module, MonoMethodSignature *target
        *endbuf = p;
 
        return sig;
+fail:
+       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+       g_free (sig);
+       return NULL;
 }
 
 static MonoMethodSignature*
@@ -815,15 +840,18 @@ typedef struct {
  * 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)
 {
        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;
@@ -835,8 +863,9 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
        }
 
        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) {
@@ -854,8 +883,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                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);
@@ -866,7 +894,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        break;
                }
                case MONO_WRAPPER_PROXY_ISINST: {
-                       MonoClass *klass = decode_klass_ref (module, p, &p);
+                       MonoClass *klass = decode_klass_ref (module, p, &p, error);
                        if (!klass)
                                return FALSE;
                        ref->method = mono_marshal_get_proxy_cancast (klass);
@@ -876,7 +904,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                case MONO_WRAPPER_LDFLDA:
                case MONO_WRAPPER_STFLD:
                case MONO_WRAPPER_ISINST: {
-                       MonoClass *klass = decode_klass_ref (module, p, &p);
+                       MonoClass *klass = decode_klass_ref (module, p, &p, error);
                        if (!klass)
                                return FALSE;
                        if (wrapper_type == MONO_WRAPPER_LDFLD)
@@ -887,8 +915,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                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:
@@ -902,8 +932,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        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: {
@@ -935,13 +967,13 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                        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);
@@ -951,8 +983,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        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);
-                               
+                               MonoClass *klass = decode_klass_ref (module, p, &p, error);
                                if (!klass)
                                        return FALSE;
 
@@ -971,14 +1002,12 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                        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);
@@ -997,7 +1026,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                        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;
                }
@@ -1012,7 +1042,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        } 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;
 
@@ -1042,8 +1072,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                        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;
 
@@ -1064,8 +1093,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                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: {
@@ -1080,15 +1111,13 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                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);
@@ -1119,7 +1148,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                MonoClass *klass;
                                MonoMethod *invoke, *wrapper;
 
-                               klass = decode_klass_ref (module, p, &p);
+                               klass = decode_klass_ref (module, p, &p, error);
                                if (!klass)
                                        return FALSE;
 
@@ -1181,10 +1210,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        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);
+                       klass = decode_klass_ref (module, p, &p, error);
                        if (!klass)
                                return FALSE;
                        ref->method = mono_marshal_get_managed_wrapper (m, klass, 0);
@@ -1197,11 +1226,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                image_index = decode_value (p, &p);
                ref->token = decode_value (p, &p);
 
-               image = load_image (module, image_index, TRUE);
+               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;
 
@@ -1209,7 +1237,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                 * These methods do not have a token which resolves them, so we 
                 * resolve them immediately.
                 */
-               klass = decode_klass_ref (module, p, &p);
+               klass = decode_klass_ref (module, p, &p, error);
                if (!klass)
                        return FALSE;
 
@@ -1219,15 +1247,14 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                image_index = decode_value (p, &p);
                ref->token = decode_value (p, &p);
 
-               image = load_image (module, image_index, TRUE);
+               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));
 
@@ -1235,25 +1262,25 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        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))
+               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);
+               klass = decode_klass_ref (module, p, &p, error);
                if (!klass)
                        return FALSE;
                method_type = decode_value (p, &p);
@@ -1274,7 +1301,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        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) {
@@ -1284,7 +1312,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
 
                ref->token = MONO_TOKEN_METHOD_DEF | (value & 0xffffff);
 
-               image = load_image (module, image_index, TRUE);
+               image = load_image (module, image_index, error);
                if (!image)
                        return FALSE;
        }
@@ -1297,9 +1325,9 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
 }
 
 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);
 }
 
 /*
@@ -1308,30 +1336,27 @@ decode_method_ref (MonoAotModule *module, MethodRef *ref, guint8 *buf, guint8 **
  *   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
@@ -1962,7 +1987,10 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                                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);
@@ -2244,8 +2272,11 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        }
 #endif
        if (do_load_image) {
-               for (i = 0; i < amodule->image_table_len; ++i)
-                       load_image (amodule, i, FALSE);
+               for (i = 0; i < amodule->image_table_len; ++i) {
+                       MonoError error;
+                       load_image (amodule, i, &error);
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+               }
        }
 
        if (amodule->out_of_date) {
@@ -2322,6 +2353,7 @@ mono_aot_cleanup (void)
 static gboolean
 decode_cached_class_info (MonoAotModule *module, MonoCachedClassInfo *info, guint8 *buf, guint8 **endbuf)
 {
+       MonoError error;
        guint32 flags;
        MethodRef ref;
        gboolean res;
@@ -2342,13 +2374,15 @@ decode_cached_class_info (MonoAotModule *module, MonoCachedClassInfo *info, guin
        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;
@@ -2368,6 +2402,7 @@ decode_cached_class_info (MonoAotModule *module, MonoCachedClassInfo *info, guin
 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;
@@ -2387,10 +2422,13 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl
        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)
@@ -2799,6 +2837,7 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain,
                                                         MonoMethod *method, guint8* ex_info,
                                                         guint8 *code, guint32 code_len)
 {
+       MonoError error;
        int i, buf_len, num_clauses, len;
        MonoJitInfo *jinfo;
        MonoJitInfoFlags flags = JIT_INFO_NONE;
@@ -2872,8 +2911,10 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain,
 
                        ei->flags = decode_value (p, &p);
 
-                       if (decode_value (p, &p))
-                               ei->data.catch_class = decode_klass_ref (amodule, p, &p);
+                       if (decode_value (p, &p)) {
+                               ei->data.catch_class = decode_klass_ref (amodule, p, &p, &error);
+                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                       }
 
                        ei->clause_index = i;
 
@@ -2921,10 +2962,12 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain,
                                int len = decode_value (p, &p);
 
                                if (len > 0) {
-                                       if (async)
+                                       if (async) {
                                                p += len;
-                                       else
-                                               ei->data.catch_class = decode_klass_ref (amodule, p, &p);
+                                       } else {
+                                               ei->data.catch_class = decode_klass_ref (amodule, p, &p, &error);
+                                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                                       }
                                }
                        }
 
@@ -3010,12 +3053,14 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain,
                }
 
                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;
@@ -3172,6 +3217,7 @@ msort_method_addresses (gpointer *array, int *indexes, int len)
 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;
@@ -3325,7 +3371,8 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
                                }
 
                                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;
@@ -3388,6 +3435,7 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
 static gboolean
 decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guint8 *buf, guint8 **endbuf)
 {
+       MonoError error;
        guint8 *p = buf;
        gpointer *table;
        MonoImage *image;
@@ -3397,12 +3445,14 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_METHOD:
        case MONO_PATCH_INFO_METHOD_JUMP:
        case MONO_PATCH_INFO_ICALL_ADDR:
+       case MONO_PATCH_INFO_ICALL_ADDR_CALL:
        case MONO_PATCH_INFO_METHOD_RGCTX:
        case MONO_PATCH_INFO_METHOD_CODE_SLOT: {
                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;
 
@@ -3434,7 +3484,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        }
        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;
@@ -3443,24 +3494,28 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_IID:
        case MONO_PATCH_INFO_ADJUSTED_IID:
                /* Shared */
-               ji->data.klass = decode_klass_ref (aot_module, p, &p);
+               ji->data.klass = decode_klass_ref (aot_module, p, &p, &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                if (!ji->data.klass)
                        goto cleanup;
                break;
        case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
                ji->data.del_tramp = (MonoDelegateClassMethodPair *)mono_mempool_alloc0 (mp, sizeof (MonoDelegateClassMethodPair));
-               ji->data.del_tramp->klass = decode_klass_ref (aot_module, p, &p);
+               ji->data.del_tramp->klass = decode_klass_ref (aot_module, p, &p, &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                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;
                }
                ji->data.del_tramp->is_virtual = decode_value (p, &p) ? TRUE : FALSE;
                break;
        case MONO_PATCH_INFO_IMAGE:
-               ji->data.image = load_image (aot_module, decode_value (p, &p), TRUE);
+               ji->data.image = load_image (aot_module, decode_value (p, &p), &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                if (!ji->data.image)
                        goto cleanup;
                break;
@@ -3500,7 +3555,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                break;
        }
        case MONO_PATCH_INFO_LDSTR:
-               image = load_image (aot_module, decode_value (p, &p), TRUE);
+               image = load_image (aot_module, decode_value (p, &p), &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                if (!image)
                        goto cleanup;
                ji->data.token = mono_jump_info_token_new (mp, image, MONO_TOKEN_STRING + decode_value (p, &p));
@@ -3510,20 +3566,23 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_LDTOKEN:
        case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
                /* Shared */
-               image = load_image (aot_module, decode_value (p, &p), TRUE);
+               image = load_image (aot_module, decode_value (p, &p), &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                if (!image)
                        goto cleanup;
                ji->data.token = mono_jump_info_token_new (mp, image, decode_value (p, &p));
 
                ji->data.token->has_context = decode_value (p, &p);
                if (ji->data.token->has_context) {
-                       gboolean res = decode_generic_context (aot_module, &ji->data.token->context, p, &p);
+                       gboolean res = decode_generic_context (aot_module, &ji->data.token->context, p, &p, &error);
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        if (!res)
                                goto cleanup;
                }
                break;
        case MONO_PATCH_INFO_EXC_NAME:
-               ji->data.klass = decode_klass_ref (aot_module, p, &p);
+               ji->data.klass = decode_klass_ref (aot_module, p, &p, &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                if (!ji->data.klass)
                        goto cleanup;
                ji->data.name = ji->data.klass->name;
@@ -3552,11 +3611,12 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
 
                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)
@@ -3579,8 +3639,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                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;
@@ -3589,8 +3649,9 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                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);
@@ -3600,7 +3661,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                        template_->info_type = (MonoRgctxInfoType)decode_value (p, &p);
                        switch (mini_rgctx_info_type_to_patch_info_type (template_->info_type)) {
                        case MONO_PATCH_INFO_CLASS: {
-                               MonoClass *klass = decode_klass_ref (aot_module, p, &p);
+                               MonoClass *klass = decode_klass_ref (aot_module, p, &p, &error);
+                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                                if (!klass)
                                        goto cleanup;
                                template_->data = &klass->byval_arg;
@@ -3633,10 +3695,11 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_VIRT_METHOD: {
                MonoJumpInfoVirtMethod *info = (MonoJumpInfoVirtMethod *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoVirtMethod));
 
-               info->klass = decode_klass_ref (aot_module, p, &p);
-               g_assert (info->klass);
-               info->method = decode_resolve_method_ref (aot_module, p, &p);
-               g_assert (info->method);
+               info->klass = decode_klass_ref (aot_module, p, &p, &error);
+               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;
@@ -3915,6 +3978,7 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM
 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;
@@ -3950,7 +4014,8 @@ find_aot_method_in_amodule (MonoAotModule *amodule, MonoMethod *method, guint32
                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 ().
@@ -4092,7 +4157,9 @@ init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, M
 
        //does the method's class has a cctor?
        if (decode_value (p, &p) == 1)
-               klass_to_run_ctor = decode_klass_ref (amodule, p, &p);
+               klass_to_run_ctor = decode_klass_ref (amodule, p, &p, error);
+       if (!is_ok (error))
+               return FALSE;
 
        //FIXME old code would use the class from @method if not null and ignore the one encoded. I don't know if we need to honor that -- @kumpera
        if (method)
@@ -5155,7 +5222,9 @@ get_new_trampoline_from_page (int tramp_type)
                /* allocate two contiguous pages of memory: the first page will contain the data (like a local constant pool)
                 * while the second will contain the trampolines.
                 */
-               ret = vm_allocate (mach_task_self (), &addr, psize * 2, VM_FLAGS_ANYWHERE);
+               do {
+                       ret = vm_allocate (mach_task_self (), &addr, psize * 2, VM_FLAGS_ANYWHERE);
+               } while (ret == KERN_ABORTED);
                if (ret != KERN_SUCCESS) {
                        g_error ("Cannot allocate memory for trampolines: %d", ret);
                        break;