Work around Rosetta clobbering startup registers on M1 Macs (issue #429) (#453)

Rosetta doesn't correctly respect the startup registers as defined in LC_UNIXTHREAD
which makes platform detection go awry. But at least Rosetta appears to consistently
set rbx to 0x00000000ffffffff and rdx to 0x0000000000000001 at startup for every
x64 executable I could get my hands on. So we use that to detect Rosetta's presence
and set up the correct registers for XNU.
This commit is contained in:
Daniil Kulchenko 2022-06-27 16:28:59 -07:00 committed by GitHub
parent 5297897ba1
commit 9f8e6c10dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 4 deletions

View file

@ -213,7 +213,18 @@ macho: .long 0xFEEDFACE+1
//
// @see APE_LOADER_ENTRY
// @see ape/loader.h
_start: mov %rsp,%rsi
_start:
// Hack for detecting M1 Rosetta environment.
// https://github.com/jart/cosmopolitan/issues/429#issuecomment-1166704377
cmp $-1,%ebx
jne 0f
cmp $+1,%edx
jne 0f
mov $XNU,%dl
xor %ecx,%ecx
0: mov %rsp,%rsi
jmp ApeLoader
.endfn _start,globl

View file

@ -113,7 +113,18 @@ macho: .long 0xFEEDFACE+1
.endobj macho,globl
.align 64
_start: mov %rsp,%rsi
_start:
// Hack for detecting M1 Rosetta environment.
// https://github.com/jart/cosmopolitan/issues/429#issuecomment-1166704377
cmp $-1,%ebx
jne 0f
cmp $+1,%edx
jne 0f
mov $XNU,%dl
xor %ecx,%ecx
0: mov %rsp,%rsi
jmp ApeLoader
.endfn _start,globl

View file

@ -595,11 +595,11 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl,
// detect freebsd
if (handoff) {
os = handoff->os;
} else if (SupportsXnu() && dl == XNU) {
os = XNU;
} else if (SupportsFreebsd() && di) {
os = FREEBSD;
sp = (long *)di;
} else if (SupportsXnu() && dl == XNU) {
os = XNU;
} else {
os = 0;
}

View file

@ -31,6 +31,18 @@
// @noreturn
_start:
#if SupportsXnu()
// Hack for detecting M1 Rosetta environment.
// https://github.com/jart/cosmopolitan/issues/429#issuecomment-1166704377
cmp $-1,%ebx
jne 0f
cmp $+1,%edx
jne 0f
mov $XNU,%cl
xor %edi,%edi
0:
#endif
#if SupportsFreebsd()
// detect free besiyata dishmaya
test %rdi,%rdi