From: Zoltan Varga Date: Mon, 3 Jan 2011 17:49:19 +0000 (+0100) Subject: Reorganize the AOT file format once more, get rid of most globals, store them as... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=3b3f1c96742257c9a384f5b55feb2aa58894901c;hp=44651e524b2a067d1ea39fbf5ceed51f1fef87ce;p=mono.git Reorganize the AOT file format once more, get rid of most globals, store them as pointers inside MonoAotFileInfo instead. --- diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index 2ca0017d205..cd3528a93d7 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -377,6 +377,14 @@ emit_string_symbol (MonoAotCompile *acfg, const char *name, const char *value) img_writer_emit_string (acfg->w, value); } +static void +emit_local_string_symbol (MonoAotCompile *acfg, const char *name, const char *value) +{ + img_writer_emit_section_change (acfg->w, RODATA_SECT, 1); + img_writer_emit_label (acfg->w, name); + img_writer_emit_string (acfg->w, value); +} + static G_GNUC_UNUSED void emit_uleb128 (MonoAotCompile *acfg, guint32 value) { @@ -3844,7 +3852,6 @@ emit_plt (MonoAotCompile *acfg) sprintf (symbol, "plt"); emit_section_change (acfg, ".text", 0); - emit_global (acfg, symbol, TRUE); emit_alignment (acfg, 16); emit_label (acfg, symbol); emit_label (acfg, acfg->plt_symbol); @@ -3956,7 +3963,6 @@ emit_plt (MonoAotCompile *acfg) emit_symbol_size (acfg, acfg->plt_symbol, "."); sprintf (symbol, "plt_end"); - emit_global (acfg, symbol, TRUE); emit_label (acfg, symbol); g_hash_table_destroy (cache); @@ -4191,7 +4197,6 @@ emit_trampolines (MonoAotCompile *acfg) g_assert_not_reached (); } - emit_global (acfg, symbol, TRUE); emit_alignment (acfg, AOT_FUNC_ALIGNMENT); emit_label (acfg, symbol); @@ -5010,13 +5015,11 @@ emit_code (MonoAotCompile *acfg) sprintf (symbol, "methods_end"); emit_section_change (acfg, ".text", 0); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); sprintf (symbol, "code_offsets"); emit_section_change (acfg, RODATA_SECT, 1); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); @@ -5056,7 +5059,6 @@ emit_info (MonoAotCompile *acfg) sprintf (symbol, "method_info_offsets"); emit_section_change (acfg, RODATA_SECT, 1); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); @@ -5420,7 +5422,6 @@ emit_extra_methods (MonoAotCompile *acfg) /* Emit the table */ sprintf (symbol, "extra_method_table"); emit_section_change (acfg, RODATA_SECT, 0); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); @@ -5449,7 +5450,6 @@ emit_extra_methods (MonoAotCompile *acfg) */ sprintf (symbol, "extra_method_info_offsets"); emit_section_change (acfg, RODATA_SECT, 0); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); @@ -5481,7 +5481,6 @@ emit_exception_info (MonoAotCompile *acfg) sprintf (symbol, "ex_info_offsets"); emit_section_change (acfg, RODATA_SECT, 1); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); @@ -5505,7 +5504,6 @@ emit_unwind_info (MonoAotCompile *acfg) emit_section_change (acfg, RODATA_SECT, 1); emit_alignment (acfg, 8); emit_label (acfg, symbol); - emit_global (acfg, symbol, FALSE); for (i = 0; i < acfg->unwind_ops->len; ++i) { guint32 index = GPOINTER_TO_UINT (g_ptr_array_index (acfg->unwind_ops, i)); @@ -5538,7 +5536,6 @@ emit_class_info (MonoAotCompile *acfg) sprintf (symbol, "class_info_offsets"); emit_section_change (acfg, RODATA_SECT, 1); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); @@ -5599,7 +5596,6 @@ emit_class_name_table (MonoAotCompile *acfg) /* Emit the table */ sprintf (symbol, "class_name_table"); emit_section_change (acfg, RODATA_SECT, 0); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); @@ -5634,9 +5630,8 @@ emit_image_table (MonoAotCompile *acfg) * So we emit it at once, and reference its elements by an index. */ - sprintf (symbol, "mono_image_table"); + sprintf (symbol, "image_table"); emit_section_change (acfg, RODATA_SECT, 1); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); @@ -5719,7 +5714,6 @@ emit_got_info (MonoAotCompile *acfg) /* Emit got_info_offsets table */ sprintf (symbol, "got_info_offsets"); emit_section_change (acfg, RODATA_SECT, 1); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); @@ -5855,16 +5849,14 @@ emit_globals (MonoAotCompile *acfg) { char *build_info; - emit_string_symbol (acfg, "mono_assembly_guid" , acfg->image->guid); - - emit_string_symbol (acfg, "mono_aot_version", MONO_AOT_FILE_VERSION); + emit_local_string_symbol (acfg, "assembly_guid" , acfg->image->guid); if (acfg->aot_opts.bind_to_runtime_version) { build_info = mono_get_runtime_build_info (); - emit_string_symbol (acfg, "mono_runtime_version", build_info); + emit_local_string_symbol (acfg, "runtime_version", build_info); g_free (build_info); } else { - emit_string_symbol (acfg, "mono_runtime_version", ""); + emit_local_string_symbol (acfg, "runtime_version", ""); } /* @@ -5930,7 +5922,6 @@ emit_mem_end (MonoAotCompile *acfg) sprintf (symbol, "mem_end"); emit_section_change (acfg, ".text", 1); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); } @@ -5961,9 +5952,13 @@ emit_file_info (MonoAotCompile *acfg) /* The data emitted here must match MonoAotFileInfo. */ + emit_int32 (acfg, MONO_AOT_FILE_VERSION); + emit_int32 (acfg, 0); + /* - * We emit these as data to avoid making these symbols global, which leads to - * various problems + * We emit pointers to our data structures instead of emitting global symbols which + * point to them, to reduce the number of globals, and because using globals leads to + * various problems (i.e. arm/thumb). */ emit_pointer (acfg, acfg->got_symbol); emit_pointer (acfg, "methods"); @@ -5975,6 +5970,37 @@ emit_file_info (MonoAotCompile *acfg) } else { emit_pointer (acfg, NULL); } + emit_pointer (acfg, "blob"); + emit_pointer (acfg, "class_name_table"); + emit_pointer (acfg, "class_info_offsets"); + emit_pointer (acfg, "method_info_offsets"); + emit_pointer (acfg, "ex_info_offsets"); + emit_pointer (acfg, "code_offsets"); + emit_pointer (acfg, "extra_method_info_offsets"); + emit_pointer (acfg, "extra_method_table"); + emit_pointer (acfg, "got_info_offsets"); + emit_pointer (acfg, "methods_end"); + emit_pointer (acfg, "unwind_info"); + emit_pointer (acfg, "mem_end"); + emit_pointer (acfg, "image_table"); + emit_pointer (acfg, "plt"); + emit_pointer (acfg, "plt_end"); + emit_pointer (acfg, "assembly_guid"); + emit_pointer (acfg, "runtime_version"); + if (acfg->num_trampoline_got_entries) { + emit_pointer (acfg, "specific_trampolines"); + emit_pointer (acfg, "static_rgctx_trampolines"); + emit_pointer (acfg, "imt_thunks"); + } else { + emit_pointer (acfg, NULL); + emit_pointer (acfg, NULL); + emit_pointer (acfg, NULL); + } + if (acfg->thumb_mixed) { + emit_pointer (acfg, "thumb_end"); + } else { + emit_pointer (acfg, NULL); + } emit_int32 (acfg, acfg->plt_got_offset_base); emit_int32 (acfg, (int)(acfg->got_offset * sizeof (gpointer))); @@ -5999,7 +6025,6 @@ emit_blob (MonoAotCompile *acfg) sprintf (symbol, "blob"); emit_section_change (acfg, RODATA_SECT, 1); - emit_global (acfg, symbol, FALSE); emit_alignment (acfg, 8); emit_label (acfg, symbol); diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index 9bdffb17b48..c38f2ff0a6b 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -964,6 +964,65 @@ find_symbol (MonoDl *module, gpointer *globals, const char *name, gpointer *valu } } +static gboolean +check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, char **out_msg) +{ + char *build_info; + char *msg = NULL; + gboolean usable = TRUE; + gboolean full_aot; + guint8 *blob; + + if (strcmp (assembly->image->guid, info->assembly_guid)) { + msg = g_strdup_printf ("doesn't match assembly"); + usable = FALSE; + } + + build_info = mono_get_runtime_build_info (); + if (strlen (info->runtime_version) > 0 && strcmp (info->runtime_version, build_info)) { + msg = g_strdup_printf ("compiled against runtime version '%s' while this runtime has version '%s'", info->runtime_version, build_info); + usable = FALSE; + } + g_free (build_info); + + full_aot = info->flags & MONO_AOT_FILE_FLAG_FULL_AOT; + + if (mono_aot_only && !full_aot) { + msg = g_strdup_printf ("not compiled with --aot=full"); + usable = FALSE; + } + if (!mono_aot_only && full_aot) { + msg = g_strdup_printf ("compiled with --aot=full"); + usable = FALSE; + } +#ifdef TARGET_ARM + /* mono_arch_find_imt_method () requires this */ + if ((info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) { + msg = g_strdup_printf ("compiled against LLVM"); + usable = FALSE; + } +#endif + if (mini_get_debug_options ()->mdb_optimizations && !(info->flags & MONO_AOT_FILE_FLAG_DEBUG) && !full_aot) { + msg = g_strdup_printf ("not compiled for debugging"); + usable = FALSE; + } + + blob = info->blob; + + if (info->gc_name_index != -1) { + char *gc_name = (char*)&blob [info->gc_name_index]; + const char *current_gc_name = mono_gc_get_gc_name (); + + if (strcmp (current_gc_name, gc_name) != 0) { + msg = g_strdup_printf ("compiled against GC %s, while the current runtime uses GC %s.\n", gc_name, current_gc_name); + usable = FALSE; + } + } + + *out_msg = msg; + return usable; +} + static void load_aot_module (MonoAssembly *assembly, gpointer user_data) { @@ -971,15 +1030,11 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) MonoAotModule *amodule; MonoDl *sofile; gboolean usable = TRUE; - char *saved_guid = NULL; - char *aot_version = NULL; - char *runtime_version, *build_info; - char *opt_flags = NULL; + char *version_symbol = NULL; char *msg = NULL; gpointer *globals; - gboolean full_aot = FALSE; - MonoAotFileInfo *file_info = NULL; - int i; + MonoAotFileInfo *info = NULL; + int i, version; guint8 *blob; if (mono_compile_aot) @@ -1035,66 +1090,22 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) return; } - find_symbol (sofile, globals, "mono_assembly_guid", (gpointer *) &saved_guid); - find_symbol (sofile, globals, "mono_aot_version", (gpointer *) &aot_version); - find_symbol (sofile, globals, "mono_aot_opt_flags", (gpointer *)&opt_flags); - find_symbol (sofile, globals, "mono_runtime_version", (gpointer *)&runtime_version); - - if (!aot_version || strcmp (aot_version, MONO_AOT_FILE_VERSION)) { - msg = g_strdup_printf ("wrong file format version (expected %s got %s)", MONO_AOT_FILE_VERSION, aot_version); - usable = FALSE; - } - else { - if (!saved_guid || strcmp (assembly->image->guid, saved_guid)) { - msg = g_strdup_printf ("doesn't match assembly"); - usable = FALSE; - } - } - - build_info = mono_get_runtime_build_info (); - if (!runtime_version || ((strlen (runtime_version) > 0 && strcmp (runtime_version, build_info)))) { - msg = g_strdup_printf ("compiled against runtime version '%s' while this runtime has version '%s'", runtime_version, build_info); - usable = FALSE; - } - g_free (build_info); - - find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&file_info); - g_assert (file_info); - - full_aot = ((MonoAotFileInfo*)file_info)->flags & MONO_AOT_FILE_FLAG_FULL_AOT; - - if (mono_aot_only && !full_aot) { - fprintf (stderr, "Can't use AOT image '%s' in aot-only mode because it is not compiled with --aot=full.\n", aot_name); - exit (1); - } - if (!mono_aot_only && full_aot) { - msg = g_strdup_printf ("compiled with --aot=full"); - usable = FALSE; - } + find_symbol (sofile, globals, "mono_aot_version", (gpointer *) &version_symbol); + find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&info); -#ifdef TARGET_ARM - /* mono_arch_find_imt_method () requires this */ - if ((((MonoAotFileInfo*)file_info)->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) { - msg = g_strdup_printf ("compiled against LLVM"); - usable = FALSE; + if (version_symbol) { + /* Old file format */ + version = atoi (version_symbol); + } else { + g_assert (info); + version = info->version; } -#endif - if (mini_get_debug_options ()->mdb_optimizations && !(file_info->flags & MONO_AOT_FILE_FLAG_DEBUG) && !full_aot) { - msg = g_strdup_printf ("not compiled for debugging"); + if (version != MONO_AOT_FILE_VERSION) { + msg = g_strdup_printf ("wrong file format version (expected %d got %d)", MONO_AOT_FILE_VERSION, version); usable = FALSE; - } - - find_symbol (sofile, globals, "blob", (gpointer*)&blob); - - if (usable && ((MonoAotFileInfo*)file_info)->gc_name_index != -1) { - char *gc_name = (char*)&blob [((MonoAotFileInfo*)file_info)->gc_name_index]; - const char *current_gc_name = mono_gc_get_gc_name (); - - if (strcmp (current_gc_name, gc_name) != 0) { - msg = g_strdup_printf ("compiled against GC %s, while the current runtime uses GC %s.\n", gc_name, current_gc_name); - usable = FALSE; - } + } else { + usable = check_usable (assembly, info, &msg); } if (!usable) { @@ -1112,11 +1123,13 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) return; } + blob = info->blob; + amodule = g_new0 (MonoAotModule, 1); amodule->aot_name = aot_name; amodule->assembly = assembly; - memcpy (&amodule->info, file_info, sizeof (*file_info)); + memcpy (&amodule->info, info, sizeof (*info)); amodule->got = amodule->info.got; amodule->got [0] = assembly->image; @@ -1130,7 +1143,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) guint32 table_len, i; char *table = NULL; - find_symbol (sofile, globals, "mono_image_table", (gpointer *)&table); + table = info->image_table; g_assert (table); table_len = *(guint32*)table; @@ -1166,34 +1179,30 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) } } - /* Read method and method_info tables */ - find_symbol (sofile, globals, "code_offsets", (gpointer*)&amodule->code_offsets); - amodule->code = amodule->info.methods; + amodule->code_offsets = info->code_offsets; + amodule->code = info->methods; #ifdef TARGET_ARM /* Mask out thumb interop bit */ amodule->code = (void*)((mgreg_t)amodule->code & ~1); #endif - find_symbol (sofile, globals, "methods_end", (gpointer*)&amodule->code_end); - find_symbol (sofile, globals, "method_info_offsets", (gpointer*)&amodule->method_info_offsets); - find_symbol (sofile, globals, "ex_info_offsets", (gpointer*)&amodule->ex_info_offsets); - find_symbol (sofile, globals, "class_info_offsets", (gpointer*)&amodule->class_info_offsets); - find_symbol (sofile, globals, "class_name_table", (gpointer *)&amodule->class_name_table); - find_symbol (sofile, globals, "extra_method_table", (gpointer *)&amodule->extra_method_table); - find_symbol (sofile, globals, "extra_method_info_offsets", (gpointer *)&amodule->extra_method_info_offsets); - find_symbol (sofile, globals, "got_info_offsets", (gpointer*)&amodule->got_info_offsets); - find_symbol (sofile, globals, "specific_trampolines", (gpointer*)&(amodule->trampolines [MONO_AOT_TRAMP_SPECIFIC])); - find_symbol (sofile, globals, "static_rgctx_trampolines", (gpointer*)&(amodule->trampolines [MONO_AOT_TRAMP_STATIC_RGCTX])); - find_symbol (sofile, globals, "imt_thunks", (gpointer*)&(amodule->trampolines [MONO_AOT_TRAMP_IMT_THUNK])); - find_symbol (sofile, globals, "unwind_info", (gpointer)&amodule->unwind_info); - find_symbol (sofile, globals, "mem_end", (gpointer*)&amodule->mem_end); - find_symbol (sofile, globals, "thumb_end", (gpointer*)&amodule->thumb_end); - + amodule->code_end = info->methods_end; + amodule->method_info_offsets = info->method_info_offsets; + amodule->ex_info_offsets = info->ex_info_offsets; + amodule->class_info_offsets = info->class_info_offsets; + amodule->class_name_table = info->class_name_table; + amodule->extra_method_table = info->extra_method_table; + amodule->extra_method_info_offsets = info->extra_method_info_offsets; + amodule->got_info_offsets = info->got_info_offsets; + amodule->unwind_info = info->unwind_info; + amodule->mem_end = info->mem_end; amodule->mem_begin = amodule->code; - - find_symbol (sofile, globals, "plt", (gpointer*)&amodule->plt); - find_symbol (sofile, globals, "plt_end", (gpointer*)&amodule->plt_end); - - amodule->mono_eh_frame = amodule->info.mono_eh_frame; + amodule->plt = info->plt; + amodule->plt_end = info->plt_end; + amodule->mono_eh_frame = info->mono_eh_frame; + amodule->trampolines [MONO_AOT_TRAMP_SPECIFIC] = info->specific_trampolines; + amodule->trampolines [MONO_AOT_TRAMP_STATIC_RGCTX] = info->static_rgctx_trampolines; + amodule->trampolines [MONO_AOT_TRAMP_IMT_THUNK] = info->imt_thunks; + amodule->thumb_end = info->thumb_end; if (make_unreadable) { #ifndef TARGET_WIN32 diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 1b82bb99e40..16c14c59925 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -111,7 +111,7 @@ typedef gint64 mgreg_t; #endif /* Version number of the AOT file format */ -#define MONO_AOT_FILE_VERSION "71" +#define MONO_AOT_FILE_VERSION 72 //TODO: This is x86/amd64 specific. #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6)) @@ -149,10 +149,44 @@ typedef enum { /* This structure is stored in the AOT file */ typedef struct MonoAotFileInfo { + /* The version number of the AOT file format, should match MONO_AOT_FILE_VERSION */ + guint32 version; + /* For alignment */ + guint32 dummy; + /* All the pointers should be at the start to avoid alignment problems */ + + /* Mono's Global Offset Table */ gpointer got; + /* Compiled code for methods */ gpointer methods; + /* Mono EH Frame created by llc when using LLVM */ gpointer mono_eh_frame; + /* Data blob */ + gpointer blob; + gpointer class_name_table; + gpointer class_info_offsets; + gpointer method_info_offsets; + gpointer ex_info_offsets; + gpointer code_offsets; + gpointer extra_method_info_offsets; + gpointer extra_method_table; + gpointer got_info_offsets; + gpointer methods_end; + gpointer unwind_info; + gpointer mem_end; + gpointer image_table; + /* Start of Mono's Program Linkage Table */ + gpointer plt; + /* End of Mono's Program Linkage Table */ + gpointer plt_end; + /* The GUID of the assembly which the AOT image was generated from */ + gpointer assembly_guid; + gpointer runtime_version; + gpointer specific_trampolines; + gpointer static_rgctx_trampolines; + gpointer imt_thunks; + gpointer thumb_end; guint32 plt_got_offset_base; guint32 got_size;