Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefix exported symbols via UnmanagedCallersOnly attribute #79880

Merged
merged 4 commits into from
Jan 19, 2023
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
6 changes: 3 additions & 3 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -5244,9 +5244,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;
}
}
Expand All @@ -5258,7 +5258,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);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<linker>
<!-- this is here to show how to configure the trimming -->
<assembly fullname="iOS.Device.ExportManagedSymbols.Test">
<type fullname="Program">
<method name="ManagedMethod" />
</type>
</assembly>
</linker>
Original file line number Diff line number Diff line change
@@ -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<int> Main(string[] args)
{
mono_ios_set_summary($"Starting functional test");
Console.WriteLine("Done!");
await Task.Delay(5000);

return 42;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk" TreatAsLocalProperty="MonoForceInterpreter">

<PropertyGroup>
<OutputType>Exe</OutputType>
<MonoForceInterpreter>false</MonoForceInterpreter>
<RunAOTCompilation>true</RunAOTCompilation>
<TestRuntime>true</TestRuntime>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<TargetOS Condition="'$(TargetOS)' == ''">iOS</TargetOS>
<MainLibraryFileName>iOS.Device.ExportManagedSymbols.Test.dll</MainLibraryFileName>
<IncludesTestRunner>false</IncludesTestRunner>
<ExpectedExitCode>42</ExpectedExitCode>
<EnableAggressiveTrimming>true</EnableAggressiveTrimming>
<MonoEnableLLVM>true</MonoEnableLLVM>
<NativeMainSource>$(MSBuildProjectDirectory)/main.m</NativeMainSource>
</PropertyGroup>

<ItemGroup>
<Compile Include="Program.cs" />
<!-- Prevent trimming of the exposed managed method via ILLinker -->
<TrimmerRootDescriptor Include="$(MSBuildProjectDirectory)/ILLink.Descriptors.xml" />
</ItemGroup>
</Project>
106 changes: 106 additions & 0 deletions src/tests/FunctionalTests/iOS/Device/ExportManagedSymbols/main.m
Original file line number Diff line number Diff line change
@@ -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 <UIKit/UIKit.h>
#import <dlfcn.h>
#import "runtime.h"
#include <TargetConditionals.h>

@interface ViewController : UIViewController
@end

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@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]));
}
}