mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-26 12:48:39 +08:00
37b3e787de
Rosetta 2 does not expose Intel SHA-NI to translated x86 processes, so a guest using sha1msg1/sha1msg2/sha1nexte/sha1rnds4 hits #UD and aborts (PPSA22102 crashes almost immediately). Decode those four opcodes on the SIGILL recovery path, evaluate them in software (Sha1InstructionEmulator), write the result back into the guest's XMM registers, and step past. The XMM state is bridged through the macOS/Linux signal<->CONTEXT plumbing: the handler copies the mcontext XMM block to the Win64 CONTEXT the shared recovery logic uses and back, but only for SIGILL (the sole signal whose recovery may touch XMM) — not on every demand-paging SIGSEGV. Critically, the recovery path is now allocation-free. The original decode allocated managed arrays (new byte[]) *inside the signal handler*; a fault can interrupt the GC mid-operation, and PPSA22102's tight 99-instruction SHA-1 loop re-entered the allocator hard enough to corrupt the thread's allocation context — detonating later as a hard "Invalid Program: attempted to call a UnmanagedCallersOnly method" at the next managed allocation (MetalVideoPresenter.CreateBlackFrame). The Iced decoder/reader/buffer are now thread-static and reused; operand reads use stackalloc via a new Span<byte> TryReadHostBytes overload. SHA-1 math independently verified against a reference implementation (4 message-schedule/round vectors + all four round functions). Result: PPSA22102 goes from crash-at-~0 to 66M imports, past the splash-hide, into the shared 0-DCB wait wall (no draws yet, but no crash). void Terrarium, Dream Sara, Silent Hill unregressed. 378 Libs tests pass.