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] Work around arm64 MacCatalyst unavailable JITing API #51669

Merged
merged 3 commits into from
Apr 23, 2021

Conversation

lambdageek
Copy link
Member

  • To JIT on Apple Silicon the application must call pthread_jit_write_protect_np (0) before writing to a code page and then pthread_jit_write_protect_np (1) before executing JITed code.

  • Catalyst apps are Mac apps that get to use iOS frameworks (as well as some mac frameworks). The API access is guarded by __API_AVAILABLE and __API_UNAVAILABLE macros in Apple framework headers. If an API is not explicitly marked for catalyst, clang will follow the ios availability.

Unfortunately, pthread_jit_write_protect_np is marked like this:

__API_AVAILABLE(macos(11.0))
__API_UNAVAILABLE(ios, tvos, watchos)
void pthread_jit_write_protect_np(int enabled);

So a Catalyst app running on arm64 cannot call it. It will get a compile-time error.

src/mono/mono/utils/mono-codeman.c:669:3: error: 'pthread_jit_write_protect_np' is unavailable: not available on macCatalyst
                  pthread_jit_write_protect_np (0);
                  ^
  /Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/usr/include/pthread.h:561:6: note: 'pthread_jit_write_protect_np' has been explicitly marked unavailable here
  void pthread_jit_write_protect_np(int enabled);
       ^

Turns out the symbol pthread_jit_write_protect_np is actually present in the Catalyst framework libraries, and it does the right thing.

This PR works around the unfortunate pthread.h declaration by not using it.

We create a new .c file that included our own declaration

void pthread_jit_write_protect_np(int enabled);

And then a new mono_jit_write_protect function that calls the pthread function.


Another option would be to use something like

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability" 
...
#pragma clang diagnostic pop

around the offending callsites. But neither ignoring -Wpartial-availability nor -Wunguarded-availability-new seem to have any effect on the compilation error.


Caveat: It's not yet clear whether this is ok to do in a retail (App Store) app.

The C code already has HOST_MACCAT ifdefs.  HOST_MACCATALYST isn't used.
The symbol is present in the pthread.h header but is marked
__API_UNAVAILABLE(ios) which prevents us from using it.  The symbol is
present and is usable in Catalyst on arm64.  Add a file that includes
our own declaration of the method and call it from
mono_codeman_enable_write/mono_codeman_disable_write.
src/mono/CMakeLists.txt Outdated Show resolved Hide resolved
@lambdageek lambdageek merged commit a9f1207 into dotnet:main Apr 23, 2021
@karelz karelz added this to the 6.0.0 milestone May 20, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jun 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants