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

Mono AOT compiler does not prefix exported UnmanagedCallersOnly symbols with underscore when targeting iOS #79491

Closed
ivanpovazan opened this issue Dec 10, 2022 · 1 comment · Fixed by #79880
Assignees
Milestone

Comments

@ivanpovazan
Copy link
Member

ivanpovazan commented Dec 10, 2022

Description

If a method is marked with UnmanagedCallersOnlyAttribute and a named export is specified via EntryPoint e.g.,

[UnmanagedCallersOnly(EntryPoint="exposed_managed_method")]
    public static int ManagedMethod() => 42;

Mono AOT compiler exports the symbols as-is without prefixing it with an _ which is required on iOS platforms.
This results in failures when trying to load the symbol dynamically from the native code via:

void *del = dlsym (RTLD_DEFAULT, "exposed_managed_method");

Repro

To reproduce, apply the following patch:

diff --git a/src/mono/sample/iOS/Program.cs b/src/mono/sample/iOS/Program.cs
index 603ff2e4ebc..fbdc8032daa 100644
--- a/src/mono/sample/iOS/Program.cs
+++ b/src/mono/sample/iOS/Program.cs
@@ -24,6 +24,9 @@ private static void OnButtonClick()
         ios_set_text("OnButtonClick! #" + counter++);
     }
 
+    [UnmanagedCallersOnly(EntryPoint="exposed_managed_method")]
+    public static int ManagedMethod() => 42;
+
 #if CI_TEST
     public static async Task<int> Main(string[] args)
 #else
diff --git a/src/mono/sample/iOS/Program.csproj b/src/mono/sample/iOS/Program.csproj
index 0e6aa8777fa..f0187ba8f81 100644
--- a/src/mono/sample/iOS/Program.csproj
+++ b/src/mono/sample/iOS/Program.csproj
@@ -16,6 +16,10 @@
     <TrimMode>Link</TrimMode>
   </PropertyGroup>
 
+  <ItemGroup>
+    <TrimmerRootDescriptor Include="$(MSBuildThisFileDirectory)ILLink.Descriptors.xml" />
+  </ItemGroup>
+
   <PropertyGroup Condition="'$(TargetOS)' == 'MacCatalyst'">
     <DevTeamProvisioning Condition="'$(TargetOS)' == 'MacCatalyst' and '$(DevTeamProvisioning)' == ''">adhoc</DevTeamProvisioning>
     <EnableAppSandbox Condition="'$(EnableAppSandbox)' == ''">false</EnableAppSandbox>
@@ -79,6 +83,7 @@
         TargetOS="$(TargetOS)"
         Arch="$(TargetArchitecture)"
         ProjectName="$(AppName)"
+        NativeMainSource="$(MSBuildThisFileDirectory)/main.m"
         MonoRuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackDir)runtimes\$(TargetOS.ToLower())-$(TargetArchitecture)\native\include\mono-2.0"
         Assemblies="@(BundleAssemblies)"
         MainLibraryFileName="Program.dll"
diff --git a/src/mono/sample/iOS/main.m b/src/mono/sample/iOS/main.m
index 0ab407e8398..e6d8a3f31f4 100644
--- a/src/mono/sample/iOS/main.m
+++ b/src/mono/sample/iOS/main.m
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 #import <UIKit/UIKit.h>
+#import <dlfcn.h>
 #import "runtime.h"
 
 @interface ViewController : UIViewController
@@ -45,6 +46,8 @@ void (*clickHandlerPtr)(void);
     [self.view addSubview:button];
 
     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 ();
     });
 }

And add the ILLink.Descriptors.xml file to the project directory with the following contents:

<linker>
  <!-- this is here to show how to configure the trimming -->
  <assembly fullname="Program">
    <type fullname="Program">
        <method name="ManagedMethod" />
    </type>
  </assembly>
</linker>

Finally, build it with:

cd src/mono/sample/iOS
make build-appbundle MONO_ARCH=arm64 AOT=true DEPLOY_AND_RUN=true

Workaround

Possible workaround is to prefix the EntryPoint name with the underscore, but then such code is not platform independent.

/cc @mdh1418 @steveisok

@steveisok
Copy link
Member

steveisok commented Dec 21, 2022

@mdh1418 as this issue mentions, the symbol won't be written w/, for example, an underscore on osx, so

g_string_append_printf (export_symbols, "%s%s\n", acfg->user_symbol_prefix, export_name);
will write the incorrect symbol name.

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Dec 21, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jan 19, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Feb 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants