Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ typedef struct MonoAotOptions {
char *outfile;
char *llvm_outfile;
char *data_outfile;
char *export_symbols_outfile;
GList *profile_files;
GList *mibc_profile_files;
gboolean save_temps;
Expand Down Expand Up @@ -5103,6 +5104,7 @@ add_wrappers (MonoAotCompile *acfg)
}
}

GString *export_symbols = g_string_new ("");
/* native-to-managed wrappers */
rows = table_info_get_rows (&acfg->image->tables [MONO_TABLE_METHOD]);
for (int i = 0; i < rows; ++i) {
Expand Down Expand Up @@ -5252,8 +5254,10 @@ MONO_RESTORE_WARNING
mono_error_assert_ok (error);

add_method (acfg, wrapper);
if (export_name)
if (export_name) {
g_hash_table_insert (acfg->export_names, wrapper, export_name);
g_string_append_printf (export_symbols, "%s%s\n", acfg->user_symbol_prefix, export_name);
}
}

g_free (cattr);
Expand All @@ -5265,6 +5269,19 @@ MONO_RESTORE_WARNING
}
}

if (acfg->aot_opts.export_symbols_outfile) {
char *export_symbols_out = g_string_free (export_symbols, FALSE);
FILE* export_symbols_outfile = fopen (acfg->aot_opts.export_symbols_outfile, "w");
if (!export_symbols_outfile) {
fprintf (stderr, "Unable to open specified export_symbols_outfile '%s' to append symbols '%s': %s\n", acfg->aot_opts.export_symbols_outfile, export_symbols_out, strerror (errno));
g_free (export_symbols_out);
exit (1);
}
fprintf (export_symbols_outfile, "%s", export_symbols_out);
g_free (export_symbols_out);
fclose (export_symbols_outfile);
}

/* StructureToPtr/PtrToStructure wrappers */
rows = table_info_get_rows (&acfg->image->tables [MONO_TABLE_TYPEDEF]);
for (int i = 0; i < rows; ++i) {
Expand Down Expand Up @@ -8445,6 +8462,8 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
opts->outfile = g_strdup (arg + strlen ("outfile="));
} else if (str_begins_with (arg, "llvm-outfile=")) {
opts->llvm_outfile = g_strdup (arg + strlen ("llvm-outfile="));
} else if (str_begins_with (arg, "export-symbols-outfile=")) {
opts->export_symbols_outfile = g_strdup (arg + strlen ("export-symbols-outfile="));
} else if (str_begins_with (arg, "temp-path=")) {
opts->temp_path = clean_path (g_strdup (arg + strlen ("temp-path=")));
} else if (str_begins_with (arg, "save-temps")) {
Expand Down
31 changes: 31 additions & 0 deletions src/tasks/AotCompilerTask/MonoAOTCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task
/// </summary>
public string LibraryFilePrefix { get; set; } = "";

/// <summary>
/// Enables exporting symbols of methods decorated with UnmanagedCallersOnly Attribute containing a specified EntryPoint
/// </summary>
public bool EnableUnmanagedCallersOnlyMethodsExport { get; set; }

/// <summary>
/// Path to the directory where LLVM binaries (opt and llc) are found.
/// It's required if UseLLVM is set
Expand Down Expand Up @@ -478,6 +483,7 @@ all assigned to that one partition.
}
}

CheckExportSymbolsFile(_assembliesToCompile);
CompiledAssemblies = ConvertAssembliesDictToOrderedList(compiledAssemblies, _assembliesToCompile).ToArray();
return !Log.HasLoggedErrors;
}
Expand Down Expand Up @@ -729,6 +735,16 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st
}
}

if (EnableUnmanagedCallersOnlyMethodsExport)
{
string exportSymbolsFile = Path.Combine(OutputDir, Path.ChangeExtension(assemblyFilename, ".exportsymbols"));
ProxyFile proxyFile = _cache.NewFile(exportSymbolsFile);
proxyFiles.Add(proxyFile);

aotArgs.Add($"export-symbols-outfile={proxyFile.TempFile}");
aotAssembly.SetMetadata("ExportSymbolsFile", proxyFile.TargetFile);
}

// pass msym-dir if specified
if (MsymPath != null)
{
Expand Down Expand Up @@ -1040,6 +1056,21 @@ private bool TryGetAssemblyName(string asmPath, [NotNullWhen(true)] out string?
}
}

private void CheckExportSymbolsFile(IList<ITaskItem> assemblies)
{
if (!EnableUnmanagedCallersOnlyMethodsExport)
return;

foreach (var assemblyItem in assemblies)
{
string assembly = assemblyItem.GetMetadata("FullPath");
string assemblyFilename = Path.GetFileName(assembly);
string exportSymbolsFile = Path.Combine(OutputDir, Path.ChangeExtension(assemblyFilename, ".exportsymbols"));
if (!File.Exists(exportSymbolsFile))
Log.LogWarning($"EnableUnmanagedCallersOnlyMethodsExport is true, but no .exportsymbols file generated for assembly '{assemblyFilename}'. Check that the AOT compilation mode is full.");
}
}

private static IList<ITaskItem> ConvertAssembliesDictToOrderedList(ConcurrentDictionary<string, ITaskItem> dict, IList<ITaskItem> originalAssemblies)
{
List<ITaskItem> outItems = new(originalAssemblies.Count);
Expand Down