4 ms·
> Why not allow an x86 application to open an ARM library if it is actually ARM code at run-time? Because the Application Binary Interface (ABI) of ARM and x86
by EdSchouten 4y ago
> Why not allow an x86 application to open an ARM library if it is actually ARM code at run-time?
Because the Application Binary Interface (ABI) of ARM and x86-64 is different. Function calling conventions don't map 1:1, structure layouts may differ, exceptions can't be propagated properly, etc. etc. etc..
That's why Rosetta only allows you to mix code of a single architecture in a given address space, so that it can be emulated as a whole. That way all code that's being executed has the same ABI.
- giyanani 4y agoThe memory ordering is different, too. Apple gets around it by adding support for intel ordering in the m1 cpus, and then changing to that mode on a per-process basis. https://twitter.com/ErrataRob/status/1331735383193903104 https://twitter.com/ErrataRob/status/1331735383193903104 If you mix arm and x86 code inside a process, you can't tell which ordering to use.
- saagarjha 4y agoGod I wish people stopped sharing this thread because it’s full of things that just cause confusion. To respond to your point though it’s a per-thread flag that the kernel can flip for you if Apple had wanted it to. It’s probably better to just run the ARM code with full TSO, though; the performance penalty is like 10-15% for most code, which is probably less than making a system call into the kernel to be rescheduled with the right ordering whenever you wanted to switch. That doesn’t change the fact that the real challenge here is ABI, not ordering.
- lisper 4y ago> Because the Application Binary Interface (ABI) of ARM and x86-64 is different How does Rosettafied x86 code call system code then?
- EdSchouten 4y agoSystem calls tend to have a _very_ basic calling convention. Typically up to six arguments, of which all of them are integers or pointers. No floating-point values. It's fairly easy to translate such calls. Even if translation is non-trivial, there are only a finite number of system calls (hundreds). It's not hard to provide bindings for those.
- lisper 4y agoYeah, I didn't phrase my question very well. I didn't mean "system calls" as in kernel calls. I meant system libraries, i.e. Cocoa frameworks. Quartz. Homekit. That sort of thing.
- EdSchouten 4y agoI think all of those are simply built as universal libraries as well, right?
- lisper 4y agoI have no idea. That's what I'm asking. But I don't think that's the case because Rosetta is a separate download. If it included universal binaries for all the system libraries it would be huge.
- lisper 4y ago> fairly straightforward conversion of x86 code into ARM, albeit with a 1-to-1 mapping between registers rather than following AAPCS or any standard calling convention OK, that explains why I can't dlopen an ARM dylib. But then how does Rosettafied code call system library routines?
- toast0 4y ago> how does Rosettafied code call system library routines? (I have no specific knowledge about how Rosetta works) x86 code (translated or not) needs to call into system libraries with the x86 calling convention. The easiest way would be to have the x86 system libraries, and translate those too, although someone mentioned they're included as pre-translated cache files. System calls (typically made from libc) in x86 will trap into the kernel, but I'd assume the CPU will run the kernel handler in ARM mode... probably? a different handler address for ARM and x86, but either way, some method to determine which type of cpu and use the appropriate syscall numbers and structures depending on the type. It's possible, but I'd think unlikely, that Apple made all the syscalls the same across both architectures, down to the width and alignment of all of the structs.