X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fimage.c;h=3cf7ee51666bb2aa01099f990da7b2bd0876cd3a;hb=99b7766e0516e347df28e073a12b0f929fdb3eeb;hp=15467d788b0c1aa59e091fc24928b3d8b88264e1;hpb=7a34816740be50ca87730f153e86deae023c884f;p=mono.git diff --git a/mono/metadata/image.c b/mono/metadata/image.c index 15467d788b0..3cf7ee51666 100644 --- a/mono/metadata/image.c +++ b/mono/metadata/image.c @@ -27,7 +27,7 @@ #include "marshal.h" #include "coree.h" #include -#include +#include #include #include #include @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #ifdef HAVE_UNISTD_H @@ -57,6 +58,57 @@ static gboolean debug_assembly_unload = FALSE; static gboolean mutex_inited; static CRITICAL_SECTION images_mutex; +typedef struct ImageUnloadHook ImageUnloadHook; +struct ImageUnloadHook { + MonoImageUnloadFunc func; + gpointer user_data; +}; + +GSList *image_unload_hooks; + +void +mono_install_image_unload_hook (MonoImageUnloadFunc func, gpointer user_data) +{ + ImageUnloadHook *hook; + + g_return_if_fail (func != NULL); + + hook = g_new0 (ImageUnloadHook, 1); + hook->func = func; + hook->user_data = user_data; + image_unload_hooks = g_slist_prepend (image_unload_hooks, hook); +} + +void +mono_remove_image_unload_hook (MonoImageUnloadFunc func, gpointer user_data) +{ + GSList *l; + ImageUnloadHook *hook; + + for (l = image_unload_hooks; l; l = l->next) { + hook = l->data; + + if (hook->func == func && hook->user_data == user_data) { + g_free (hook); + image_unload_hooks = g_slist_delete_link (image_unload_hooks, l); + break; + } + } +} + +static void +mono_image_invoke_unload_hook (MonoImage *image) +{ + GSList *l; + ImageUnloadHook *hook; + + for (l = image_unload_hooks; l; l = l->next) { + hook = l->data; + + hook->func (image, hook->user_data); + } +} + /* returns offset relative to image->raw_data */ guint32 mono_cli_rva_image_map (MonoImage *image, guint32 addr) @@ -144,8 +196,15 @@ mono_images_init (void) void mono_images_cleanup (void) { + GHashTableIter iter; + MonoImage *image; + DeleteCriticalSection (&images_mutex); + g_hash_table_iter_init (&iter, loaded_images_hash); + while (g_hash_table_iter_next (&iter, NULL, (void**)&image)) + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly image '%s' still loaded at shutdown.", image->name); + g_hash_table_destroy (loaded_images_hash); g_hash_table_destroy (loaded_images_refonly_hash); @@ -469,10 +528,6 @@ mono_image_check_for_module_cctor (MonoImage *image) MonoTableInfo *t, *mt; t = &image->tables [MONO_TABLE_TYPEDEF]; mt = &image->tables [MONO_TABLE_METHOD]; - if (mono_framework_version () == 1) { - image->checked_module_cctor = TRUE; - return; - } if (image->dynamic) { /* FIXME: */ image->checked_module_cctor = TRUE; @@ -534,7 +589,7 @@ mono_image_load_module (MonoImage *image, int idx) GList *list_iter, *valid_modules = NULL; MonoImageOpenStatus status; - if ((image->module_count == 0) || (idx > image->module_count)) + if ((image->module_count == 0) || (idx > image->module_count || idx <= 0)) return NULL; if (image->modules_loaded [idx - 1]) return image->modules [idx - 1]; @@ -881,6 +936,7 @@ do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status, { MonoCLIImageInfo *iinfo; MonoDotNetHeader *header; + GSList *errors = NULL; mono_profiler_module_event (image, MONO_PROFILE_START_LOAD); @@ -895,7 +951,7 @@ do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status, if (care_about_pecoff == FALSE) goto done; - if (!mono_verifier_verify_pe_data (image, NULL)) + if (!mono_verifier_verify_pe_data (image, &errors)) goto invalid_image; if (!mono_image_load_pe_data (image)) @@ -905,13 +961,13 @@ do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status, goto done; } - if (!mono_verifier_verify_cli_data (image, NULL)) + if (!mono_verifier_verify_cli_data (image, &errors)) goto invalid_image; if (!mono_image_load_cli_data (image)) goto invalid_image; - if (!mono_verifier_verify_table_data (image, NULL)) + if (!mono_verifier_verify_table_data (image, &errors)) goto invalid_image; mono_image_load_names (image); @@ -926,9 +982,14 @@ done: return image; invalid_image: + if (errors) { + MonoVerifyInfo *info = errors->data; + g_warning ("Could not load image %s due to %s", image->name, info->message); + mono_free_verify_list (errors); + } mono_profiler_module_loaded (image, MONO_PROFILE_FAILED); mono_image_close (image); - return NULL; + return NULL; } static MonoImage * @@ -959,6 +1020,12 @@ do_mono_image_open (const char *fname, MonoImageOpenStatus *status, image->raw_buffer_used = TRUE; image->raw_data_len = mono_file_map_size (filed); image->raw_data = mono_file_map (image->raw_data_len, MONO_MMAP_READ|MONO_MMAP_PRIVATE, mono_file_map_fd (filed), 0, &image->raw_data_handle); +#if defined(HAVE_MMAP) && !defined (HOST_WIN32) + if (!image->raw_data) { + image->fileio_used = TRUE; + image->raw_data = mono_file_map_fileio (image->raw_data_len, MONO_MMAP_READ|MONO_MMAP_PRIVATE, mono_file_map_fd (filed), 0, &image->raw_data_handle); + } +#endif if (!image->raw_data) { mono_file_map_close (filed); g_free (image); @@ -1067,7 +1134,7 @@ register_image (MonoImage *image) } MonoImage * -mono_image_open_from_data_full (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly) +mono_image_open_from_data_with_name (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, const char *name) { MonoCLIImageInfo *iinfo; MonoImage *image; @@ -1093,7 +1160,7 @@ mono_image_open_from_data_full (char *data, guint32 data_len, gboolean need_copy image->raw_data = datac; image->raw_data_len = data_len; image->raw_data_allocated = need_copy; - image->name = g_strdup_printf ("data-%p", datac); + image->name = (name == NULL) ? g_strdup_printf ("data-%p", datac) : g_strdup(name); iinfo = g_new0 (MonoCLIImageInfo, 1); image->image_info = iinfo; image->ref_only = refonly; @@ -1105,6 +1172,12 @@ mono_image_open_from_data_full (char *data, guint32 data_len, gboolean need_copy return register_image (image); } +MonoImage * +mono_image_open_from_data_full (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly) +{ + return mono_image_open_from_data_with_name (data, data_len, need_copy, status, refonly, NULL); +} + MonoImage * mono_image_open_from_data (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status) { @@ -1194,8 +1267,12 @@ mono_image_open_full (const char *fname, MonoImageOpenStatus *status, gboolean r if (status) { if (last_error == ERROR_BAD_EXE_FORMAT || last_error == STATUS_INVALID_IMAGE_FORMAT) *status = MONO_IMAGE_IMAGE_INVALID; - else - *status = MONO_IMAGE_ERROR_ERRNO; + else { + if (last_error == ERROR_FILE_NOT_FOUND || last_error == ERROR_PATH_NOT_FOUND) + errno = ENOENT; + else + errno = 0; + } } return NULL; } @@ -1355,12 +1432,6 @@ free_mr_signatures (gpointer key, gpointer val, gpointer user_data) } */ -static void -free_remoting_wrappers (gpointer key, gpointer val, gpointer user_data) -{ - g_free (val); -} - static void free_array_cache_entry (gpointer key, gpointer val, gpointer user_data) { @@ -1411,6 +1482,7 @@ mono_image_close_except_pools (MonoImage *image) MonoImage *image2; GHashTable *loaded_images; int i; + GSList *free_list; g_return_val_if_fail (image != NULL, FALSE); @@ -1453,7 +1525,9 @@ mono_image_close_except_pools (MonoImage *image) mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Unloading image %s [%p].", image->name, image); - mono_metadata_clean_for_image (image); + mono_image_invoke_unload_hook (image); + + free_list = mono_metadata_clean_for_image (image); /* * The caches inside a MonoImage might refer to metadata which is stored in referenced @@ -1465,7 +1539,7 @@ mono_image_close_except_pools (MonoImage *image) int i; for (i = 0; i < t->rows; i++) { - if (image->references [i]) { + if (image->references [i] && image->references [i] != REFERENCE_MISSING) { if (!mono_assembly_close_except_image_pools (image->references [i])) image->references [i] = NULL; } @@ -1485,8 +1559,14 @@ mono_image_close_except_pools (MonoImage *image) #endif if (image->raw_buffer_used) { - if (image->raw_data != NULL) - mono_file_unmap (image->raw_data, image->raw_data_handle); + if (image->raw_data != NULL) { +#ifndef HOST_WIN32 + if (image->fileio_used) + mono_file_unmap_fileio (image->raw_data, image->raw_data_handle); + else +#endif + mono_file_unmap (image->raw_data, image->raw_data_handle); + } } if (image->raw_data_allocated) { @@ -1540,8 +1620,7 @@ mono_image_close_except_pools (MonoImage *image) free_hash (image->delegate_end_invoke_cache); free_hash (image->delegate_invoke_cache); free_hash (image->delegate_abstract_invoke_cache); - if (image->remoting_invoke_cache) - g_hash_table_foreach (image->remoting_invoke_cache, free_remoting_wrappers, NULL); + free_hash (image->delegate_bound_static_invoke_cache); free_hash (image->remoting_invoke_cache); free_hash (image->runtime_invoke_cache); free_hash (image->runtime_invoke_direct_cache); @@ -1558,6 +1637,12 @@ mono_image_close_except_pools (MonoImage *image) free_hash (image->castclass_cache); free_hash (image->proxy_isinst_cache); free_hash (image->thunk_invoke_cache); + free_hash (image->var_cache_slow); + free_hash (image->mvar_cache_slow); + free_hash (image->wrapper_param_names); + free_hash (image->native_wrapper_aot_cache); + free_hash (image->pinvoke_scopes); + free_hash (image->pinvoke_scope_filenames); /* The ownership of signatures is not well defined */ //g_hash_table_foreach (image->memberref_signatures, free_mr_signatures, NULL); @@ -1566,9 +1651,6 @@ mono_image_close_except_pools (MonoImage *image) g_hash_table_destroy (image->helper_signatures); g_hash_table_destroy (image->method_signatures); - if (image->generic_class_cache) - g_hash_table_destroy (image->generic_class_cache); - if (image->rgctx_template_hash) g_hash_table_destroy (image->rgctx_template_hash); @@ -1576,6 +1658,7 @@ mono_image_close_except_pools (MonoImage *image) mono_property_hash_destroy (image->property_hash); g_slist_free (image->reflection_info_unregister_classes); + image->reflection_info_unregister_classes = free_list; if (image->interface_bitset) { mono_unload_interface_ids (image->interface_bitset); @@ -1619,13 +1702,19 @@ void mono_image_close_finish (MonoImage *image) { int i; + GSList *l; + + for (l = image->reflection_info_unregister_classes; l; l = l->next) + g_free (l->data); + g_slist_free (image->reflection_info_unregister_classes); + image->reflection_info_unregister_classes = NULL; if (image->references && !image->dynamic) { MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF]; int i; for (i = 0; i < t->rows; i++) { - if (image->references [i]) + if (image->references [i] && image->references [i] != REFERENCE_MISSING) mono_assembly_close_finish (image->references [i]); }