ntdll: Ensure %cs is correct in sigcontext on x86_64 macOS.
On x86_64 macOS (real Intel/not under Rosetta), a signal delivered to a thread inside a syscall will have CS in sigcontext
set to the kernel's selector (0x07, SYSCALL_CS
in xnu source) instead of the user selector (cs64_sel
: 0x2b, USER64_CS
).
This causes crashes when running a 32-bit CEF sample or Steam: those do lots of async I/O, SIGUSR1 is received often, and CS_sig
is 0x07
if received while in _thread_set_tsd_base
. get_wow_context()
later compares SegCs
to cs64_sel
, sees that it's different, assumes that we are in 32-bit code, and the 32-bit context is used. The top 32-bits of RIP
and every register are stripped off, and the thread crashes when it tries to return after handling the signal.
To fix this, set CS_sig
to cs64_sel
if it's set to 0x07/SYSCALL_CS
. We only make macOS syscalls from 64-bit code.
It appears that macOS has always done this (I tested back to 10.12), but it wasn't an issue until 3a16aabb/!6866 (merged) started doing _thread_set_tsd_base()
outside of a Wine/NT syscall.