X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fassembly.c;h=9efcf1db486445dec64ee79c733593dbd7511391;hb=bb4b0ff4fc2877a3fd5d784348368ec832fb82c7;hp=64d1000bbb63b8f896164af207e176969b6ece3c;hpb=7f51d473ef1a8bcb08ba488cb35500445a501b39;p=mono.git diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c index 64d1000bbb6..9efcf1db486 100644 --- a/mono/metadata/assembly.c +++ b/mono/metadata/assembly.c @@ -214,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) { @@ -559,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 @@ -1193,6 +1211,7 @@ mono_assembly_load_reference (MonoImage *image, int index) aname.major, aname.minor, aname.build, aname.revision, strlen ((char*)aname.public_key_token) == 0 ? "(none)" : (char*)aname.public_key_token, extra_msg); g_free (extra_msg); + } mono_assemblies_lock (); @@ -1749,7 +1768,7 @@ mono_assembly_load_friends (MonoAssembly* ass) if (ass->friend_assembly_names_inited) return; - attrs = mono_custom_attrs_from_assembly_checked (ass, &error); + attrs = mono_custom_attrs_from_assembly_checked (ass, FALSE, &error); mono_error_assert_ok (&error); if (!attrs) { mono_assemblies_lock (); @@ -1811,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. * @@ -1819,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); - MonoCustomAttrInfo *attrs = mono_custom_attrs_from_assembly_checked (assembly, 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 1 + MonoCustomAttrInfo *attrs = mono_custom_attrs_from_assembly_checked (assembly, TRUE, 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 } /** @@ -1975,8 +1997,38 @@ 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); + image->assembly = ass; + /* 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); + } + loaded_assemblies = g_list_prepend (loaded_assemblies, ass); mono_assemblies_unlock (); @@ -3178,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, @@ -3259,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; }