Here's a tutorial for a simple JIT that uses mmap() with PROT_EXEC to write machine code to before executing:
Here's a tutorial for a simple JIT that uses mmap() with PROT_EXEC to write machine code to before executing:
So what you'll do is silently enforce W^X to trap code modifications, but not propagate those traps to the emulated code.
I don't see anything here that requires extra kernel hooks.
What that practically means is that x86 executable pages get mapped as RO by default as seen by the ARM side even if they would normally be RWX. Modifications trap, the handler mprotects the pages as writeable, flush the translation cache for that region, then returns from the trap. Then on an x86 jump to that region, the JIT cache sees no traces for that region, marks the page as RO again so that modifications will trap, and starts recompiling (or maybe just interpreting; they may be using a tiered approach in the JIT).
This is some serious black magic, especially if it actually works. Even if it only works some of the time I give it an A for effort, since they could easily have just said "JITs will not work with Rosetta." Most applications do not contain JITs.
My guess is there are enough important Mac apps that contain JITs of some form to merit this work, probably high performance math and graphics kernels that JIT processing pipelines or something like that. I wonder if some pro studio editing applications do this.
Java apps and JavaScript apps (Electron) come to mind.
Some apps out there are between a rock and a hard place if it weren't for rosetta.
If there were ever a time and a place for black magic, it would be this use case: swapping out an enormous layer (the hardware) at the bottom of the stack, while keeping everything at the top of the stack working seamlessly.