Emulated lmw/stmw with unaligned EA. e.g. for BBEdit under MacOS 8.6.

This may be due to some switch mode that needs to save r13 and upwards.
The faultive code seems to explicitly add 0xee to r1, which causes it to
be unaligned for upcoming lmw/stmw.
This commit is contained in:
gbeauche 2004-01-04 18:35:21 +00:00
parent 866919579f
commit dd3a208906

View File

@ -132,6 +132,9 @@
#endif
// Enable emulation of unaligned lmw/stmw?
#define EMULATE_UNALIGNED_LOADSTORE_MULTIPLE 1
// Enable Execute68k() safety checks?
#define SAFE_EXEC_68K 0
@ -216,6 +219,7 @@ static void *sig_stack = NULL; // Stack for signal handlers
static void *extra_stack = NULL; // Stack for SIGSEGV inside interrupt handler
static bool emul_thread_fatal = false; // Flag: MacOS thread crashed, tick thread shall dump debug output
static sigregs sigsegv_regs; // Register dump when crashed
static const char *crash_reason = NULL; // Reason of the crash (SIGSEGV, SIGBUS, SIGILL)
#endif
uintptr SheepMem::zero_page = 0; // Address of ro page filled in with zeros
@ -739,7 +743,7 @@ int main(int argc, char **argv)
#endif
#if !EMULATED_PPC
// Install SIGSEGV handler
// Install SIGSEGV and SIGBUS handlers
sigemptyset(&sigsegv_action.sa_mask); // Block interrupts during SEGV handling
sigaddset(&sigsegv_action.sa_mask, SIGUSR2);
sigsegv_action.sa_handler = (__sighandler_t)sigsegv_handler;
@ -750,6 +754,11 @@ int main(int argc, char **argv)
ErrorAlert(str);
goto quit;
}
if (sigaction(SIGBUS, &sigsegv_action, NULL) < 0) {
sprintf(str, GetString(STR_SIGSEGV_INSTALL_ERR), strerror(errno));
ErrorAlert(str);
goto quit;
}
// Install SIGILL handler
sigemptyset(&sigill_action.sa_mask); // Block interrupts during ILL handling
@ -813,11 +822,12 @@ static void Quit(void)
}
#if !EMULATED_PPC
// Uninstall SIGSEGV handler
// Uninstall SIGSEGV and SIGBUS handlers
sigemptyset(&sigsegv_action.sa_mask);
sigsegv_action.sa_handler = SIG_DFL;
sigsegv_action.sa_flags = 0;
sigaction(SIGSEGV, &sigsegv_action, NULL);
sigaction(SIGBUS, &sigsegv_action, NULL);
// Uninstall SIGILL handler
sigemptyset(&sigill_action.sa_mask);
@ -1098,7 +1108,9 @@ static void *tick_func(void *arg)
// Yes, dump registers
pt_regs *r = (pt_regs *)&sigsegv_regs;
char str[256];
sprintf(str, "SIGSEGV\n"
if (crash_reason == NULL)
crash_reason = "SIGSEGV";
sprintf(str, "%s\n"
" pc %08lx lr %08lx ctr %08lx msr %08lx\n"
" xer %08lx cr %08lx \n"
" r0 %08lx r1 %08lx r2 %08lx r3 %08lx\n"
@ -1109,6 +1121,7 @@ static void *tick_func(void *arg)
" r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n"
" r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n"
" r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n",
crash_reason,
r->nip, r->link, r->ctr, r->msr,
r->xer, r->ccr,
r->gpr[0], r->gpr[1], r->gpr[2], r->gpr[3],
@ -1551,6 +1564,32 @@ static void sigsegv_handler(int sig, sigcontext_struct *sc)
transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_NORM; break;
case 45: // sthu
transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break;
#if EMULATE_UNALIGNED_LOADSTORE_MULTIPLE
case 46: // lmw
if (sig == SIGBUS) {
uint32 ea = (ra == 0 ? 0 : r->gpr[ra]) + imm;
D(bug("WARNING: unaligned lmw to EA=%08x from IP=%08x\n", ea, r->nip));
for (int i = rd; i <= 31; i++) {
r->gpr[i] = ReadMacInt32(ea);
ea += 4;
}
r->nip += 4;
goto rti;
}
break;
case 47: // stmw
if (sig == SIGBUS) {
uint32 ea = (ra == 0 ? 0 : r->gpr[ra]) + imm;
D(bug("WARNING: unaligned stmw to EA=%08x from IP=%08x\n", ea, r->nip));
for (int i = rd; i <= 31; i++) {
WriteMacInt32(ea, r->gpr[i]);
ea += 4;
}
r->nip += 4;
goto rti;
}
break;
#endif
}
// Ignore ROM writes
@ -1586,8 +1625,9 @@ static void sigsegv_handler(int sig, sigcontext_struct *sc)
}
// For all other errors, jump into debugger (sort of...)
crash_reason = (sig == SIGBUS) ? "SIGBUS" : "SIGSEGV";
if (!ready_for_signals) {
printf("SIGSEGV\n");
printf("%s\n");
printf(" sigcontext %p, pt_regs %p\n", sc, r);
printf(
" pc %08lx lr %08lx ctr %08lx msr %08lx\n"
@ -1600,6 +1640,7 @@ static void sigsegv_handler(int sig, sigcontext_struct *sc)
" r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n"
" r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n"
" r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n",
crash_reason,
r->nip, r->link, r->ctr, r->msr,
r->xer, r->ccr,
r->gpr[0], r->gpr[1], r->gpr[2], r->gpr[3],
@ -1750,8 +1791,9 @@ power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->nip, r->gpr[1
}
// For all other errors, jump into debugger (sort of...)
crash_reason = "SIGILL";
if (!ready_for_signals) {
printf("SIGILL\n");
printf("%s\n");
printf(" sigcontext %p, pt_regs %p\n", sc, r);
printf(
" pc %08lx lr %08lx ctr %08lx msr %08lx\n"
@ -1764,6 +1806,7 @@ power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->nip, r->gpr[1
" r20 %08lx r21 %08lx r22 %08lx r23 %08lx\n"
" r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n"
" r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n",
crash_reason,
r->nip, r->link, r->ctr, r->msr,
r->xer, r->ccr,
r->gpr[0], r->gpr[1], r->gpr[2], r->gpr[3],