Use g_assertion_message instead of exit to kill an iOS app.
[mono.git] / mono / mini / aot-runtime.c
index e32d6e49bc591f36abe744c2d64c4bd251a38fc6..0a51626141dfc6f64b9af4413a05d1a0e7671186 100644 (file)
@@ -415,35 +415,52 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
        }
        case MONO_AOT_TYPEREF_VAR: {
                MonoType *t;
-               MonoGenericContainer *container;
+               MonoGenericContainer *container = NULL;
                int type = decode_value (p, &p);
                int num = decode_value (p, &p);
-               gboolean is_method = decode_value (p, &p);
+               gboolean has_container = decode_value (p, &p);
+               int serial = 0;
 
-               if (is_method) {
-                       MonoMethod *method_def;
-                       g_assert (type == MONO_TYPE_MVAR);
-                       method_def = decode_resolve_method_ref (module, p, &p);
-                       if (!method_def)
-                               return NULL;
-
-                       container = mono_method_get_generic_container (method_def);
+               if (has_container) {
+                       gboolean is_method = decode_value (p, &p);
+                       
+                       if (is_method) {
+                               MonoMethod *method_def;
+                               g_assert (type == MONO_TYPE_MVAR);
+                               method_def = decode_resolve_method_ref (module, p, &p);
+                               if (!method_def)
+                                       return NULL;
+
+                               container = mono_method_get_generic_container (method_def);
+                       } else {
+                               MonoClass *class_def;
+                               g_assert (type == MONO_TYPE_VAR);
+                               class_def = decode_klass_ref (module, p, &p);
+                               if (!class_def)
+                                       return NULL;
+                               container = class_def->generic_container;
+                       }
                } else {
-                       MonoClass *class_def;
-                       g_assert (type == MONO_TYPE_VAR);
-                       class_def = decode_klass_ref (module, p, &p);
-                       if (!class_def)
-                               return NULL;
-
-                       container = class_def->generic_container;
+                       serial = decode_value (p, &p);
                }
 
-               g_assert (container);
-
                // FIXME: Memory management
                t = g_new0 (MonoType, 1);
                t->type = type;
-               t->data.generic_param = mono_generic_container_get_param (container, num);
+
+               if (container) {
+                       t->data.generic_param = mono_generic_container_get_param (container, num);
+                       g_assert (serial == 0);
+               } else {
+                       /* Anonymous */
+                       MonoGenericParam *par = (MonoGenericParam*)g_new0 (MonoGenericParamFull, 1);
+                       par->num = num;
+                       par->serial = serial;
+                       // FIXME:
+                       par->image = mono_defaults.corlib;
+                       t->data.generic_param = par;
+               }
 
                // FIXME: Maybe use types directly to avoid
                // the overhead of creating MonoClass-es
@@ -804,7 +821,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                kind = decode_value (p, &p);
 
                                /* Can't decode this */
-                               g_assert (target);
+                               if (!target)
+                                       return FALSE;
                                if (target->wrapper_type == MONO_WRAPPER_STELEMREF) {
                                        info = mono_marshal_get_wrapper_info (target);
 
@@ -840,7 +858,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                if (!klass)
                                        return FALSE;
 
-                               g_assert (target);
+                               if (!target)
+                                       return FALSE;
                                if (klass != target->klass)
                                        return FALSE;
 
@@ -891,7 +910,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                if (!m)
                                        return FALSE;
 
-                               g_assert (target);
+                               if (!target)
+                                       return FALSE;
                                g_assert (target->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED);
 
                                info = mono_marshal_get_wrapper_info (target);
@@ -908,7 +928,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        char *name;
 
                        if (subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER) {
-                               g_assert (target);
+                               if (!target)
+                                       return FALSE;
 
                                name = (char*)p;
                                if (strcmp (target->name, name) != 0)
@@ -921,7 +942,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                        return FALSE;
 
                                /* This should only happen when looking for an extra method */
-                               g_assert (target);
+                               if (!target)
+                                       return FALSE;
                                if (mono_marshal_method_from_wrapper (target) == m)
                                        ref->method = target;
                                else
@@ -943,7 +965,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                case MONO_WRAPPER_RUNTIME_INVOKE: {
                        int subtype = decode_value (p, &p);
 
-                       g_assert (target);
+                       if (!target)
+                               return FALSE;
 
                        if (subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_DYNAMIC) {
                                if (strcmp (target->name, "runtime_invoke_dynamic") != 0)
@@ -978,7 +1001,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                         * These wrappers are associated with a signature, not with a method.
                         * Since we can't decode them into methods, they need a target method.
                         */
-                       g_assert (target);
+                       if (!target)
+                               return FALSE;
 
                        if (sig_matches_target (module, target, p, &p))
                                ref->method = target;
@@ -1312,6 +1336,7 @@ check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, char **out_msg)
        gboolean usable = TRUE;
        gboolean full_aot;
        guint8 *blob;
+       guint32 excluded_cpu_optimizations;
 
        if (strcmp (assembly->image->guid, info->assembly_guid)) {
                msg = g_strdup_printf ("doesn't match assembly");
@@ -1351,6 +1376,17 @@ check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, char **out_msg)
                usable = FALSE;
        }
 
+       mono_arch_cpu_optimizations (&excluded_cpu_optimizations);
+       if (info->opts & excluded_cpu_optimizations) {
+               msg = g_strdup_printf ("compiled with unsupported CPU optimizations");
+               usable = FALSE;
+       }
+
+       if (!mono_aot_only && (info->simd_opts & ~mono_arch_cpu_enumerate_simd_versions ())) {
+               msg = g_strdup_printf ("compiled with unsupported SIMD extensions");
+               usable = FALSE;
+       }
+
        blob = info->blob;
 
        if (info->gc_name_index != -1) {
@@ -2020,7 +2056,7 @@ decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain,
 
        if (amodule->thumb_end && (guint8*)code_start < amodule->thumb_end)
                /* Clear thumb flag */
-               code_start = (char*)(((mgreg_t)code_start) & ~1);
+               code_start = (guint8*)(((mgreg_t)code_start) & ~1);
 
        fde = amodule->mono_eh_frame + table [(pos * 2) + 1];   
        /* This won't overflow because there is +1 entry in the table */
@@ -2464,7 +2500,7 @@ MonoJitInfo *
 mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
 {
        int pos, left, right, offset, offset1, offset2, code_len;
-       int method_index, table_len, is_wrapper;
+       int method_index, table_len;
        guint32 token;
        MonoAotModule *amodule = image->aot_module;
        MonoMethod *method;
@@ -2502,15 +2538,19 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
                for (i = 0; i < offsets_len -1; ++i)
                        g_assert (code_offsets [(i * 2)] <= code_offsets [(i + 1) * 2]);
 
+               amodule->sorted_code_offsets_len = offsets_len;
+               mono_memory_barrier ();
                if (InterlockedCompareExchangePointer ((gpointer*)&amodule->sorted_code_offsets, code_offsets, NULL) != NULL)
                        /* Somebody got in before us */
                        g_free (code_offsets);
-               amodule->sorted_code_offsets_len = offsets_len;
        }
 
        code_offsets = amodule->sorted_code_offsets;
        offsets_len = amodule->sorted_code_offsets_len;
 
+       if (offsets_len > 0 && (offset < code_offsets [0] || offset >= (amodule->code_end - amodule->code)))
+               return NULL;
+
        /* Binary search in the sorted_code_offsets table */
        left = 0;
        right = offsets_len;
@@ -2582,10 +2622,10 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
                        }
 
                        p = amodule->blob + table [(pos * 2) + 1];
-                       is_wrapper = decode_value (p, &p);
-                       g_assert (!is_wrapper);
                        method = decode_resolve_method_ref (amodule, p, &p);
-                       g_assert (method);
+                       if (!method)
+                               /* Happens when a random address is passed in which matches a not-yey called wrapper encoded using its name */
+                               return NULL;
                } else {
                        token = mono_metadata_make_token (MONO_TABLE_METHOD, method_index + 1);
                        method = mono_get_method (image, token, NULL);