Skip to content

Commit

Permalink
[mono] Export unmanagedcallersonly method symbols (#79424)
Browse files Browse the repository at this point in the history
* [mono] Add export_symbols_outfile parameter
[mono] Export EntryPoint of methods decorated with UnmanagedCallersOnlyAttribute to specified export_symbols_outfile

* [mono] Create export file and export symbols iff there are specified EntryPoints

* [task] Bootstrap export-symbols-outfile mono aot compiler option to MonoAOTCompiler Task

* Format symbols based on platform

* Address feedback

* Check for exportsymbols when EnableUnmanagedCallersOnlyMethodsExport is true
  • Loading branch information
mdh1418 committed Dec 19, 2022
1 parent c9175cc commit 73b5ac0
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
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 @@ private bool ExecuteInternal()
}
}

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

0 comments on commit 73b5ac0

Please sign in to comment.