5 ms·
Sorry, I don't understand what you are trying to say. Of course the CPU knows about pages and the executable bit? But there is no executable bit on a page fille
by anyfoo 5y ago
Sorry, I don't understand what you are trying to say. Of course the CPU knows about pages and the executable bit? But there is no executable bit on a page filled with x86 code running on an ARM CPU, because the ARM CPU cannot execute that. It can only execute the translated ARM code that sits somewhere else, essentially out of sight for the x86 program.
- chrisseaton 5y ago> Sorry, I don't understand what you are trying to say. Rosetta implements x86 execution bit semantics. It does this by invalidating translated pages when the system call to set the execution bit is set. Which bit do you not understand? How do you think for example the JVM works today on Rosetta?
- anyfoo 5y ago> Which bit do you not understand? How you are disagreeing with me, then? The actual page table entries that the ARM CPU looks at will never mark a page containing x86 code as executable. x86 execution bit semantics are implemented, but on a different layer. From the ARM CPU's POV, the x86 code is always just data.
- chrisseaton 5y ago> those are not something the x86 code knows about The implementation of AMD64 is in software. It knows about page executable bits. The 'x86' code knows about them. Again, how do you think things like V8 and the JVM work on Rosetta otherwise?
- anyfoo 5y ago> The implementation of AMD64 is in software. It knows about page executable bits. The 'x86' code knows about them. Where did I claim anything else? The thing I claimed the x86 code does not know about is the pages that contain the translated ARM code, which are distinct from the pages that contain the x86 code. The former pages are marked executable in the actual page tables, the latter pages have a software executable bit in the kernel, but are not marked as such in the actual page tables. > Again, how do you think things like V8 and the JVM work on Rosetta otherwise? Did I write something confusing that gave the wrong impression? My last answer says: "x86 execution bit semantics are implemented, but on a different layer".
- brigade 5y agoThe JIT'd ARM code pages are W^X, and that's not optional on macOS ARM. But W^X was opt-in on x86 macOS, so for backwards compatibility Rosetta can't require the x86 code to implement it in order to function. So your model of how Rosetta works is off - the translation would need to support remapping the original code page read-only regardless of whether the x86 code did so, and letting a subsequent write invalidate the JIT cache of that page, instead of relying solely on the emulated process to implement W^X.
- chrisseaton 5y agoSystems that install new machine code without changing page permissions run an instruction cache barrier after installing and before running. Rosetta catches this instruction.
- brigade 5y agoX86 does not require any explicit barrier if you modify through the same virtual address as execution, so no.
- chrisseaton 5y agoNot sure which bit you’re saying ‘no’ to. Most JITs do execution an icache flush, and Rosetta does catch it to invalidate their code. For example https://github.com/openjdk/jdk/blob/master/src/hotspot/cpu/x86/icache_x86.cpp https://github.com/openjdk/jdk/blob/master/src/hotspot/cpu/x... Otherwise, how do you think it works?
- saagarjha 5y agox86 does not require an icache flush because it has a unified cache. Rosetta emulates this correctly, which means it must be able to invalidate its code without encountering such an instruction.
- chrisseaton 5y ago