Hi Quinn — following up from DTS case 22070584.
I'm working on a Windows compatibility runtime (Wine plus a CPU translator) that runs natively on Apple Silicon. 64-bit x86 Windows programs work fine. 32-bit ones don't, because they need address space in the low 4 GB: guest pointers are 32-bit, and some Windows structures sit at fixed addresses like 0x7ffe0000 that programs read directly.
On arm64 I can't get anything down there:
task_info(TASK_VM_INFO) -> min_address 0x100ea0000
mmap(0x7ffe0000, MAP_FIXED) -> ENOMEM
mach_vm_allocate(0x7ffe0000, VM_FLAGS_FIXED) -> KERN_INVALID_ADDRESS
There's also nothing below 4 GB to remove: mach_vm_region finds no entry there at all, and mach_vm_deallocate(0, 4 GB) returns KERN_SUCCESS without changing anything. Building with a smaller __PAGEZERO doesn't help either — every size I tried (0x1000, 0x4000, 0x10000, 0x100000, 0x1000000, 0x10000000, 0x80000000) gets SIGKILLed before main, with no crash report. Ad-hoc signing, the hardened runtime and -no_pie made no difference.
I did notice /usr/libexec/rosetta/runtime is arm64 with no __PAGEZERO segment at all and __TEXT at vmaddr 0, so the kernel can clearly do this, at least for platform binaries.
Is there a supported way for a third-party arm64 process to map below 4 GB — an entitlement, a spawn attribute, something I've missed? If the answer is no, that's fine, I'd just like to know so I can stop looking and plan around it.
I have two small test programs that print all of the above if they'd be useful.
2
0
246