From f429780c9ccce3546e9c9e25c05ed083318428bd Mon Sep 17 00:00:00 2001
From: Ivan Povazan <55002338+ivanpovazan@users.noreply.github.com>
Date: Thu, 19 Jan 2023 11:17:02 +0100
Subject: [PATCH] [mono] Prefix exported symbols via UnmanagedCallersOnly
attribute (#79880)
Fixes https://github.com/dotnet/runtime/issues/79491
---
src/mono/mono/mini/aot-compiler.c | 6 +-
.../ILLink.Descriptors.xml | 8 ++
.../Device/ExportManagedSymbols/Program.cs | 25 +++++
...OS.Device.ExportManagedSymbols.Test.csproj | 23 ++++
.../iOS/Device/ExportManagedSymbols/main.m | 106 ++++++++++++++++++
5 files changed, 165 insertions(+), 3 deletions(-)
create mode 100644 src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/ILLink.Descriptors.xml
create mode 100644 src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/Program.cs
create mode 100644 src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/iOS.Device.ExportManagedSymbols.Test.csproj
create mode 100644 src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/main.m
diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c
index cf7a164eb3e82..de1d1c5efa8c6 100644
--- a/src/mono/mono/mini/aot-compiler.c
+++ b/src/mono/mono/mini/aot-compiler.c
@@ -5208,9 +5208,9 @@ MONO_RESTORE_WARNING
for (j = 0; j < decoded_args->named_args_num; ++j) {
if (decoded_args->named_args_info [j].field && !strcmp (decoded_args->named_args_info [j].field->name, "EntryPoint")) {
named = (const char *)decoded_args->named_args[j]->value.primitive;
- slen = mono_metadata_decode_value (named, &named);
+ slen = mono_metadata_decode_value (named, &named) + (int)strlen(acfg->user_symbol_prefix);
export_name = (char *)g_malloc (slen + 1);
- memcpy (export_name, named, slen);
+ sprintf (export_name, "%s%s", acfg->user_symbol_prefix, named);
export_name [slen] = 0;
}
}
@@ -5222,7 +5222,7 @@ MONO_RESTORE_WARNING
add_method (acfg, wrapper);
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_string_append_printf (export_symbols, "%s\n", export_name);
}
}
diff --git a/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/ILLink.Descriptors.xml b/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/ILLink.Descriptors.xml
new file mode 100644
index 0000000000000..863595682f8f9
--- /dev/null
+++ b/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/ILLink.Descriptors.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/Program.cs b/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/Program.cs
new file mode 100644
index 0000000000000..510a752d5c1b4
--- /dev/null
+++ b/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/Program.cs
@@ -0,0 +1,25 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+public static class Program
+{
+ [DllImport("__Internal")]
+ public static extern void mono_ios_set_summary (string value);
+
+ [UnmanagedCallersOnly(EntryPoint="exposed_managed_method")]
+ public static int ManagedMethod() => 42;
+
+ public static async Task Main(string[] args)
+ {
+ mono_ios_set_summary($"Starting functional test");
+ Console.WriteLine("Done!");
+ await Task.Delay(5000);
+
+ return 42;
+ }
+}
diff --git a/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/iOS.Device.ExportManagedSymbols.Test.csproj b/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/iOS.Device.ExportManagedSymbols.Test.csproj
new file mode 100644
index 0000000000000..be52903a35524
--- /dev/null
+++ b/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/iOS.Device.ExportManagedSymbols.Test.csproj
@@ -0,0 +1,23 @@
+
+
+
+ Exe
+ false
+ true
+ true
+ $(NetCoreAppCurrent)
+ iOS
+ iOS.Device.ExportManagedSymbols.Test.dll
+ false
+ 42
+ true
+ true
+ $(MSBuildProjectDirectory)/main.m
+
+
+
+
+
+
+
+
diff --git a/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/main.m b/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/main.m
new file mode 100644
index 0000000000000..067a52edfbfdf
--- /dev/null
+++ b/src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/main.m
@@ -0,0 +1,106 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#import
+#import
+#import "runtime.h"
+#include
+
+@interface ViewController : UIViewController
+@end
+
+@interface AppDelegate : UIResponder
+@property (strong, nonatomic) UIWindow *window;
+@property (strong, nonatomic) ViewController *controller;
+@end
+
+@implementation AppDelegate
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ self.controller = [[ViewController alloc] initWithNibName:nil bundle:nil];
+ self.window.rootViewController = self.controller;
+ [self.window makeKeyAndVisible];
+ return YES;
+}
+@end
+
+UILabel *summaryLabel;
+UITextView* logLabel;
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ CGRect applicationFrame = [[UIScreen mainScreen] bounds];
+ logLabel = [[UITextView alloc] initWithFrame:
+ CGRectMake(2.0, 50.0, applicationFrame.size.width - 2.0, applicationFrame.size.height - 50.0)];
+ logLabel.font = [UIFont systemFontOfSize:9.0];
+ logLabel.backgroundColor = [UIColor blackColor];
+ logLabel.textColor = [UIColor greenColor];
+ logLabel.scrollEnabled = YES;
+ logLabel.alwaysBounceVertical = YES;
+#ifndef TARGET_OS_TV
+ logLabel.editable = NO;
+#endif
+ logLabel.clipsToBounds = YES;
+
+ summaryLabel = [[UILabel alloc] initWithFrame: CGRectMake(10.0, 0.0, applicationFrame.size.width - 10.0, 50)];
+ summaryLabel.textColor = [UIColor whiteColor];
+ summaryLabel.font = [UIFont boldSystemFontOfSize: 12];
+ summaryLabel.numberOfLines = 2;
+ summaryLabel.textAlignment = NSTextAlignmentLeft;
+#if !TARGET_OS_SIMULATOR || FORCE_AOT
+ summaryLabel.text = @"Loading...";
+#else
+ summaryLabel.text = @"Jitting...";
+#endif
+ [self.view addSubview:logLabel];
+ [self.view addSubview:summaryLabel];
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ void *del = dlsym (RTLD_DEFAULT, "exposed_managed_method");
+ NSAssert(del != NULL, @"'exposed_managed_method' not found");
+ mono_ios_runtime_init ();
+ });
+}
+
+@end
+
+// called from C#
+void
+invoke_external_native_api (void (*callback)(void))
+{
+ if (callback)
+ callback();
+}
+
+// can be called from C# to update UI
+void
+mono_ios_set_summary (const char* value)
+{
+ NSString* nsstr = [NSString stringWithUTF8String:value];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ summaryLabel.text = nsstr;
+ });
+}
+
+// can be called from C# to update UI
+void
+mono_ios_append_output (const char* value)
+{
+ NSString* nsstr = [NSString stringWithUTF8String:value];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ logLabel.text = [logLabel.text stringByAppendingString:nsstr];
+ CGRect caretRect = [logLabel caretRectForPosition:logLabel.endOfDocument];
+ [logLabel scrollRectToVisible:caretRect animated:NO];
+ [logLabel setScrollEnabled:NO];
+ [logLabel setScrollEnabled:YES];
+ });
+}
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}