diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 8c7c6cdc8d6..7cdf148488d 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1930,6 +1930,70 @@ NTSTATUS WINAPI NtCallbackReturn( void *ret_ptr, ULONG ret_len, NTSTATUS status user_mode_callback_return( ret_ptr, ret_len, status, NtCurrentTeb() ); } +#ifdef __APPLE__ +/*********************************************************************** + * handle_cet_nop + * + * Check if the fault location is an Intel CET instruction that should be treated as a NOP. + * Rosetta on Big Sur throws an exception for this, but is fixed in Monterey. + * CW HACK 20186 + */ +static inline BOOL handle_cet_nop( ucontext_t *sigcontext, CONTEXT *context ) +{ + BYTE instr[16]; + unsigned int i, prefix_count = 0; + unsigned int len = virtual_uninterrupted_read_memory( (BYTE *)context->Rip, instr, sizeof(instr) ); + + for (i = 0; i < len; i++) switch (instr[i]) + { + /* instruction prefixes */ + case 0x2e: /* %cs: */ + case 0x36: /* %ss: */ + case 0x3e: /* %ds: */ + case 0x26: /* %es: */ + case 0x40: /* rex */ + case 0x41: /* rex */ + case 0x42: /* rex */ + case 0x43: /* rex */ + case 0x44: /* rex */ + case 0x45: /* rex */ + case 0x46: /* rex */ + case 0x47: /* rex */ + case 0x48: /* rex */ + case 0x49: /* rex */ + case 0x4a: /* rex */ + case 0x4b: /* rex */ + case 0x4c: /* rex */ + case 0x4d: /* rex */ + case 0x4e: /* rex */ + case 0x4f: /* rex */ + case 0x64: /* %fs: */ + case 0x65: /* %gs: */ + case 0x66: /* opcode size */ + case 0x67: /* addr size */ + case 0xf0: /* lock */ + case 0xf2: /* repne */ + case 0xf3: /* repe */ + if (++prefix_count >= 15) return FALSE; + continue; + + case 0x0f: /* extended instruction */ + if (i == len - 1) return 0; + switch (instr[i + 1]) + { + case 0x1E: + /* RDSSPD/RDSSPQ: (prefixes) 0F 1E (modrm) */ + RIP_sig(sigcontext) += prefix_count + 3; + TRACE_(seh)( "skipped RDSSPD/RDSSPQ instruction\n" ); + return TRUE; + } + break; + default: + return FALSE; + } + return FALSE; +} +#endif /*********************************************************************** * is_privileged_instr @@ -2275,6 +2339,10 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; break; case TRAP_x86_PRIVINFLT: /* Invalid opcode exception */ +#ifdef __APPLE__ + /* CW HACK 20186 */ + if (handle_cet_nop( ucontext, &context.c )) return; +#endif rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; break; case TRAP_x86_STKFLT: /* Stack fault */