Files
BepInEx/BepInEx.Preloader
Chris Dobbyn 01fd4aabe2 v5: Fix plugin loading on native arm64 macOS (#1402)
BepInEx loads no plugins and writes no log when the game runs as arm64
rather than under Rosetta. There is no crash and no error.

MonoMod picks DetourNativeMonoPosixPlatform on Mono, whose MakeWritable
and MakeExecutable call mprotect with PROT_READ|PROT_WRITE|PROT_EXEC.
macOS on Apple Silicon answers EACCES: without the entitlement
com.apple.security.cs.allow-unsigned-executable-memory no page may be
writable and executable at once. Unity ships allow-jit instead, so
Mono's code lives in a MAP_JIT region, which also refuses mach_vm_write
with KERN_INVALID_ADDRESS.

The failure is invisible. DetourHelper.get_Runtime sets _RuntimeInit
before constructing the platform and returns null on every later call
once set, so the one EACCES turns every subsequent Harmony patch into a
NullReferenceException in DetourHelper.GetIdentifiable. HarmonyX
swallows the first inside Harmony..cctor, and Entrypoint.Start writes
the rest to preloader_*.log beside the executable, not to LogOutput.log.

AppleSiliconDetourFix installs a detour platform that keeps
DetourNativeARMPlatform's AArch64 encoding and routes code writes
through doorstop_jit_memcpy, which brackets its memcpy with
pthread_jit_write_protect_np. That toggle cannot be done from managed
code, because it removes execute permission for the calling thread and
that thread is running JIT-compiled code.

XTermFix forced DetourNativeX86Platform on every non-Windows target,
which on Apple Silicon encodes x86 branches into arm64 method bodies and
reinstates the failing mprotect. It is now skipped when the fix applies.

Preloader.Run logs a warning if the fix cannot install, so this cannot
fail silently again.

Requires doorstop_jit_memcpy from UnityDoorstop.
2026-09-20 17:51:59 +02:00
..
2020-08-06 22:44:24 +03:00
2020-08-30 17:44:53 +10:00