guint8 *plt_end;
guint8 *blob;
gint32 *code_offsets;
+#ifdef MONOTOUCH
+ gpointer *method_addresses;
+#endif
/* This contains <offset, index> pairs sorted by offset */
/* This is needed because LLVM emitted methods can be in any order */
gint32 *sorted_code_offsets;
}
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);
-
- 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;
+ gboolean has_container = decode_value (p, &p);
+ int serial = 0;
- 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
usable = FALSE;
}
- mono_arch_cpu_optimizazions (&excluded_cpu_optimizations);
- if (!(excluded_cpu_optimizations & info->opts)) {
+ 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) {
}
amodule->code_offsets = info->code_offsets;
+#ifdef MONOTOUCH
+ amodule->method_addresses = info->method_addresses;
+#endif
amodule->code = info->methods;
#ifdef TARGET_ARM
/* Mask out thumb interop bit */
amodule->trampolines [MONO_AOT_TRAMP_IMT_THUNK] = info->imt_thunks;
amodule->thumb_end = info->thumb_end;
+#ifdef MONOTOUCH
+ if (info->flags & MONO_AOT_FILE_FLAG_DIRECT_METHOD_ADDRESSES) {
+ /* Compute code_offsets from the method addresses */
+ amodule->code_offsets = g_malloc0 (amodule->info.nmethods * sizeof (gint32));
+ for (i = 0; i < amodule->info.nmethods; ++i) {
+ if (!amodule->method_addresses [i])
+ amodule->code_offsets [i] = 0xffffffff;
+ else
+ amodule->code_offsets [i] = (char*)amodule->method_addresses [i] - (char*)amodule->code;
+ }
+ }
+#endif
+
if (make_unreadable) {
#ifndef TARGET_WIN32
guint8 *addr;
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;
}
p = amodule->blob + table [(pos * 2) + 1];
- is_wrapper = decode_value (p, &p);
- if (is_wrapper)
- /* Happens when a random address is passed in which matches a not-yey called wrapper encoded using its name */
- return NULL;
- g_assert (!is_wrapper);
method = decode_resolve_method_ref (amodule, p, &p);
if (!method)
- /* Ditto */
+ /* 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);
info = &amodule->blob [mono_aot_get_offset (amodule->method_info_offsets, method_index)];
- if (amodule->thumb_end && code < amodule->thumb_end) {
+ if (amodule->thumb_end && code < amodule->thumb_end && ((amodule->info.flags & MONO_AOT_FILE_FLAG_DIRECT_METHOD_ADDRESSES) == 0)) {
/* Convert this into a thumb address */
g_assert ((amodule->code_offsets [method_index] & 0x1) == 0);
code = &amodule->code [amodule->code_offsets [method_index] + 1];
g_assert_not_reached ();
#endif
+#ifdef MONOTOUCH
+ while (target != NULL) {
+ if ((target >= (guint8*)(amodule->plt)) && (target < (guint8*)(amodule->plt_end)))
+ return target;
+
+ // Add 4 since mono_arch_get_call_target assumes we're passing
+ // the instruction after the actual branch instruction.
+ target = mono_arch_get_call_target (target + 4);
+ }
+
+ return NULL;
+#else
if ((target >= (guint8*)(amodule->plt)) && (target < (guint8*)(amodule->plt_end)))
return target;
else
return NULL;
+#endif
}
/*
*out_amodule = amodule;
- if (amodule->trampoline_index [tramp_type] == amodule->info.num_trampolines [tramp_type])
- g_error ("Ran out of trampolines of type %d in '%s' (%d)\n", tramp_type, image->name, amodule->info.num_trampolines [tramp_type]);
-
+ if (amodule->trampoline_index [tramp_type] == amodule->info.num_trampolines [tramp_type]) {
+ g_error ("Ran out of trampolines of type %d in '%s' (%d)%s\n",
+ tramp_type, image->name, amodule->info.num_trampolines [tramp_type],
+#ifdef MONOTOUCH
+ ". See http://docs.xamarin.com/ios/troubleshooting for instruction on how to fix this condition"
+#else
+ ""
+#endif
+ );
+ }
index = amodule->trampoline_index [tramp_type] ++;
mono_aot_unlock ();