X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fassembly.c;h=209e4ab4f988192fe280953fe7d5017c547d56b3;hb=1fb083d2d4fa63b41b1c97bb61cd5782a62c910b;hp=0744389c400bf4539c0d88f3e530df2a95436b6e;hpb=bc9461168edd5bceab698999685f3cbfdd113107;p=mono.git diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c index 0744389c400..209e4ab4f98 100644 --- a/mono/metadata/assembly.c +++ b/mono/metadata/assembly.c @@ -16,7 +16,9 @@ #include #include #include "assembly.h" +#include "assembly-internals.h" #include "image.h" +#include "image-internals.h" #include "object-internals.h" #include #include @@ -212,6 +214,9 @@ mono_assembly_load_full_internal (MonoAssemblyName *aname, MonoAssembly *request static MonoBoolean mono_assembly_is_in_gac (const gchar *filanem); +static MonoAssembly* +prevent_reference_assembly_from_running (MonoAssembly* candidate, gboolean refonly); + static gchar* encode_public_tok (const guchar *token, gint32 len) { @@ -557,6 +562,21 @@ mono_assembly_getrootdir (void) return default_path [0]; } +/** + * mono_native_getrootdir: + * + * Obtains the root directory used for looking up native libs (.so, .dylib). + * + * Returns: a string with the directory, this string should be freed by + * the caller. + */ +gchar * +mono_native_getrootdir (void) +{ + gchar* fullpath = g_build_path (G_DIR_SEPARATOR_S, mono_assembly_getrootdir (), mono_config_get_reloc_lib_dir(), NULL); + return fullpath; +} + /** * mono_set_dirs: * @assembly_dir: the base directory for assemblies @@ -1192,22 +1212,6 @@ mono_assembly_load_reference (MonoImage *image, int index) strlen ((char*)aname.public_key_token) == 0 ? "(none)" : (char*)aname.public_key_token, extra_msg); g_free (extra_msg); - } else if (!image->assembly->ref_only) { - MonoError error; - if (mono_assembly_get_reference_assembly_attribute (reference, &error)) { - mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY, "The following reference assembly assembly referenced from %s was not loaded. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context:\n" - " Assembly: %s (assemblyref_index=%d)\n" - " Version: %d.%d.%d.%d\n" - " Public Key: %s\n", - image->name, aname.name, index, - aname.major, aname.minor, aname.build, aname.revision, - strlen ((char*)aname.public_key_token) == 0 ? "(none)" : (char*)aname.public_key_token); - reference = NULL; /* don't load reference assemblies for execution */ - } - if (!is_ok (&error)) { - reference = NULL; - mono_error_cleanup (&error); - } } mono_assemblies_lock (); @@ -1562,8 +1566,9 @@ mono_assembly_open_from_bundle (const char *filename, MonoImageOpenStatus *statu { int i; char *name; + gchar *lowercase_filename; MonoImage *image = NULL; - + gboolean is_satellite = FALSE; /* * we do a very simple search for bundled assemblies: it's not a general * purpose assembly loading mechanism. @@ -1572,11 +1577,13 @@ mono_assembly_open_from_bundle (const char *filename, MonoImageOpenStatus *statu if (!bundles) return NULL; + lowercase_filename = g_utf8_strdown (filename, -1); + is_satellite = g_str_has_suffix (lowercase_filename, ".resources.dll"); + g_free (lowercase_filename); name = g_path_get_basename (filename); - mono_assemblies_lock (); for (i = 0; !image && bundles [i]; ++i) { - if (strcmp (bundles [i]->name, name) == 0) { + if (strcmp (bundles [i]->name, is_satellite ? filename : name) == 0) { image = mono_image_open_from_data_with_name ((char*)bundles [i]->data, bundles [i]->size, FALSE, status, refonly, name); break; } @@ -1584,7 +1591,7 @@ mono_assembly_open_from_bundle (const char *filename, MonoImageOpenStatus *statu mono_assemblies_unlock (); if (image) { mono_image_addref (image); - mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly Loader loaded assembly from bundle: '%s'.", name); + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly Loader loaded assembly from bundle: '%s'.", is_satellite ? filename : name); g_free (name); return image; } @@ -1823,7 +1830,7 @@ mono_assembly_load_friends (MonoAssembly* ass) /** - * mono_assembly_get_reference_assembly_attribute: + * mono_assembly_has_reference_assembly_attribute: * @assembly: a MonoAssembly * @error: set on error. * @@ -1831,25 +1838,28 @@ mono_assembly_load_friends (MonoAssembly* ass) * On error returns FALSE and sets @error. */ gboolean -mono_assembly_get_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error) +mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error) { mono_error_init (error); +/* TODO: mono_custom_attrs_from_assembly_checked returns NULL if a + * single assembly is missing. The custom attr we want is from + * corlib, however, so we need a more robust version that doesn't care + * about missing attributes. + */ +#if 0 MonoCustomAttrInfo *attrs = mono_custom_attrs_from_assembly_checked (assembly, error); return_val_if_nok (error, FALSE); if (!attrs) return FALSE; MonoClass *ref_asm_class = mono_class_try_get_reference_assembly_class (); - gboolean result = FALSE; - for (int i = 0; i < attrs->num_attrs; ++i) { - MonoCustomAttrEntry *attr = &attrs->attrs [i]; - if (attr->ctor && attr->ctor->klass && attr->ctor->klass == ref_asm_class) { - result = TRUE; - break; - } - } + g_assert (ref_asm_class != NULL && ref_asm_class != mono_defaults.object_class && !strcmp(ref_asm_class->name, "ReferenceAssemblyAttribute") ); + gboolean result = mono_custom_attrs_has_attr (attrs, ref_asm_class); mono_custom_attrs_free (attrs); return result; +#else + return FALSE; +#endif } /** @@ -1987,6 +1997,36 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname, return ass2; } + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Prepared to set up assembly '%s' (%s)", ass->aname.name, image->name); + + /* We need to check for ReferenceAssmeblyAttribute before we + * mark the assembly as loaded and before we fire the load + * hook. Otherwise mono_domain_fire_assembly_load () in + * appdomain.c will cache a mapping from the assembly name to + * this image and we won't be able to look for a different + * candidate. */ + + if (!refonly && strcmp (ass->aname.name, "mscorlib") != 0) { + /* Don't check for reference assmebly attribute for + * corlib here because if corlib isn't loaded yet, + * it's too early to set up the + * ReferenceAssemblyAttribute class. We check that + * we're not running with a reference corlib in + * mono_init_internal(). + */ + MonoError refasm_error; + if (mono_assembly_has_reference_assembly_attribute (ass, &refasm_error)) { + mono_assemblies_unlock (); + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Image for assembly '%s' (%s) has ReferenceAssemblyAttribute, skipping", ass->aname.name, image->name); + g_free (ass); + g_free (base_dir); + mono_image_close (image); + *status = MONO_IMAGE_IMAGE_INVALID; + return NULL; + } + mono_error_cleanup (&refasm_error); + } + image->assembly = ass; loaded_assemblies = g_list_prepend (loaded_assemblies, ass); @@ -2355,11 +2395,11 @@ mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboole if (!g_ascii_strcasecmp (retargetable, "yes")) { flags |= ASSEMBLYREF_RETARGETABLE_FLAG; } else if (g_ascii_strcasecmp (retargetable, "no")) { - free (retargetable_uq); + g_free (retargetable_uq); goto cleanup_and_fail; } - free (retargetable_uq); + g_free (retargetable_uq); tmp++; continue; } @@ -2379,11 +2419,11 @@ mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboole else if (!g_ascii_strcasecmp (procarch, "AMD64")) arch = MONO_PROCESSOR_ARCHITECTURE_AMD64; else { - free (procarch_uq); + g_free (procarch_uq); goto cleanup_and_fail; } - free (procarch_uq); + g_free (procarch_uq); tmp++; continue; } @@ -2411,11 +2451,11 @@ mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboole key_uq == NULL ? key : key_uq, flags, arch, aname, save_public_key); - free (dllname_uq); - free (version_uq); - free (culture_uq); - free (token_uq); - free (key_uq); + g_free (dllname_uq); + g_free (version_uq); + g_free (culture_uq); + g_free (token_uq); + g_free (key_uq); g_strfreev (parts); return res; @@ -3190,6 +3230,19 @@ return_corlib_and_facades: return corlib; } +static MonoAssembly* +prevent_reference_assembly_from_running (MonoAssembly* candidate, gboolean refonly) +{ + MonoError refasm_error; + mono_error_init (&refasm_error); + if (candidate && !refonly && mono_assembly_has_reference_assembly_attribute (candidate, &refasm_error)) { + candidate = NULL; + } + mono_error_cleanup (&refasm_error); + return candidate; +} + + MonoAssembly* mono_assembly_load_full_nosearch (MonoAssemblyName *aname, const char *basedir, @@ -3271,9 +3324,11 @@ mono_assembly_load_full_internal (MonoAssemblyName *aname, MonoAssembly *request { MonoAssembly *result = mono_assembly_load_full_nosearch (aname, basedir, status, refonly); - if (!result) + if (!result) { /* Try a postload search hook */ result = mono_assembly_invoke_search_hook_internal (aname, requesting, refonly, TRUE); + result = prevent_reference_assembly_from_running (result, refonly); + } return result; } @@ -3447,9 +3502,19 @@ mono_assembly_close (MonoAssembly *assembly) MonoImage* mono_assembly_load_module (MonoAssembly *assembly, guint32 idx) { - return mono_image_load_file_for_image (assembly->image, idx); + MonoError error; + MonoImage *result = mono_assembly_load_module_checked (assembly, idx, &error); + mono_error_assert_ok (&error); + return result; +} + +MONO_API MonoImage* +mono_assembly_load_module_checked (MonoAssembly *assembly, uint32_t idx, MonoError *error) +{ + return mono_image_load_file_for_image_checked (assembly->image, idx, error); } + /** * mono_assembly_foreach: * @func: function to invoke for each assembly loaded