132 |
|
#endif |
133 |
|
|
134 |
|
|
135 |
+ |
// Enable emulation of unaligned lmw/stmw? |
136 |
+ |
#define EMULATE_UNALIGNED_LOADSTORE_MULTIPLE 1 |
137 |
+ |
|
138 |
|
// Enable Execute68k() safety checks? |
139 |
|
#define SAFE_EXEC_68K 0 |
140 |
|
|
219 |
|
static void *extra_stack = NULL; // Stack for SIGSEGV inside interrupt handler |
220 |
|
static bool emul_thread_fatal = false; // Flag: MacOS thread crashed, tick thread shall dump debug output |
221 |
|
static sigregs sigsegv_regs; // Register dump when crashed |
222 |
+ |
static const char *crash_reason = NULL; // Reason of the crash (SIGSEGV, SIGBUS, SIGILL) |
223 |
|
#endif |
224 |
|
|
225 |
|
uintptr SheepMem::zero_page = 0; // Address of ro page filled in with zeros |
743 |
|
#endif |
744 |
|
|
745 |
|
#if !EMULATED_PPC |
746 |
< |
// Install SIGSEGV handler |
746 |
> |
// Install SIGSEGV and SIGBUS handlers |
747 |
|
sigemptyset(&sigsegv_action.sa_mask); // Block interrupts during SEGV handling |
748 |
|
sigaddset(&sigsegv_action.sa_mask, SIGUSR2); |
749 |
|
sigsegv_action.sa_handler = (__sighandler_t)sigsegv_handler; |
754 |
|
ErrorAlert(str); |
755 |
|
goto quit; |
756 |
|
} |
757 |
+ |
if (sigaction(SIGBUS, &sigsegv_action, NULL) < 0) { |
758 |
+ |
sprintf(str, GetString(STR_SIGSEGV_INSTALL_ERR), strerror(errno)); |
759 |
+ |
ErrorAlert(str); |
760 |
+ |
goto quit; |
761 |
+ |
} |
762 |
|
|
763 |
|
// Install SIGILL handler |
764 |
|
sigemptyset(&sigill_action.sa_mask); // Block interrupts during ILL handling |
822 |
|
} |
823 |
|
|
824 |
|
#if !EMULATED_PPC |
825 |
< |
// Uninstall SIGSEGV handler |
825 |
> |
// Uninstall SIGSEGV and SIGBUS handlers |
826 |
|
sigemptyset(&sigsegv_action.sa_mask); |
827 |
|
sigsegv_action.sa_handler = SIG_DFL; |
828 |
|
sigsegv_action.sa_flags = 0; |
829 |
|
sigaction(SIGSEGV, &sigsegv_action, NULL); |
830 |
+ |
sigaction(SIGBUS, &sigsegv_action, NULL); |
831 |
|
|
832 |
|
// Uninstall SIGILL handler |
833 |
|
sigemptyset(&sigill_action.sa_mask); |
1108 |
|
// Yes, dump registers |
1109 |
|
pt_regs *r = (pt_regs *)&sigsegv_regs; |
1110 |
|
char str[256]; |
1111 |
< |
sprintf(str, "SIGSEGV\n" |
1111 |
> |
if (crash_reason == NULL) |
1112 |
> |
crash_reason = "SIGSEGV"; |
1113 |
> |
sprintf(str, "%s\n" |
1114 |
|
" pc %08lx lr %08lx ctr %08lx msr %08lx\n" |
1115 |
|
" xer %08lx cr %08lx \n" |
1116 |
|
" r0 %08lx r1 %08lx r2 %08lx r3 %08lx\n" |
1121 |
|
" r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n" |
1122 |
|
" r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n" |
1123 |
|
" r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n", |
1124 |
+ |
crash_reason, |
1125 |
|
r->nip, r->link, r->ctr, r->msr, |
1126 |
|
r->xer, r->ccr, |
1127 |
|
r->gpr[0], r->gpr[1], r->gpr[2], r->gpr[3], |
1564 |
|
transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break; |
1565 |
|
case 45: // sthu |
1566 |
|
transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break; |
1567 |
+ |
#if EMULATE_UNALIGNED_LOADSTORE_MULTIPLE |
1568 |
+ |
case 46: // lmw |
1569 |
+ |
if (sig == SIGBUS) { |
1570 |
+ |
uint32 ea = (ra == 0 ? 0 : r->gpr[ra]) + imm; |
1571 |
+ |
D(bug("WARNING: unaligned lmw to EA=%08x from IP=%08x\n", ea, r->nip)); |
1572 |
+ |
for (int i = rd; i <= 31; i++) { |
1573 |
+ |
r->gpr[i] = ReadMacInt32(ea); |
1574 |
+ |
ea += 4; |
1575 |
+ |
} |
1576 |
+ |
r->nip += 4; |
1577 |
+ |
goto rti; |
1578 |
+ |
} |
1579 |
+ |
break; |
1580 |
+ |
case 47: // stmw |
1581 |
+ |
if (sig == SIGBUS) { |
1582 |
+ |
uint32 ea = (ra == 0 ? 0 : r->gpr[ra]) + imm; |
1583 |
+ |
D(bug("WARNING: unaligned stmw to EA=%08x from IP=%08x\n", ea, r->nip)); |
1584 |
+ |
for (int i = rd; i <= 31; i++) { |
1585 |
+ |
WriteMacInt32(ea, r->gpr[i]); |
1586 |
+ |
ea += 4; |
1587 |
+ |
} |
1588 |
+ |
r->nip += 4; |
1589 |
+ |
goto rti; |
1590 |
+ |
} |
1591 |
+ |
break; |
1592 |
+ |
#endif |
1593 |
|
} |
1594 |
|
|
1595 |
|
// Ignore ROM writes |
1625 |
|
} |
1626 |
|
|
1627 |
|
// For all other errors, jump into debugger (sort of...) |
1628 |
+ |
crash_reason = (sig == SIGBUS) ? "SIGBUS" : "SIGSEGV"; |
1629 |
|
if (!ready_for_signals) { |
1630 |
< |
printf("SIGSEGV\n"); |
1630 |
> |
printf("%s\n"); |
1631 |
|
printf(" sigcontext %p, pt_regs %p\n", sc, r); |
1632 |
|
printf( |
1633 |
|
" pc %08lx lr %08lx ctr %08lx msr %08lx\n" |
1640 |
|
" r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n" |
1641 |
|
" r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n" |
1642 |
|
" r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n", |
1643 |
+ |
crash_reason, |
1644 |
|
r->nip, r->link, r->ctr, r->msr, |
1645 |
|
r->xer, r->ccr, |
1646 |
|
r->gpr[0], r->gpr[1], r->gpr[2], r->gpr[3], |
1791 |
|
} |
1792 |
|
|
1793 |
|
// For all other errors, jump into debugger (sort of...) |
1794 |
+ |
crash_reason = "SIGILL"; |
1795 |
|
if (!ready_for_signals) { |
1796 |
< |
printf("SIGILL\n"); |
1796 |
> |
printf("%s\n"); |
1797 |
|
printf(" sigcontext %p, pt_regs %p\n", sc, r); |
1798 |
|
printf( |
1799 |
|
" pc %08lx lr %08lx ctr %08lx msr %08lx\n" |
1806 |
|
" r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n" |
1807 |
|
" r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n" |
1808 |
|
" r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n", |
1809 |
+ |
crash_reason, |
1810 |
|
r->nip, r->link, r->ctr, r->msr, |
1811 |
|
r->xer, r->ccr, |
1812 |
|
r->gpr[0], r->gpr[1], r->gpr[2], r->gpr[3], |