summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/mono-6.12.0-add-runpath.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches/mono-6.12.0-add-runpath.patch')
-rw-r--r--gnu/packages/patches/mono-6.12.0-add-runpath.patch185
1 files changed, 185 insertions, 0 deletions
diff --git a/gnu/packages/patches/mono-6.12.0-add-runpath.patch b/gnu/packages/patches/mono-6.12.0-add-runpath.patch
new file mode 100644
index 0000000000..3062bd6a0d
--- /dev/null
+++ b/gnu/packages/patches/mono-6.12.0-add-runpath.patch
@@ -0,0 +1,185 @@
+mono: metadata: add <runpath> element to .config files.
+
+This new element is of the form:
+
+<runpath path="/path1/to/libs:/path2/to/libs:..."/>
+
+(the : will actually be whatever G_SEARCHPATH_SEPARATOR_S is, so likely ; on
+windows and : elsewhere).
+
+* mono/metadata/metadata-internals.h (struct _MonoImage): new 'runpath' field.
+* mono/metadata/mono-config.c (runpath_init, runpath_start, runpath_handler):
+ new functions and parser using them to populate runpath field from <runpath>
+ element.
+ (mono_config_init): register runpath_handler.
+* mono/metadata/assembly.c (mono_assembly_load_full_gac_base_default): new
+ 'requesting' parameter, use it to search the requesting assembly's runpath
+ first.
+ (mono_assembly_request_byname_nosearch): use it.
+
+
+diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c
+index f9feaacf2c1..8c71ad0eb95 100644
+--- a/mono/metadata/assembly.c
++++ b/mono/metadata/assembly.c
+@@ -376,7 +376,7 @@ mono_assembly_invoke_search_hook_internal (MonoAssemblyLoadContext *alc, MonoAss
+ static MonoAssembly*
+ mono_assembly_request_byname_nosearch (MonoAssemblyName *aname, const MonoAssemblyByNameRequest *req, MonoImageOpenStatus *status);
+ static MonoAssembly*
+-mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname, const char *basedir, MonoAssemblyLoadContext *alc, MonoAssemblyContextKind asmctx, MonoImageOpenStatus *status);
++mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname, MonoAssembly *requesting, const char *basedir, MonoAssemblyLoadContext *alc, MonoAssemblyContextKind asmctx, MonoImageOpenStatus *status);
+ static MonoAssembly*
+ chain_redirections_loadfrom (MonoAssemblyLoadContext *alc, MonoImage *image, MonoImageOpenStatus *out_status);
+ static MonoAssembly*
+@@ -4655,7 +4655,7 @@ mono_assembly_request_byname_nosearch (MonoAssemblyName *aname,
+ }
+
+ #ifndef ENABLE_NETCORE
+- result = mono_assembly_load_full_gac_base_default (aname, req->basedir, req->request.alc, req->request.asmctx, status);
++ result = mono_assembly_load_full_gac_base_default (aname, req->requesting_assembly, req->basedir, req->request.alc, req->request.asmctx, status);
+ #endif
+ return result;
+ }
+@@ -4667,6 +4667,7 @@ mono_assembly_request_byname_nosearch (MonoAssemblyName *aname,
+ */
+ MonoAssembly*
+ mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname,
++ MonoAssembly *requesting,
+ const char *basedir,
+ MonoAssemblyLoadContext *alc,
+ MonoAssemblyContextKind asmctx,
+@@ -4718,6 +4719,23 @@ mono_assembly_load_full_gac_base_default (MonoAssemblyName *aname,
+ filename = g_strconcat (aname->name, ext, (const char*)NULL);
+ }
+
++ if (requesting
++ && requesting->image
++ && requesting->image->runpath) {
++ char **runpath = requesting->image->runpath;
++ int j;
++ for (j = 0; runpath[j]; j++) {
++ fullpath = g_build_filename (runpath[j], filename, NULL);
++ result = mono_assembly_request_open (fullpath, &req, status);
++ g_free (fullpath);
++ if (result) {
++ result->in_gac = FALSE;
++ g_free (filename);
++ return result;
++ }
++ }
++ }
++
+ #ifndef DISABLE_GAC
+ const gboolean refonly = asmctx == MONO_ASMCTX_REFONLY;
+
+diff --git a/mono/metadata/image.c b/mono/metadata/image.c
+index e0b86dd3d09..12a8094e4e0 100644
+--- a/mono/metadata/image.c
++++ b/mono/metadata/image.c
+@@ -2363,6 +2363,9 @@ mono_image_close_except_pools (MonoImage *image)
+
+ mono_metadata_clean_for_image (image);
+
++ if (image->runpath)
++ g_strfreev (image->runpath);
++
+ /*
+ * The caches inside a MonoImage might refer to metadata which is stored in referenced
+ * assemblies, so we can't release these references in mono_assembly_close () since the
+diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h
+index 9388d69b0fd..93f4b880c61 100644
+--- a/mono/metadata/metadata-internals.h
++++ b/mono/metadata/metadata-internals.h
+@@ -423,6 +423,12 @@ struct _MonoImage {
+ /**/
+ MonoTableInfo tables [MONO_TABLE_NUM];
+
++ /*
++ Search path to be tried first when looking for assemblies referenced by
++ this image, or NULL. Is a NULL-terminated vector.
++ */
++ char **runpath;
++
+ /*
+ * references is initialized only by using the mono_assembly_open
+ * function, and not by using the lowlevel mono_image_open.
+diff --git a/mono/metadata/mono-config.c b/mono/metadata/mono-config.c
+index d973de53c8c..8888c7b4fac 100644
+--- a/mono/metadata/mono-config.c
++++ b/mono/metadata/mono-config.c
+@@ -21,6 +21,7 @@
+ #include "mono/metadata/metadata-internals.h"
+ #include "mono/metadata/object-internals.h"
+ #include "mono/utils/mono-logger-internals.h"
++#include "mono/utils/mono-path.h"
+
+ #if defined(TARGET_PS3)
+ #define CONFIG_OS "CellOS"
+@@ -464,6 +465,59 @@ aot_cache_handler = {
+ NULL, /* finish */
+ };
+
++static void*
++runpath_init (MonoImage *assembly)
++{
++ return assembly;
++}
++
++static void
++runpath_start (gpointer user_data,
++ const gchar *element_name,
++ const gchar **attribute_names,
++ const gchar **attribute_values)
++{
++ MonoImage *assembly = (MonoImage *) user_data;
++ int i;
++
++ if (strcmp (element_name, "runpath") != 0)
++ return;
++
++ for (i = 0; attribute_names[i]; i++)
++ {
++ if(!strcmp (attribute_names [i], "path"))
++ {
++ char **splitted, **dest;
++
++ splitted = g_strsplit (attribute_values[i],
++ G_SEARCHPATH_SEPARATOR_S,
++ 1000);
++ if (assembly->runpath)
++ g_strfreev (assembly->runpath);
++ assembly->runpath = dest = splitted;
++ while (*splitted) {
++ char *tmp = *splitted;
++ if (*tmp)
++ *dest++ = mono_path_canonicalize (tmp);
++ g_free (tmp);
++ splitted++;
++ }
++ *dest = *splitted;
++ break;
++ }
++ }
++}
++
++static const MonoParseHandler
++runpath_handler = {
++ "runpath",
++ runpath_init,
++ runpath_start,
++ NULL, /* text */
++ NULL, /* end */
++ NULL, /* finish */
++};
++
+ static int inited = 0;
+
+ static void
+@@ -476,6 +530,7 @@ mono_config_init (void)
+ #endif
+ g_hash_table_insert (config_handlers, (gpointer) legacyUEP_handler.element_name, (gpointer) &legacyUEP_handler);
+ g_hash_table_insert (config_handlers, (gpointer) aot_cache_handler.element_name, (gpointer) &aot_cache_handler);
++ g_hash_table_insert (config_handlers, (gpointer) runpath_handler.element_name, (gpointer) &runpath_handler);
+ }
+
+ /**