diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index f4591ee19b..bfceafaee1 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1932,9 +1932,8 @@ static void signal_handler(int /*sig*/, siginfo_t* info, void* uct) noexcept const bool is_writing = err & 0x2; #elif defined(ARCH_ARM64) const bool is_executing = uptr(info->si_addr) == uptr(RIP(context)); - const u32 insn = is_executing ? 0 : *reinterpret_cast(RIP(context)); -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) // Current CPU state decoder is reverse-engineered from the linux kernel and may not work on other platforms. const auto decoded_reason = aarch64::decode_fault_reason(context); const bool is_writing = (decoded_reason == aarch64::fault_reason::data_write); @@ -1947,6 +1946,7 @@ static void signal_handler(int /*sig*/, siginfo_t* info, void* uct) noexcept } #else + const u32 insn = is_executing ? 0 : *reinterpret_cast(RIP(context)); const bool is_writing = (insn & 0xbfff0000) == 0x0c000000 || // STR , [, #] (store word with immediate offset) (insn & 0xbfe00000) == 0x0c800000 || // STP , , [, #] (store pair of registers with immediate offset) diff --git a/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.cpp b/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.cpp index 6d3004e82d..7beea61ccb 100644 --- a/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.cpp +++ b/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.cpp @@ -53,6 +53,13 @@ namespace aarch64 auto esr_ctx = find_EL1_esr_context(uctx); return esr_ctx ? esr_ctx->esr : 0; } +#elif defined(__APPLE__) + u64 _read_ESR_EL1(const ucontext_t* uctx) + { + // Easy to read from mcontext + const auto darwin_ctx = reinterpret_cast(uctx->uc_mcontext); + return darwin_ctx->es.ESR; + } #else u64 _read_ESR_EL1(const ucontext_t*) { diff --git a/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.h b/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.h index 5cf5b9288f..eba782af6c 100644 --- a/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.h +++ b/rpcs3/Emu/CPU/Backends/AArch64/AArch64Signal.h @@ -8,6 +8,7 @@ namespace aarch64 // Some renamed kernel definitions, we don't need to include kernel headers directly #pragma pack(push, 1) +#if defined(__linux__) struct aarch64_cpu_ctx_block { u32 magic; @@ -19,6 +20,20 @@ namespace aarch64 aarch64_cpu_ctx_block head; u64 esr; // Exception syndrome register }; +#elif defined(__APPLE__) + struct aarch64_exception_state + { + u64 FAR; // Fault address reg + u32 ESR; // Exception syndrome reg (ESR_EL1) + u32 exception_id; + }; + + struct aarch64_darwin_mcontext64 + { + aarch64_exception_state es; + // Other states we don't care about follow this field + }; +#endif #pragma pack(pop)