#include "object-internals.h"
#include <mono/metadata/loader.h>
#include <mono/metadata/tabledefs.h>
+#include <mono/metadata/custom-attrs-internals.h>
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/profiler-private.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/reflection-internals.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/mono-debug.h>
-#include <mono/io-layer/io-layer.h>
#include <mono/utils/mono-uri.h>
#include <mono/metadata/mono-config.h>
#include <mono/metadata/mono-config-dirs.h>
/* Class lazy loading functions */
static GENERATE_TRY_GET_CLASS_WITH_CACHE (internals_visible, System.Runtime.CompilerServices, InternalsVisibleToAttribute)
-static GENERATE_TRY_GET_CLASS_WITH_CACHE (reference_assembly, System.Runtime.CompilerServices, ReferenceAssemblyAttribute)
-
static MonoAssembly*
mono_assembly_invoke_search_hook_internal (MonoAssemblyName *aname, MonoAssembly *requesting, gboolean refonly, gboolean postload);
static MonoAssembly*
* Returns: a string with the directory, this string should be freed by
* the caller.
*/
-G_CONST_RETURN gchar *
+gchar *
mono_native_getrootdir (void)
{
gchar* fullpath = g_build_path (G_DIR_SEPARATOR_S, mono_assembly_getrootdir (), mono_config_get_reloc_lib_dir(), NULL);
}
gboolean
-mono_assembly_fill_assembly_name (MonoImage *image, MonoAssemblyName *aname)
+mono_assembly_fill_assembly_name_full (MonoImage *image, MonoAssemblyName *aname, gboolean copyBlobs)
{
MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLY];
guint32 cols [MONO_ASSEMBLY_SIZE];
aname->hash_len = 0;
aname->hash_value = NULL;
aname->name = mono_metadata_string_heap (image, cols [MONO_ASSEMBLY_NAME]);
+ if (copyBlobs)
+ aname->name = g_strdup (aname->name);
aname->culture = mono_metadata_string_heap (image, cols [MONO_ASSEMBLY_CULTURE]);
+ if (copyBlobs)
+ aname->culture = g_strdup (aname->culture);
aname->flags = cols [MONO_ASSEMBLY_FLAGS];
aname->major = cols [MONO_ASSEMBLY_MAJOR_VERSION];
aname->minor = cols [MONO_ASSEMBLY_MINOR_VERSION];
if (cols [MONO_ASSEMBLY_PUBLIC_KEY]) {
aname->public_key = (guchar*)mono_metadata_blob_heap (image, cols [MONO_ASSEMBLY_PUBLIC_KEY]);
+ if (copyBlobs) {
+ const gchar *pkey_end;
+ int len = mono_metadata_decode_blob_size ((const gchar*) aname->public_key, &pkey_end);
+ pkey_end += len; /* move to end */
+ size_t size = pkey_end - (const gchar*)aname->public_key;
+ guchar *tmp = g_new (guchar, size);
+ memcpy (tmp, aname->public_key, size);
+ aname->public_key = tmp;
+ }
+
}
else
aname->public_key = 0;
return TRUE;
}
+gboolean
+mono_assembly_fill_assembly_name (MonoImage *image, MonoAssemblyName *aname)
+{
+ return mono_assembly_fill_assembly_name_full (image, aname, FALSE);
+}
+
/**
* mono_stringify_assembly_name:
* @aname: the assembly name.
image->assembly->aname.name, image->assembly, reference->aname.name, reference, reference->ref_count);
} else {
if (image->assembly)
- mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Failed to load assembly %s[%p]\n",
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Failed to load assembly %s[%p].",
image->assembly->aname.name, image->assembly);
}
mono_assemblies_unlock ();
}
+struct HasReferenceAssemblyAttributeIterData {
+ gboolean has_attr;
+};
+
+static gboolean
+has_reference_assembly_attribute_iterator (MonoImage *image, guint32 typeref_scope_token, const char *nspace, const char *name, guint32 method_token, gpointer user_data)
+{
+ gboolean stop_scanning = FALSE;
+ struct HasReferenceAssemblyAttributeIterData *iter_data = (struct HasReferenceAssemblyAttributeIterData*)user_data;
+
+ if (!strcmp (name, "ReferenceAssemblyAttribute") && !strcmp (nspace, "System.Runtime.CompilerServices")) {
+ /* Note we don't check the assembly name, same as coreCLR. */
+ iter_data->has_attr = TRUE;
+ stop_scanning = TRUE;
+ }
+
+ return stop_scanning;
+}
/**
* mono_assembly_has_reference_assembly_attribute:
{
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, TRUE, error);
- return_val_if_nok (error, FALSE);
- if (!attrs)
- return FALSE;
- MonoClass *ref_asm_class = mono_class_try_get_reference_assembly_class ();
- 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
+ /*
+ * This might be called during assembly loading, so do everything using the low-level
+ * metadata APIs.
+ */
+
+ struct HasReferenceAssemblyAttributeIterData iter_data = { FALSE };
+
+ mono_assembly_metadata_foreach_custom_attr (assembly, &has_reference_assembly_attribute_iterator, &iter_data);
+
+ return iter_data.has_attr;
}
/**
}
}
- mono_assemblies_lock ();
-
- if (image->assembly) {
- /*
- * This means another thread has already loaded the assembly, but not yet
- * called the load hooks so the search hook can't find the assembly.
- */
- mono_assemblies_unlock ();
- ass2 = image->assembly;
- g_free (ass);
- g_free (base_dir);
- mono_image_close (image);
- *status = MONO_IMAGE_OK;
- 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
* 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().
- */
+ if (!refonly) {
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_error_cleanup (&refasm_error);
}
+ mono_assemblies_lock ();
+
+ if (image->assembly) {
+ /*
+ * This means another thread has already loaded the assembly, but not yet
+ * called the load hooks so the search hook can't find the assembly.
+ */
+ mono_assemblies_unlock ();
+ ass2 = image->assembly;
+ g_free (ass);
+ g_free (base_dir);
+ mono_image_close (image);
+ *status = MONO_IMAGE_OK;
+ 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;
loaded_assemblies = g_list_prepend (loaded_assemblies, ass);
res = probe_for_partial_name (gacpath, fullname, aname, status);
g_free (gacpath);
+ g_free (fullname);
+ mono_assembly_name_free (aname);
+
if (res)
res->in_gac = TRUE;
else {
MonoDomain *domain = mono_domain_get ();
- MonoReflectionAssembly *refasm;
- refasm = mono_try_assembly_resolve (domain, mono_string_new (domain, name), NULL, FALSE, &error);
+ res = mono_try_assembly_resolve (domain, name, NULL, FALSE, &error);
if (!is_ok (&error)) {
- g_free (fullname);
- mono_assembly_name_free (aname);
mono_error_cleanup (&error);
if (*status == MONO_IMAGE_OK)
*status = MONO_IMAGE_IMAGE_INVALID;
}
-
- if (refasm)
- res = refasm->assembly;
}
-
- g_free (fullname);
- mono_assembly_name_free (aname);
return res;
}