#include <mono/metadata/cil-coff.h>
#include <mono/utils/mono-io-portability.h>
#include <mono/utils/atomic.h>
+#include <mono/utils/mono-mutex.h>
#ifndef HOST_WIN32
#include <sys/types.h>
/* If defined, points to the bundled assembly information */
const MonoBundledAssembly **bundles;
+static mono_mutex_t assembly_binding_mutex;
+
/* Loaded assembly binding info */
static GSList *loaded_assembly_bindings = NULL;
check_extra_gac_path_env ();
InitializeCriticalSection (&assemblies_mutex);
+ mono_mutex_init (&assembly_binding_mutex);
+}
+
+static void
+mono_assembly_binding_lock (void)
+{
+ mono_locks_mutex_acquire (&assembly_binding_mutex, AssemblyBindingLock);
+}
+
+static void
+mono_assembly_binding_unlock (void)
+{
+ mono_locks_mutex_release (&assembly_binding_mutex, AssemblyBindingLock);
}
gboolean
{
MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLY];
guint32 cols [MONO_ASSEMBLY_SIZE];
- gint32 machine;
+ gint32 machine, flags;
if (!t->rows)
return FALSE;
aname->public_key = 0;
machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
+ flags = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags;
switch (machine) {
case COFF_MACHINE_I386:
- aname->arch = MONO_PROCESSOR_ARCHITECTURE_X86;
+ /* https://bugzilla.xamarin.com/show_bug.cgi?id=17632 */
+ if (flags & (CLI_FLAGS_32BITREQUIRED|CLI_FLAGS_PREFERRED32BIT))
+ aname->arch = MONO_PROCESSOR_ARCHITECTURE_X86;
+ else if ((flags & 0x70) == 0x70)
+ aname->arch = MONO_PROCESSOR_ARCHITECTURE_NONE;
+ else
+ aname->arch = MONO_PROCESSOR_ARCHITECTURE_MSIL;
break;
case COFF_MACHINE_IA64:
aname->arch = MONO_PROCESSOR_ARCHITECTURE_IA64;
memcpy (aname->public_key_token, entry->to, MONO_PUBLIC_KEY_TOKEN_LENGTH);
- mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY,
"Remapped public key token of retargetable assembly %s from %s to %s",
aname->name, entry->from, entry->to);
return;
remap_keys (dest_aname);
- mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY,
"The request to load the retargetable assembly %s v%d.%d.%d.%d was remapped to %s v%d.%d.%d.%d",
aname->name,
aname->major, aname->minor, aname->build, aname->revision,
}
if (part_name_len == 21 && !g_ascii_strncasecmp (part_name, "ProcessorArchitecture", part_name_len)) {
- if (!g_ascii_strcasecmp (value, "None"))
- arch = MONO_PROCESSOR_ARCHITECTURE_NONE;
- else if (!g_ascii_strcasecmp (value, "MSIL"))
+ if (!g_ascii_strcasecmp (value, "MSIL"))
arch = MONO_PROCESSOR_ARCHITECTURE_MSIL;
else if (!g_ascii_strcasecmp (value, "X86"))
arch = MONO_PROCESSOR_ARCHITECTURE_X86;
return dest_name;
}
-/* LOCKING: Assumes that we are already locked */
+/* LOCKING: assembly_binding lock must be held */
static MonoAssemblyBindingInfo*
search_binding_loaded (MonoAssemblyName *aname)
{
domain->assembly_bindings = g_slist_append_mempool (domain->mp, domain->assembly_bindings, info_copy);
}
+static int
+get_version_number (int major, int minor)
+{
+ return major * 256 + minor;
+}
+
static inline gboolean
info_major_minor_in_range (MonoAssemblyBindingInfo *info, MonoAssemblyName *aname)
{
+ int aname_version_number = get_version_number (aname->major, aname->minor);
if (!info->has_old_version_bottom)
return FALSE;
- if (info->old_version_bottom.major > aname->major || info->old_version_bottom.minor > aname->minor)
+ if (get_version_number (info->old_version_bottom.major, info->old_version_bottom.minor) > aname_version_number)
return FALSE;
- if (info->has_old_version_top && (info->old_version_top.major < aname->major || info->old_version_top.minor < aname->minor))
+ if (info->has_old_version_top && get_version_number (info->old_version_top.major, info->old_version_top.minor) < aname_version_number)
return FALSE;
/* This is not the nicest way to do it, but it's a by-product of the way parsing is done */
return aname;
domain = mono_domain_get ();
- mono_loader_lock ();
+
+ mono_assembly_binding_lock ();
info = search_binding_loaded (aname);
+ mono_assembly_binding_unlock ();
+
if (!info) {
mono_domain_lock (domain);
info = get_per_domain_assembly_binding_info (domain, aname);
mono_domain_unlock (domain);
}
- mono_loader_unlock ();
if (info) {
if (!check_policy_versions (info, aname))
return aname;
g_free (domain_config_file_name);
g_free (domain_config_file_path);
}
- mono_domain_unlock (domain);
- mono_loader_lock ();
- mono_domain_lock (domain);
info2 = get_per_domain_assembly_binding_info (domain, aname);
if (info2) {
}
mono_domain_unlock (domain);
- mono_loader_unlock ();
}
if (!info) {
g_strlcpy ((char *)info->public_key_token, (const char *)aname->public_key_token, MONO_PUBLIC_KEY_TOKEN_LENGTH);
}
- mono_loader_lock ();
+ mono_assembly_binding_lock ();
info2 = search_binding_loaded (aname);
if (info2) {
/* This binding was added by another thread
} else
loaded_assembly_bindings = g_slist_prepend (loaded_assembly_bindings, info);
- mono_loader_unlock ();
+ mono_assembly_binding_unlock ();
if (!info->is_valid || !check_policy_versions (info, aname))
return aname;
GSList *l;
DeleteCriticalSection (&assemblies_mutex);
+ mono_mutex_destroy (&assembly_binding_mutex);
for (l = loaded_assembly_bindings; l; l = l->next) {
MonoAssemblyBindingInfo *info = l->data;
free_assembly_preload_hooks ();
}
-/*LOCKING assumes loader lock is held*/
+/*LOCKING takes the assembly_binding lock*/
void
mono_assembly_cleanup_domain_bindings (guint32 domain_id)
{
- GSList **iter = &loaded_assembly_bindings;
+ GSList **iter;
+ mono_assembly_binding_lock ();
+ iter = &loaded_assembly_bindings;
while (*iter) {
GSList *l = *iter;
MonoAssemblyBindingInfo *info = l->data;
iter = &l->next;
}
}
+ mono_assembly_binding_unlock ();
}
/*