#include <mono/utils/mono-path.h>
#include <mono/metadata/reflection.h>
#include <mono/metadata/coree.h>
+#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>
/* the default search path is empty, the first slot is replaced with the computed value */
static const char*
default_path [] = {
+ NULL,
NULL,
NULL
};
{"System.Data", 0},
{"System.Data.Linq", 2},
{"System.Data.OracleClient", 0},
+ {"System.Data.Services", 2},
+ {"System.Data.Services.Client", 2},
{"System.Data.SqlXml", 0},
{"System.Design", 0},
{"System.DirectoryServices", 0},
{"System.EnterpriseServices", 0},
{"System.Management", 0},
{"System.Messaging", 0},
+ {"System.Net", 2},
{"System.Runtime.Remoting", 0},
{"System.Runtime.Serialization", 3},
{"System.Runtime.Serialization.Formatters.Soap", 0},
{"System.Security", 0},
+ {"System.ServiceModel.Web", 2},
{"System.ServiceProcess", 0},
{"System.Transactions", 0},
{"System.Web", 0},
{"System.Web.Abstractions", 2},
+ {"System.Web.DynamicData", 2},
+ {"System.Web.Extensions", 2},
{"System.Web.Mobile", 0},
{"System.Web.Routing", 2},
{"System.Web.Services", 0},
{"System.Windows.Forms", 0},
{"System.Xml", 0},
+ {"System.Xml.Linq", 2},
+ {"WindowsBase", 3},
{"mscorlib", 0}
};
#endif
/* 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;
gchar buf[4096];
guint buf_size = sizeof (buf);
+ name = NULL;
if (_NSGetExecutablePath (buf, &buf_size) == 0)
name = g_strdup (buf);
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, flags;
if (!t->rows)
return FALSE;
else
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:
+ /* 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;
+ break;
+ case COFF_MACHINE_AMD64:
+ aname->arch = MONO_PROCESSOR_ARCHITECTURE_AMD64;
+ break;
+ case COFF_MACHINE_ARM:
+ aname->arch = MONO_PROCESSOR_ARCHITECTURE_ARM;
+ break;
+ default:
+ break;
+ }
+
return TRUE;
}
InterlockedIncrement (&assembly->ref_count);
}
+/*
+ * CAUTION: This table must be kept in sync with
+ * ivkm/reflect/Fusion.cs
+ */
+
#define SILVERLIGHT_KEY "7cec85d7bea7798e"
#define WINFX_KEY "31bf3856ad364e35"
#define ECMA_KEY "b77a5c561934e089"
{ "System.ComponentModel.Composition", WINFX_KEY, ECMA_KEY },
{ "System.ComponentModel.DataAnnotations", "ddd0da4d3e678217", WINFX_KEY },
{ "System.Core", SILVERLIGHT_KEY, ECMA_KEY },
+ // FIXME: MS uses MSFINAL_KEY for .NET 4.5
+ { "System.Net", SILVERLIGHT_KEY, MSFINAL_KEY },
{ "System.Numerics", WINFX_KEY, ECMA_KEY },
{ "System.Runtime.Serialization", SILVERLIGHT_KEY, ECMA_KEY },
{ "System.ServiceModel", WINFX_KEY, ECMA_KEY },
{ "System.Windows", SILVERLIGHT_KEY, MSFINAL_KEY },
{ "System.Xml", SILVERLIGHT_KEY, ECMA_KEY },
{ "System.Xml.Linq", WINFX_KEY, ECMA_KEY },
- { "System.Xml.Serialization", WINFX_KEY, MSFINAL_KEY }
+ { "System.Xml.Serialization", WINFX_KEY, ECMA_KEY }
};
static void
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,
MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
image->references = g_new0 (MonoAssembly *, t->rows + 1);
+ image->nreferences = t->rows;
}
reference = image->references [index];
mono_assemblies_unlock ();
}
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;
}
corlib = load_in_path (corlib_file, default_path, status, FALSE);
g_free (corlib_file);
-
+
+ if (corlib && !strcmp (runtime->framework_version, "4.5"))
+ default_path [1] = g_strdup_printf ("%s/mono/4.5/Facades", default_path [0]);
+
return corlib;
}
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 ();
}
/*