From 8cd6a94e262fd0596653f4a6127a7c493476c110 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 8 Jan 2023 11:13:01 +0100 Subject: [PATCH] arm dynarec: avoid SIGBUS errors due to unaligned memory access VSTR and VLDR require a 32-bit alignment in armv7. SH4 alignment requirement is identical but ignored (no SH4 address error is raised). So instead of crashing, just align the memory address. Fix for MINIDUMP-1J --- core/rec-ARM/rec_arm.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/core/rec-ARM/rec_arm.cpp b/core/rec-ARM/rec_arm.cpp index 78edfa79f..afd9df04a 100644 --- a/core/rec-ARM/rec_arm.cpp +++ b/core/rec-ARM/rec_arm.cpp @@ -736,8 +736,9 @@ bool ngen_Rewrite(host_context_t &context, void *faultAddress) ass = Arm32Assembler((u8 *)ptr, 12); - //fault offset must always be the addr from ubfx (sanity check) - verify(fault_offs == 0 || fault_offs == (sh4_addr & 0x1FFFFFFF)); + // fault offset must always be the addr from ubfx (sanity check) + // ignore last 2 bits zeroed to avoid sigbus errors + verify(fault_offs == 0 || (fault_offs & ~3) == (sh4_addr & 0x1FFFFFFC)); if (is_sq && !read && optp >= SZ_32I) { @@ -892,6 +893,8 @@ static bool ngen_readm_immediate(RuntimeBlockInfo* block, shil_opcode* op, bool if (isram) { + if (optp == SZ_32F || optp == SZ_64F) + ptr = (void *)((uintptr_t)ptr & ~3); ass.Mov(r0, (u32)ptr); switch(optp) { @@ -1032,6 +1035,8 @@ static bool ngen_writemem_immediate(RuntimeBlockInfo* block, shil_opcode* op, bo if (isram) { + if (optp == SZ_32F || optp == SZ_64F) + ptr = (void *)((uintptr_t)ptr & ~3); ass.Mov(r0, (u32)ptr); switch(optp) { @@ -1153,7 +1158,7 @@ static void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool o genMmuLookup(block, *op, 0, raddr); if (_nvmem_enabled()) { - ass.Bic(r1, raddr, 0xE0000000); + ass.Bic(r1, raddr, optp == SZ_32F || optp == SZ_64F ? 0xE0000003 : 0xE0000000); switch(optp) { @@ -1268,7 +1273,7 @@ static void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool o } if (_nvmem_enabled()) { - ass.Bic(r1, raddr, 0xE0000000); + ass.Bic(r1, raddr, optp == SZ_32F || optp == SZ_64F ? 0xE0000003 : 0xE0000000); switch(optp) {