#include "config.h"
#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <fcntl.h>
#include <string.h>
#ifndef PLATFORM_WIN32
#include <mono/metadata/assembly.h>
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/marshal.h>
+#include <mono/metadata/gc-internal.h>
#include <mono/utils/mono-logger.h>
#include "mono/utils/mono-compiler.h"
#include "mini.h"
+#include "version.h"
#ifndef DISABLE_AOT
/* Pointer to the Global Offset Table */
gpointer *got;
guint32 got_size;
+ GHashTable *name_cache;
MonoAssemblyName *image_names;
char **image_guids;
MonoImage **image_table;
static inline gboolean
is_got_patch (MonoJumpInfoType patch_type)
{
-#ifdef __x86_64__
- return TRUE;
-#elif defined(__i386__)
return TRUE;
-#else
- return FALSE;
-#endif
}
/*****************************************************/
}
static MonoClass*
-decode_klass_info (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
{
MonoImage *image;
- MonoClass *klass;
- guint32 token, rank, image_index;
+ MonoClass *klass, *eklass;
+ guint32 token, rank;
token = decode_value (buf, &buf);
if (token == 0) {
*endbuf = buf;
return NULL;
}
- image_index = decode_value (buf, &buf);
- image = load_image (module, image_index);
- if (!image)
- return NULL;
- if (mono_metadata_token_code (token) == 0) {
+ if (mono_metadata_token_table (token) == 0) {
+ image = load_image (module, decode_value (buf, &buf));
+ if (!image)
+ return NULL;
klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF + token);
- } else {
- token = MONO_TOKEN_TYPE_DEF + decode_value (buf, &buf);
+ } else if (mono_metadata_token_table (token) == MONO_TABLE_TYPESPEC) {
+ if (token == MONO_TOKEN_TYPE_SPEC) {
+ MonoClass *gclass;
+ int i;
+ MonoGenericContext ctx;
+ MonoGenericInst inst;
+
+ gclass = decode_klass_ref (module, buf, &buf);
+ g_assert (gclass->generic_container);
+
+ memset (&ctx, 0, sizeof (ctx));
+ memset (&inst, 0, sizeof (inst));
+ ctx.class_inst = &inst;
+ inst.type_argc = decode_value (buf, &buf);
+ inst.type_argv = g_new0 (MonoType*, inst.type_argc);
+ for (i = 0; i < inst.type_argc; ++i) {
+ MonoClass *pclass = decode_klass_ref (module, buf, &buf);
+ if (!pclass) {
+ g_free (inst.type_argv);
+ return NULL;
+ }
+ inst.type_argv [i] = &pclass->byval_arg;
+ }
+ klass = mono_class_from_mono_type (mono_class_inflate_generic_type (&gclass->byval_arg, &ctx));
+ } else {
+ image = load_image (module, decode_value (buf, &buf));
+ if (!image)
+ return NULL;
+ klass = mono_class_get (image, token);
+ }
+ } else if (token == MONO_TOKEN_TYPE_DEF) {
+ /* Array */
+ image = load_image (module, decode_value (buf, &buf));
+ if (!image)
+ return NULL;
rank = decode_value (buf, &buf);
- klass = mono_class_get (image, token);
- g_assert (klass);
- klass = mono_array_class_get (klass, rank);
+ eklass = decode_klass_ref (module, buf, &buf);
+ klass = mono_array_class_get (eklass, rank);
+ } else {
+ g_assert_not_reached ();
}
g_assert (klass);
mono_class_init (klass);
static MonoClassField*
decode_field_info (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
{
- MonoClass *klass = decode_klass_info (module, buf, &buf);
+ MonoClass *klass = decode_klass_ref (module, buf, &buf);
guint32 token;
if (!klass)
MonoImage *image;
value = decode_value (buf, &buf);
- *endbuf = buf;
image_index = value >> 24;
*token = MONO_TOKEN_METHOD_DEF | (value & 0xffffff);
+ if (image_index == 255) {
+ /* Methodspec */
+ image_index = decode_value (buf, &buf);
+ *token = decode_value (buf, &buf);
+ }
+
+ *endbuf = buf;
+
image = load_image (module, image_index);
if (!image)
return NULL;
* - invoking a new mono process is a security risk
* - recompile the AOT module if one of its dependencies changes
*/
-static GModule*
+static MonoDl*
load_aot_module_from_cache (MonoAssembly *assembly, char **aot_name)
{
char *fname, *cmd, *tmp2, *aot_options;
const char *home;
- GModule *module;
+ MonoDl *module;
gboolean res;
gchar *out, *err;
gint exit_status;
g_free (tmp2);
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT trying to load from cache: '%s'.", fname);
- module = g_module_open (fname, G_MODULE_BIND_LAZY);
+ module = mono_dl_open (fname, MONO_DL_LAZY, NULL);
if (!module) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT not found.");
}
}
- module = g_module_open (fname, G_MODULE_BIND_LAZY);
+ module = mono_dl_open (fname, MONO_DL_LAZY, NULL);
g_free (aot_options);
}
gboolean usable = TRUE;
char *saved_guid = NULL;
char *aot_version = NULL;
+ char *runtime_version;
char *opt_flags = NULL;
gpointer *plt_jump_table_addr = NULL;
guint32 *plt_jump_table_size = NULL;
gpointer *got_addr = NULL;
gpointer *got = NULL;
guint32 *got_size_ptr = NULL;
+ int i;
if (mono_compile_aot)
return;
if (use_aot_cache)
assembly->aot_module = load_aot_module_from_cache (assembly, &aot_name);
else {
+ char *err;
aot_name = g_strdup_printf ("%s%s", assembly->image->name, SHARED_EXT);
- assembly->aot_module = g_module_open (aot_name, G_MODULE_BIND_LAZY);
+ assembly->aot_module = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
if (!assembly->aot_module) {
- mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT failed to load AOT module %s: %s\n", aot_name, g_module_error ());
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT failed to load AOT module %s: %s\n", aot_name, err);
+ g_free (err);
}
}
return;
}
- g_module_symbol (assembly->aot_module, "mono_assembly_guid", (gpointer *) &saved_guid);
- g_module_symbol (assembly->aot_module, "mono_aot_version", (gpointer *) &aot_version);
- g_module_symbol (assembly->aot_module, "mono_aot_opt_flags", (gpointer *)&opt_flags);
+ mono_dl_symbol (assembly->aot_module, "mono_assembly_guid", (gpointer *) &saved_guid);
+ mono_dl_symbol (assembly->aot_module, "mono_aot_version", (gpointer *) &aot_version);
+ mono_dl_symbol (assembly->aot_module, "mono_aot_opt_flags", (gpointer *)&opt_flags);
+ mono_dl_symbol (assembly->aot_module, "mono_runtime_version", (gpointer *)&runtime_version);
if (!aot_version || strcmp (aot_version, MONO_AOT_FILE_VERSION)) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module %s has wrong file format version (expected %s got %s)\n", aot_name, MONO_AOT_FILE_VERSION, aot_version);
}
}
+ if (!runtime_version || ((strlen (runtime_version) > 0 && strcmp (runtime_version, FULL_VERSION)))) {
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module %s is compiled against runtime version %s while this runtime has version %s.\n", aot_name, runtime_version, FULL_VERSION);
+ usable = FALSE;
+ }
+
if (!usable) {
g_free (aot_name);
- g_module_close (assembly->aot_module);
+ mono_dl_close (assembly->aot_module);
assembly->aot_module = NULL;
return;
}
- g_module_symbol (assembly->aot_module, "got_addr", (gpointer *)&got_addr);
+ mono_dl_symbol (assembly->aot_module, "got_addr", (gpointer *)&got_addr);
g_assert (got_addr);
got = (gpointer*)*got_addr;
g_assert (got);
- g_module_symbol (assembly->aot_module, "got_size", (gpointer *)&got_size_ptr);
+ mono_dl_symbol (assembly->aot_module, "got_size", (gpointer *)&got_size_ptr);
g_assert (got_size_ptr);
info = g_new0 (MonoAotModule, 1);
guint32 table_len, i;
char *table = NULL;
- g_module_symbol (assembly->aot_module, "mono_image_table", (gpointer *)&table);
+ mono_dl_symbol (assembly->aot_module, "mono_image_table", (gpointer *)&table);
g_assert (table);
table_len = *(guint32*)table;
}
/* Read method and method_info tables */
- g_module_symbol (assembly->aot_module, "method_offsets", (gpointer*)&info->code_offsets);
- g_module_symbol (assembly->aot_module, "methods", (gpointer*)&info->code);
- g_module_symbol (assembly->aot_module, "methods_end", (gpointer*)&info->code_end);
- g_module_symbol (assembly->aot_module, "method_info_offsets", (gpointer*)&info->method_info_offsets);
- g_module_symbol (assembly->aot_module, "method_info", (gpointer*)&info->method_info);
- g_module_symbol (assembly->aot_module, "ex_info_offsets", (gpointer*)&info->ex_info_offsets);
- g_module_symbol (assembly->aot_module, "ex_info", (gpointer*)&info->ex_info);
- g_module_symbol (assembly->aot_module, "method_order", (gpointer*)&info->method_order);
- g_module_symbol (assembly->aot_module, "method_order_end", (gpointer*)&info->method_order_end);
- g_module_symbol (assembly->aot_module, "class_info", (gpointer*)&info->class_info);
- g_module_symbol (assembly->aot_module, "class_info_offsets", (gpointer*)&info->class_info_offsets);
- g_module_symbol (assembly->aot_module, "class_name_table", (gpointer *)&info->class_name_table);
- g_module_symbol (assembly->aot_module, "got_info", (gpointer*)&info->got_info);
- g_module_symbol (assembly->aot_module, "got_info_offsets", (gpointer*)&info->got_info_offsets);
- g_module_symbol (assembly->aot_module, "mem_end", (gpointer*)&info->mem_end);
+ mono_dl_symbol (assembly->aot_module, "method_offsets", (gpointer*)&info->code_offsets);
+ mono_dl_symbol (assembly->aot_module, "methods", (gpointer*)&info->code);
+ mono_dl_symbol (assembly->aot_module, "methods_end", (gpointer*)&info->code_end);
+ mono_dl_symbol (assembly->aot_module, "method_info_offsets", (gpointer*)&info->method_info_offsets);
+ mono_dl_symbol (assembly->aot_module, "method_info", (gpointer*)&info->method_info);
+ mono_dl_symbol (assembly->aot_module, "ex_info_offsets", (gpointer*)&info->ex_info_offsets);
+ mono_dl_symbol (assembly->aot_module, "ex_info", (gpointer*)&info->ex_info);
+ mono_dl_symbol (assembly->aot_module, "method_order", (gpointer*)&info->method_order);
+ mono_dl_symbol (assembly->aot_module, "method_order_end", (gpointer*)&info->method_order_end);
+ mono_dl_symbol (assembly->aot_module, "class_info", (gpointer*)&info->class_info);
+ mono_dl_symbol (assembly->aot_module, "class_info_offsets", (gpointer*)&info->class_info_offsets);
+ mono_dl_symbol (assembly->aot_module, "class_name_table", (gpointer *)&info->class_name_table);
+ mono_dl_symbol (assembly->aot_module, "got_info", (gpointer*)&info->got_info);
+ mono_dl_symbol (assembly->aot_module, "got_info_offsets", (gpointer*)&info->got_info_offsets);
+ mono_dl_symbol (assembly->aot_module, "mem_end", (gpointer*)&info->mem_end);
info->mem_begin = info->code;
- g_module_symbol (assembly->aot_module, "plt", (gpointer*)&info->plt);
- g_module_symbol (assembly->aot_module, "plt_end", (gpointer*)&info->plt_end);
- g_module_symbol (assembly->aot_module, "plt_info", (gpointer*)&info->plt_info);
+ mono_dl_symbol (assembly->aot_module, "plt", (gpointer*)&info->plt);
+ mono_dl_symbol (assembly->aot_module, "plt_end", (gpointer*)&info->plt_end);
+ mono_dl_symbol (assembly->aot_module, "plt_info", (gpointer*)&info->plt_info);
- g_module_symbol (assembly->aot_module, "plt_jump_table_addr", (gpointer *)&plt_jump_table_addr);
+ mono_dl_symbol (assembly->aot_module, "plt_jump_table_addr", (gpointer *)&plt_jump_table_addr);
g_assert (plt_jump_table_addr);
info->plt_jump_table = (guint8*)*plt_jump_table_addr;
g_assert (info->plt_jump_table);
- g_module_symbol (assembly->aot_module, "plt_jump_table_size", (gpointer *)&plt_jump_table_size);
+ mono_dl_symbol (assembly->aot_module, "plt_jump_table_size", (gpointer *)&plt_jump_table_size);
g_assert (plt_jump_table_size);
info->plt_jump_table_size = *plt_jump_table_size;
mono_jit_info_add_aot_module (assembly->image, info->code, info->code_end);
- mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT loaded AOT Module for %s.\n", assembly->image->name);
+ /*
+ * Since we store methoddef and classdef tokens when referring to methods/classes in
+ * referenced assemblies, we depend on the exact versions of the referenced assemblies.
+ * MS calls this 'hard binding'. This means we have to load all referenced assemblies
+ * non-lazily, since we can't handle out-of-date errors later.
+ */
+ for (i = 0; i < info->image_table_len; ++i)
+ load_image (info, i);
+
+ if (info->out_of_date)
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT Module %s is unusable because a dependency is out-of-date.\n", assembly->image->name);
+ else
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT loaded AOT Module for %s.\n", assembly->image->name);
}
void
guint32 flags;
info->vtable_size = decode_value (buf, &buf);
+ if (info->vtable_size == -1)
+ /* Generic type */
+ return FALSE;
flags = decode_value (buf, &buf);
info->ghcimpl = (flags >> 0) & 0x1;
info->has_finalize = (flags >> 1) & 0x1;
gboolean
mono_aot_init_vtable (MonoVTable *vtable)
{
+#ifdef MONO_ARCH_COMMON_VTABLE_TRAMPOLINE
int i;
MonoAotModule *aot_module;
MonoClass *klass = vtable->klass;
return FALSE;
}
+ mono_aot_unlock ();
+
//printf ("VT0: %s.%s %d\n", klass->name_space, klass->name, vtable_size);
for (i = 0; i < class_info.vtable_size; ++i) {
- guint32 image_index, token, value;
- MonoImage *image;
-#ifndef MONO_ARCH_HAVE_CREATE_TRAMPOLINE_FROM_TOKEN
- MonoMethod *m;
+ vtable->vtable [i] = mini_get_vtable_trampoline ();
+ }
+
+ return TRUE;
+#else
+ return FALSE;
#endif
+}
- vtable->vtable [i] = 0;
+gpointer
+mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
+{
+ int i;
+ MonoAotModule *aot_module;
+ MonoClass *klass = vtable->klass;
+ guint8 *info, *p;
+ MonoCachedClassInfo class_info;
+ gboolean err;
+ guint32 token;
+ MonoImage *image;
- value = decode_value (p, &p);
- if (!value)
- continue;
+ if (MONO_CLASS_IS_INTERFACE (klass) || klass->rank || !klass->image->assembly->aot_module)
+ return NULL;
- image_index = value >> 24;
- token = MONO_TOKEN_METHOD_DEF | (value & 0xffffff);
+ mono_aot_lock ();
- image = load_image (aot_module, image_index);
- if (!image) {
- mono_aot_unlock ();
- return FALSE;
- }
+ aot_module = (MonoAotModule*) g_hash_table_lookup (aot_modules, klass->image->assembly);
+ if (!aot_module) {
+ mono_aot_unlock ();
+ return NULL;
+ }
-#ifdef MONO_ARCH_HAVE_CREATE_TRAMPOLINE_FROM_TOKEN
- vtable->vtable [i] = mono_create_jit_trampoline_from_token (image, token);
-#else
- m = mono_get_method (image, token, NULL);
- g_assert (m);
+ info = &aot_module->class_info [aot_module->class_info_offsets [mono_metadata_token_index (klass->type_token) - 1]];
+ p = info;
- //printf ("M: %d %p %s\n", i, &(vtable->vtable [i]), mono_method_full_name (m, TRUE));
- vtable->vtable [i] = mono_create_jit_trampoline (m);
-#endif
+ err = decode_cached_class_info (aot_module, &class_info, p, &p);
+ if (!err) {
+ mono_aot_unlock ();
+ return NULL;
+ }
+
+ for (i = 0; i < slot; ++i)
+ decode_method_ref (aot_module, &token, p, &p);
+
+ image = decode_method_ref (aot_module, &token, p, &p);
+ if (!image) {
+ mono_aot_unlock ();
+ return NULL;
}
mono_aot_unlock ();
- return TRUE;
+ return mono_aot_get_method_from_token (domain, image, token);
}
gboolean
const char *name2, *name_space2;
MonoTableInfo *t;
guint32 cols [MONO_TYPEDEF_SIZE];
+ GHashTable *nspace_table;
if (!aot_modules)
return FALSE;
*klass = NULL;
+ /* First look in the cache */
+ if (!aot_module->name_cache)
+ aot_module->name_cache = g_hash_table_new (g_str_hash, g_str_equal);
+ nspace_table = g_hash_table_lookup (aot_module->name_cache, name_space);
+ if (nspace_table) {
+ *klass = g_hash_table_lookup (nspace_table, name);
+ if (*klass) {
+ mono_aot_unlock ();
+ return TRUE;
+ }
+ }
+
table_size = aot_module->class_name_table [0];
table = aot_module->class_name_table + 1;
if (!strcmp (name, name2) && !strcmp (name_space, name_space2)) {
mono_aot_unlock ();
*klass = mono_class_get (image, token);
+
+ /* Add to cache */
+ if (*klass) {
+ mono_aot_lock ();
+ nspace_table = g_hash_table_lookup (aot_module->name_cache, name_space);
+ if (!nspace_table) {
+ nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (aot_module->name_cache, (char*)name_space2, nspace_table);
+ }
+ g_hash_table_insert (nspace_table, (char*)name2, *klass);
+ mono_aot_unlock ();
+ }
return TRUE;
}
mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
{
MonoAssembly *ass = image->assembly;
- GModule *module = ass->aot_module;
+ MonoDl *module = ass->aot_module;
int pos, left, right, offset, offset1, offset2, last_offset, new_offset, page_index, method_index, table_len;
guint32 token;
MonoAotModule *aot_module;
switch (ji->type) {
case MONO_PATCH_INFO_METHOD:
case MONO_PATCH_INFO_METHODCONST:
- case MONO_PATCH_INFO_METHOD_JUMP: {
- guint32 image_index, token, value;
-
- value = decode_value (p, &p);
- image_index = value >> 24;
- token = MONO_TOKEN_METHOD_DEF | (value & 0xffffff);
+ case MONO_PATCH_INFO_METHOD_JUMP:
+ case MONO_PATCH_INFO_ICALL_ADDR: {
+ guint32 token;
- image = load_image (aot_module, image_index);
+ image = decode_method_ref (aot_module, &token, p, &p);
if (!image)
goto cleanup;
#ifdef MONO_ARCH_HAVE_CREATE_TRAMPOLINE_FROM_TOKEN
- if (ji->type == MONO_PATCH_INFO_METHOD) {
+ if ((ji->type == MONO_PATCH_INFO_METHOD) && (mono_metadata_token_table (token) == MONO_TABLE_METHOD)) {
ji->data.target = mono_create_jit_trampoline_from_token (image, token);
ji->type = MONO_PATCH_INFO_ABS;
}
wrapper_type = decode_value (p, &p);
+ ji->type = MONO_PATCH_INFO_METHOD;
+
switch (wrapper_type) {
case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK: {
guint32 image_index, token, value;
g_assert (ji->data.method);
mono_class_init (ji->data.method->klass);
- ji->type = MONO_PATCH_INFO_METHOD;
ji->data.method = mono_marshal_get_remoting_invoke_with_check (ji->data.method);
break;
}
case MONO_WRAPPER_PROXY_ISINST: {
- MonoClass *klass = decode_klass_info (aot_module, p, &p);
+ MonoClass *klass = decode_klass_ref (aot_module, p, &p);
if (!klass)
goto cleanup;
- ji->type = MONO_PATCH_INFO_METHOD;
ji->data.method = mono_marshal_get_proxy_cancast (klass);
break;
}
case MONO_WRAPPER_LDFLD:
case MONO_WRAPPER_LDFLDA:
case MONO_WRAPPER_STFLD:
- case MONO_WRAPPER_LDFLD_REMOTE:
- case MONO_WRAPPER_STFLD_REMOTE:
case MONO_WRAPPER_ISINST: {
- MonoClass *klass = decode_klass_info (aot_module, p, &p);
+ MonoClass *klass = decode_klass_ref (aot_module, p, &p);
if (!klass)
goto cleanup;
- ji->type = MONO_PATCH_INFO_METHOD;
if (wrapper_type == MONO_WRAPPER_LDFLD)
ji->data.method = mono_marshal_get_ldfld_wrapper (&klass->byval_arg);
else if (wrapper_type == MONO_WRAPPER_LDFLDA)
ji->data.method = mono_marshal_get_ldflda_wrapper (&klass->byval_arg);
else if (wrapper_type == MONO_WRAPPER_STFLD)
ji->data.method = mono_marshal_get_stfld_wrapper (&klass->byval_arg);
- else if (wrapper_type == MONO_WRAPPER_LDFLD_REMOTE)
- ji->data.method = mono_marshal_get_ldfld_remote_wrapper (klass);
- else if (wrapper_type == MONO_WRAPPER_STFLD_REMOTE)
- ji->data.method = mono_marshal_get_stfld_remote_wrapper (klass);
else if (wrapper_type == MONO_WRAPPER_ISINST)
ji->data.method = mono_marshal_get_isinst (klass);
else
g_assert_not_reached ();
break;
}
+ case MONO_WRAPPER_LDFLD_REMOTE:
+ ji->data.method = mono_marshal_get_ldfld_remote_wrapper (NULL);
+ break;
+ case MONO_WRAPPER_STFLD_REMOTE:
+ ji->data.method = mono_marshal_get_stfld_remote_wrapper (NULL);
+ break;
+ case MONO_WRAPPER_ALLOC: {
+ int atype = decode_value (p, &p);
+
+ ji->data.method = mono_gc_get_managed_allocator_by_type (atype);
+ break;
+ }
case MONO_WRAPPER_STELEMREF:
- ji->type = MONO_PATCH_INFO_METHOD;
ji->data.method = mono_marshal_get_stelemref ();
break;
default:
//printf ("HIT!\n");
} else {
guint8 *tmp = aot_module->got_info + aot_module->got_info_offsets [*got_offset];
- ji->data.klass = decode_klass_info (aot_module, tmp, &tmp);
+ ji->data.klass = decode_klass_ref (aot_module, tmp, &tmp);
if (!ji->data.klass)
goto cleanup;
}
break;
case MONO_PATCH_INFO_CLASS_INIT:
- ji->data.klass = decode_klass_info (aot_module, p, &p);
+ case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
+ ji->data.klass = decode_klass_ref (aot_module, p, &p);
if (!ji->data.klass)
goto cleanup;
break;
goto cleanup;
ji->data.token = mono_jump_info_token_new (mp, image, MONO_TOKEN_STRING + decode_value (p, &p));
break;
+ case MONO_PATCH_INFO_RVA:
case MONO_PATCH_INFO_DECLSEC:
case MONO_PATCH_INFO_LDTOKEN:
case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
}
break;
case MONO_PATCH_INFO_EXC_NAME:
- ji->data.klass = decode_klass_info (aot_module, p, &p);
+ ji->data.klass = decode_klass_ref (aot_module, p, &p);
if (!ji->data.klass)
goto cleanup;
ji->data.name = ji->data.klass->name;
{
MonoClass *klass = method->klass;
MonoAssembly *ass = klass->image->assembly;
- GModule *module = ass->aot_module;
+ MonoDl *module = ass->aot_module;
guint32 method_index = mono_metadata_token_index (method->token) - 1;
guint8 *code, *info;
MonoAotModule *aot_module;
if (aot_module->out_of_date)
return NULL;
+ if (method->is_inflated) {
+ if (!mono_method_is_generic_sharable_impl (method))
+ return NULL;
+ method = mono_method_get_declaring_generic_method (method);
+ }
+
if (aot_module->code_offsets [method_index] == 0xffffffff) {
if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT)) {
char *full_name = mono_method_full_name (method, TRUE);
MonoJitInfo *jinfo = NULL;
p = info;
- decode_klass_info (aot_module, p, &p);
+ decode_klass_ref (aot_module, p, &p);
if (!use_loaded_code) {
guint8 *code2;
int i, method_index, pindex, got_index, n_patches, used_strings;
gboolean keep_patches = TRUE;
guint8 *p;
- GModule *module = ass->aot_module;
+ MonoDl *module = ass->aot_module;
guint8 *code = NULL;
guint8 *info;
MonoAotModule *aot_module;
}
p = info;
- *klass = decode_klass_info (aot_module, p, &p);
+ *klass = decode_klass_ref (aot_module, p, &p);
if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT)) {
MonoMethod *method = mono_get_method (image, token, NULL);
}
/*
- * aot_dyn_resolve:
+ * mono_aot_plt_resolve:
*
* This function is called by the entries in the PLT to resolve the actual method that
* needs to be called. It returns a trampoline to the method and patches the PLT entry.
gpointer
mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code)
{
-#ifdef MONO_ARCH_HAVE_PIC_AOT
+#ifdef MONO_ARCH_AOT_SUPPORTED
guint8 *p, *target, *plt_entry;
MonoJumpInfo ji;
MonoAotModule *module = (MonoAotModule*)aot_module;
static void
init_plt (MonoAotModule *info)
{
-#ifdef MONO_ARCH_HAVE_PIC_AOT
+#ifdef MONO_ARCH_AOT_SUPPORTED
#ifdef __i386__
guint8 *buf = info->plt;
-#endif
-#if defined(__x86_64__)
+#elif defined(__x86_64__)
+ int i, n_entries;
+#elif defined(__arm__)
int i, n_entries;
#endif
gpointer tramp;
for (i = 1; i < n_entries; ++i)
/* Each PLT entry is 16 bytes long, the default entry begins at offset 6 */
((gpointer*)info->plt_jump_table)[i] = info->plt + (i * 16) + 6;
+#elif defined(__arm__)
+ /* Initialize the first PLT entry */
+ make_writable (info->plt, info->plt_end - info->plt);
+ ((guint32*)info->plt)[1] = (guint32)tramp;
+
+ n_entries = ((guint8*)info->plt_end - (guint8*)info->plt) / 8;
+
+ /*
+ * Initialize the jump targets embedded inside the PLT entries to the default
+ * targets.
+ */
+ for (i = 1; i < n_entries; ++i)
+ /* Each PLT entry is 8 bytes long, the jump target is at offset 4 */
+ /* Each default PLT target is 12 bytes long */
+ ((guint32*)info->plt)[(i * 2) + 1] = (guint8*)info->plt_end + ((i - 1) * 12);
#else
g_assert_not_reached ();
#endif
mono_aot_get_plt_entry (guint8 *code)
{
MonoAotModule *aot_module = find_aot_module (code);
+#if defined(__arm__)
+ guint32 ins;
+#endif
if (!aot_module)
return NULL;
if ((target >= (guint8*)(aot_module->plt)) && (target < (guint8*)(aot_module->plt_end)))
return target;
}
+#elif defined(__arm__)
+ ins = ((guint32*)(gpointer)code) [-1];
+
+ /* Should be a 'bl' */
+ if ((((ins >> 25) & 0x7) == 0x5) && (((ins >> 24) & 0x1) == 0x1)) {
+ gint32 disp = ((gint32)ins) & 0xffffff;
+ guint8 *target = code - 4 + 8 + (disp * 4);
+
+ if ((target >= (guint8*)(aot_module->plt)) && (target < (guint8*)(aot_module->plt_end)))
+ return target;
+ }
+#else
+ g_assert_not_reached ();
#endif
return NULL;
{
}
-MonoJitInfo*
+gpointer
mono_aot_get_method (MonoDomain *domain, MonoMethod *method)
{
return NULL;
return NULL;
}
+gpointer
+mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code)
+{
+ return NULL;
+}
+
+gpointer
+mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
+{
+ return NULL;
+}
#endif