Last-Modified: Mon, 10 Mar 2025 01:42:48 GMT
Expires: Mon, 10 Mar 2025 01:57:48 GMT

<!DOCTYPE html>
<html lang='en'>
<head>
<title>guix - Wojtek's customized Guix</title>
<meta name='generator' content='cgit v1.2.3'/>
<meta name='robots' content='noindex, nofollow'/>
<link rel='stylesheet' type='text/css' href='/cgit-static/cgit.css'/>
<link rel='stylesheet' type='text/css' href='/cgit-static/better-cgit-markdown-heading-color.css'/>
<link rel='shortcut icon' href='/cgit-static/favicon.ico'/>
<link rel='alternate' title='Atom feed' href='https://git.koszko.org/guix/atom/?h=koszko' type='application/atom+xml'/>
</head>
<body>
<div id='cgit'><table id='header'>
<tr>
<td class='logo' rowspan='2'><a href='/'><img src='https://git.koszko.org/cgit-static/cgit.png' alt='cgit logo'/></a></td>
<td class='main'><a href='/'>index</a> : <a href='/guix/'>guix</a></td><td class='form'><form method='get'>
<select name='h' onchange='this.form.submit();'>
<option value='koszko' selected='selected'>koszko</option>
<option value='koszko-scripts'>koszko-scripts</option>
</select> <input type='submit' value='switch'/></form></td></tr>
<tr><td class='sub'>Wojtek's customized Guix</td><td class='sub right'<</td></tr></table>
<table class='tabs'><tr><td>
<a class='active' href='/guix/about/'>about</a><a href='/guix/'>summary</a><a href='/guix/refs/'>refs</a><a href='/guix/log/'>log</a><a href='/guix/tree/'>tree</a><a href='/guix/commit/'>commit</a><a href='/guix/diff/'>diff</a></td><td class='form'><form class='right' method='get' action='/guix/log/'>
<select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='content'><div id='summary'<pre>
mono: metadata: add &lt;runpath&gt; element to .config files.

This new element is of the form:

&lt;runpath path=&quot;/path1/to/libs:/path2/to/libs:...&quot;/&gt;

(the : will actually be whatever G_SEARCHPATH_SEPARATOR_S is, so likely ; on
windows and : elsewhere).

* mono/metadata/metadata-internals.h (struct _MonoImage): new &apos;runpath&apos; field.
* mono/metadata/mono-config.c (runpath_init, runpath_start, runpath_handler):
  new functions and parser using them to populate runpath field from &lt;runpath&gt;
  element.
  (mono_config_init): register runpath_handler.
* mono/metadata/assembly.c (mono_assembly_load_full_gac_base_default): new
  &apos;requesting&apos; parameter, use it to search the requesting assembly&apos;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-&gt;basedir, req-&gt;request.alc, req-&gt;request.asmctx, status);
+	result = mono_assembly_load_full_gac_base_default (aname, req-&gt;requesting_assembly, req-&gt;basedir, req-&gt;request.alc, req-&gt;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-&gt;name, ext, (const char*)NULL);
 		}
 
+                if (requesting
+                    &amp;&amp; requesting-&gt;image
+                    &amp;&amp; requesting-&gt;image-&gt;runpath) {
+                    char **runpath = requesting-&gt;image-&gt;runpath;
+                    int j;
+                    for (j = 0; runpath[j]; j++) {
+                        fullpath = g_build_filename (runpath[j], filename, NULL);
+                        result = mono_assembly_request_open (fullpath, &amp;req, status);
+                        g_free (fullpath);
+                        if (result) {
+                            result-&gt;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-&gt;runpath)
+            g_strfreev (image-&gt;runpath);
+
 	/*
 	 * The caches inside a MonoImage might refer to metadata which is stored in referenced 
 	 * assemblies, so we can&apos;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 &quot;mono/metadata/metadata-internals.h&quot;
 #include &quot;mono/metadata/object-internals.h&quot;
 #include &quot;mono/utils/mono-logger-internals.h&quot;
+#include &quot;mono/utils/mono-path.h&quot;
 
 #if defined(TARGET_PS3)
 #define CONFIG_OS &quot;CellOS&quot;
@@ -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, &quot;runpath&quot;) != 0)
+        return;
+
+    for (i = 0; attribute_names[i]; i++)
+        {
+            if(!strcmp (attribute_names [i], &quot;path&quot;))
+                {
+                    char **splitted, **dest;
+
+                    splitted = g_strsplit (attribute_values[i],
+                                           G_SEARCHPATH_SEPARATOR_S,
+                                           1000);
+                    if (assembly-&gt;runpath)
+                        g_strfreev (assembly-&gt;runpath);
+                    assembly-&gt;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 = {
+    &quot;runpath&quot;,
+    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) &amp;legacyUEP_handler);
 	g_hash_table_insert (config_handlers, (gpointer) aot_cache_handler.element_name, (gpointer) &amp;aot_cache_handler);
+        g_hash_table_insert (config_handlers, (gpointer) runpath_handler.element_name, (gpointer) &amp;runpath_handler);
 }
 
 /**
</pre>
</div></div> <!-- class=content -->
                         <div class=footer>generated by
                             <a href="https://git.zx2c4.com/cgit/about/">
                                 cgit
                             </a>
                         </div>
                        </div> <!-- id=cgit -->
</body>
</html>
