Wrappers around machine state registers within signal handlers.

This commit is contained in:
gbeauche
2004-01-18 22:14:31 +00:00
parent 07fa8c79b3
commit 7f13ce6fed

View File

@@ -154,19 +154,70 @@ const uint32 SIG_STACK_SIZE = 0x10000; // Size of signal stack
#if !EMULATED_PPC #if !EMULATED_PPC
// Structure in which registers are saved in a signal handler;
// sigcontext->regs points to it
// (see arch/ppc/kernel/signal.c)
typedef struct {
uint32 u[4];
} __attribute((aligned(16))) vector128;
#include <linux/elf.h>
struct sigregs { struct sigregs {
elf_gregset_t gp_regs; // Identical to pt_regs uint32 nip;
double fp_regs[ELF_NFPREG]; // f0..f31 and fpsrc uint32 link;
//more (uninteresting) stuff following here uint32 ctr;
uint32 msr;
uint32 xer;
uint32 ccr;
uint32 gpr[32];
}; };
#if defined(__linux__)
struct machine_regs : public pt_regs
{
u_long & cr() { return pt_regs::ccr; }
uint32 cr() const { return pt_regs::ccr; }
uint32 lr() const { return pt_regs::link; }
uint32 ctr() const { return pt_regs::ctr; }
uint32 xer() const { return pt_regs::xer; }
uint32 msr() const { return pt_regs::msr; }
uint32 dar() const { return pt_regs::dar; }
u_long & pc() { return pt_regs::nip; }
uint32 pc() const { return pt_regs::nip; }
u_long & gpr(int i) { return pt_regs::gpr[i]; }
uint32 gpr(int i) const { return pt_regs::gpr[i]; }
};
#include <sys/ucontext.h>
#define MACHINE_REGISTERS(scp) ((machine_regs *)(((ucontext_t *)scp)->uc_mcontext.regs))
#endif
#if defined(__APPLE__) && defined(__MACH__)
struct machine_regs : public mcontext
{
uint32 & cr() { return ss.cr; }
uint32 cr() const { return ss.cr; }
uint32 lr() const { return ss.lr; }
uint32 ctr() const { return ss.ctr; }
uint32 xer() const { return ss.xer; }
uint32 msr() const { return ss.srr1; }
uint32 dar() const { return es.dar; }
uint32 & pc() { return ss.srr0; }
uint32 pc() const { return ss.srr0; }
uint32 & gpr(int i) { return (&ss.r0)[i]; }
uint32 gpr(int i) const { return (&ss.r0)[i]; }
};
#include <sys/ucontext.h>
#define MACHINE_REGISTERS(scp) ((machine_regs *)(((ucontext_t *)scp)->uc_mcontext))
#include <sys/signal.h>
extern "C" int sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss);
#endif
static void build_sigregs(sigregs *srp, machine_regs *mrp)
{
srp->nip = mrp->pc();
srp->link = mrp->lr();
srp->ctr = mrp->ctr();
srp->msr = mrp->msr();
srp->xer = mrp->xer();
srp->ccr = mrp->cr();
for (int i = 0; i < 32; i++)
srp->gpr[i] = mrp->gpr(i);
}
#endif #endif
@@ -238,9 +289,9 @@ extern void emul_ppc(uint32 start);
extern void init_emul_ppc(void); extern void init_emul_ppc(void);
extern void exit_emul_ppc(void); extern void exit_emul_ppc(void);
#else #else
static void sigusr2_handler(int sig, sigcontext_struct *sc); static void sigusr2_handler(int sig, siginfo_t *sip, void *scp);
static void sigsegv_handler(int sig, sigcontext_struct *sc); static void sigsegv_handler(int sig, siginfo_t *sip, void *scp);
static void sigill_handler(int sig, sigcontext_struct *sc); static void sigill_handler(int sig, siginfo_t *sip, void *scp);
#endif #endif
@@ -465,6 +516,7 @@ int main(int argc, char **argv)
goto quit; goto quit;
} }
#ifndef PAGEZERO_HACK
// Create Low Memory area (0x0000..0x3000) // Create Low Memory area (0x0000..0x3000)
if (vm_acquire_fixed((char *)0, 0x3000) < 0) { if (vm_acquire_fixed((char *)0, 0x3000) < 0) {
sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno)); sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno));
@@ -472,6 +524,7 @@ int main(int argc, char **argv)
goto quit; goto quit;
} }
lm_area_mapped = true; lm_area_mapped = true;
#endif
// Create areas for Kernel Data // Create areas for Kernel Data
kernel_area = shmget(IPC_PRIVATE, KERNEL_AREA_SIZE, 0600); kernel_area = shmget(IPC_PRIVATE, KERNEL_AREA_SIZE, 0600);
@@ -746,9 +799,11 @@ int main(int argc, char **argv)
// Install SIGSEGV and SIGBUS handlers // Install SIGSEGV and SIGBUS handlers
sigemptyset(&sigsegv_action.sa_mask); // Block interrupts during SEGV handling sigemptyset(&sigsegv_action.sa_mask); // Block interrupts during SEGV handling
sigaddset(&sigsegv_action.sa_mask, SIGUSR2); sigaddset(&sigsegv_action.sa_mask, SIGUSR2);
sigsegv_action.sa_handler = (__sighandler_t)sigsegv_handler; sigsegv_action.sa_sigaction = sigsegv_handler;
sigsegv_action.sa_flags = SA_ONSTACK; sigsegv_action.sa_flags = SA_ONSTACK | SA_SIGINFO;
#ifdef HAVE_SIGNAL_SA_RESTORER
sigsegv_action.sa_restorer = NULL; sigsegv_action.sa_restorer = NULL;
#endif
if (sigaction(SIGSEGV, &sigsegv_action, NULL) < 0) { if (sigaction(SIGSEGV, &sigsegv_action, NULL) < 0) {
sprintf(str, GetString(STR_SIGSEGV_INSTALL_ERR), strerror(errno)); sprintf(str, GetString(STR_SIGSEGV_INSTALL_ERR), strerror(errno));
ErrorAlert(str); ErrorAlert(str);
@@ -763,9 +818,11 @@ int main(int argc, char **argv)
// Install SIGILL handler // Install SIGILL handler
sigemptyset(&sigill_action.sa_mask); // Block interrupts during ILL handling sigemptyset(&sigill_action.sa_mask); // Block interrupts during ILL handling
sigaddset(&sigill_action.sa_mask, SIGUSR2); sigaddset(&sigill_action.sa_mask, SIGUSR2);
sigill_action.sa_handler = (__sighandler_t)sigill_handler; sigill_action.sa_sigaction = sigill_handler;
sigill_action.sa_flags = SA_ONSTACK; sigill_action.sa_flags = SA_ONSTACK | SA_SIGINFO;
#ifdef HAVE_SIGNAL_SA_RESTORER
sigill_action.sa_restorer = NULL; sigill_action.sa_restorer = NULL;
#endif
if (sigaction(SIGILL, &sigill_action, NULL) < 0) { if (sigaction(SIGILL, &sigill_action, NULL) < 0) {
sprintf(str, GetString(STR_SIGILL_INSTALL_ERR), strerror(errno)); sprintf(str, GetString(STR_SIGILL_INSTALL_ERR), strerror(errno));
ErrorAlert(str); ErrorAlert(str);
@@ -773,19 +830,20 @@ int main(int argc, char **argv)
} }
#endif #endif
#if !EMULATED_PPC
// Install interrupt signal handler // Install interrupt signal handler
sigemptyset(&sigusr2_action.sa_mask); sigemptyset(&sigusr2_action.sa_mask);
sigusr2_action.sa_handler = (__sighandler_t)sigusr2_handler; sigusr2_action.sa_sigaction = sigusr2_handler;
sigusr2_action.sa_flags = 0; sigusr2_action.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
#if !EMULATED_PPC #ifdef HAVE_SIGNAL_SA_RESTORER
sigusr2_action.sa_flags = SA_ONSTACK | SA_RESTART;
#endif
sigusr2_action.sa_restorer = NULL; sigusr2_action.sa_restorer = NULL;
#endif
if (sigaction(SIGUSR2, &sigusr2_action, NULL) < 0) { if (sigaction(SIGUSR2, &sigusr2_action, NULL) < 0) {
sprintf(str, GetString(STR_SIGUSR2_INSTALL_ERR), strerror(errno)); sprintf(str, GetString(STR_SIGUSR2_INSTALL_ERR), strerror(errno));
ErrorAlert(str); ErrorAlert(str);
goto quit; goto quit;
} }
#endif
// Get my thread ID and execute MacOS thread function // Get my thread ID and execute MacOS thread function
emul_thread = pthread_self(); emul_thread = pthread_self();
@@ -1109,7 +1167,7 @@ static void *tick_func(void *arg)
if (emul_thread_fatal) { if (emul_thread_fatal) {
// Yes, dump registers // Yes, dump registers
pt_regs *r = (pt_regs *)&sigsegv_regs; sigregs *r = &sigsegv_regs;
char str[256]; char str[256];
if (crash_reason == NULL) if (crash_reason == NULL)
crash_reason = "SIGSEGV"; crash_reason = "SIGSEGV";
@@ -1339,9 +1397,9 @@ static void sigusr2_handler(int sig)
#endif #endif
} }
#else #else
static void sigusr2_handler(int sig, sigcontext_struct *sc) static void sigusr2_handler(int sig, siginfo_t *sip, void *scp)
{ {
pt_regs *r = sc->regs; machine_regs *r = MACHINE_REGISTERS(scp);
// Do nothing if interrupts are disabled // Do nothing if interrupts are disabled
if (*(int32 *)XLM_IRQ_NEST > 0) if (*(int32 *)XLM_IRQ_NEST > 0)
@@ -1355,13 +1413,13 @@ static void sigusr2_handler(int sig, sigcontext_struct *sc)
case MODE_68K: case MODE_68K:
// 68k emulator active, trigger 68k interrupt level 1 // 68k emulator active, trigger 68k interrupt level 1
WriteMacInt16(ntohl(kernel_data->v[0x67c >> 2]), 1); WriteMacInt16(ntohl(kernel_data->v[0x67c >> 2]), 1);
r->ccr |= ntohl(kernel_data->v[0x674 >> 2]); r->cr() |= ntohl(kernel_data->v[0x674 >> 2]);
break; break;
#if INTERRUPTS_IN_NATIVE_MODE #if INTERRUPTS_IN_NATIVE_MODE
case MODE_NATIVE: case MODE_NATIVE:
// 68k emulator inactive, in nanokernel? // 68k emulator inactive, in nanokernel?
if (r->gpr[1] != KernelDataAddr) { if (r->gpr(1) != KernelDataAddr) {
// Prepare for 68k interrupt level 1 // Prepare for 68k interrupt level 1
WriteMacInt16(ntohl(kernel_data->v[0x67c >> 2]), 1); WriteMacInt16(ntohl(kernel_data->v[0x67c >> 2]), 1);
WriteMacInt32(ntohl(kernel_data->v[0x658 >> 2]) + 0xdc, ReadMacInt32(ntohl(kernel_data->v[0x658 >> 2]) + 0xdc) | ntohl(kernel_data->v[0x674 >> 2])); WriteMacInt32(ntohl(kernel_data->v[0x658 >> 2]) + 0xdc, ReadMacInt32(ntohl(kernel_data->v[0x658 >> 2]) + 0xdc) | ntohl(kernel_data->v[0x674 >> 2]));
@@ -1430,55 +1488,55 @@ static void sigusr2_handler(int sig, sigcontext_struct *sc)
*/ */
#if !EMULATED_PPC #if !EMULATED_PPC
static void sigsegv_handler(int sig, sigcontext_struct *sc) static void sigsegv_handler(int sig, siginfo_t *sip, void *scp)
{ {
pt_regs *r = sc->regs; machine_regs *r = MACHINE_REGISTERS(scp);
// Get effective address // Get effective address
uint32 addr = r->dar; uint32 addr = r->dar();
#if ENABLE_VOSF #if ENABLE_VOSF
// Handle screen fault. // Handle screen fault.
extern bool Screen_fault_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction); extern bool Screen_fault_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction);
if (Screen_fault_handler((sigsegv_address_t)addr, (sigsegv_address_t)r->nip)) if (Screen_fault_handler((sigsegv_address_t)addr, (sigsegv_address_t)r->pc()))
return; return;
#endif #endif
num_segv++; num_segv++;
// Fault in Mac ROM or RAM? // Fault in Mac ROM or RAM?
bool mac_fault = (r->nip >= ROM_BASE) && (r->nip < (ROM_BASE + ROM_AREA_SIZE)) || (r->nip >= RAMBase) && (r->nip < (RAMBase + RAMSize)); bool mac_fault = (r->pc() >= ROM_BASE) && (r->pc() < (ROM_BASE + ROM_AREA_SIZE)) || (r->pc() >= RAMBase) && (r->pc() < (RAMBase + RAMSize));
if (mac_fault) { if (mac_fault) {
// "VM settings" during MacOS 8 installation // "VM settings" during MacOS 8 installation
if (r->nip == ROM_BASE + 0x488160 && r->gpr[20] == 0xf8000000) { if (r->pc() == ROM_BASE + 0x488160 && r->gpr(20) == 0xf8000000) {
r->nip += 4; r->pc() += 4;
r->gpr[8] = 0; r->gpr(8) = 0;
return; return;
// MacOS 8.5 installation // MacOS 8.5 installation
} else if (r->nip == ROM_BASE + 0x488140 && r->gpr[16] == 0xf8000000) { } else if (r->pc() == ROM_BASE + 0x488140 && r->gpr(16) == 0xf8000000) {
r->nip += 4; r->pc() += 4;
r->gpr[8] = 0; r->gpr(8) = 0;
return; return;
// MacOS 8 serial drivers on startup // MacOS 8 serial drivers on startup
} else if (r->nip == ROM_BASE + 0x48e080 && (r->gpr[8] == 0xf3012002 || r->gpr[8] == 0xf3012000)) { } else if (r->pc() == ROM_BASE + 0x48e080 && (r->gpr(8) == 0xf3012002 || r->gpr(8) == 0xf3012000)) {
r->nip += 4; r->pc() += 4;
r->gpr[8] = 0; r->gpr(8) = 0;
return; return;
// MacOS 8.1 serial drivers on startup // MacOS 8.1 serial drivers on startup
} else if (r->nip == ROM_BASE + 0x48c5e0 && (r->gpr[20] == 0xf3012002 || r->gpr[20] == 0xf3012000)) { } else if (r->pc() == ROM_BASE + 0x48c5e0 && (r->gpr(20) == 0xf3012002 || r->gpr(20) == 0xf3012000)) {
r->nip += 4; r->pc() += 4;
return; return;
} else if (r->nip == ROM_BASE + 0x4a10a0 && (r->gpr[20] == 0xf3012002 || r->gpr[20] == 0xf3012000)) { } else if (r->pc() == ROM_BASE + 0x4a10a0 && (r->gpr(20) == 0xf3012002 || r->gpr(20) == 0xf3012000)) {
r->nip += 4; r->pc() += 4;
return; return;
} }
// Get opcode and divide into fields // Get opcode and divide into fields
uint32 opcode = *((uint32 *)r->nip); uint32 opcode = *((uint32 *)r->pc());
uint32 primop = opcode >> 26; uint32 primop = opcode >> 26;
uint32 exop = (opcode >> 1) & 0x3ff; uint32 exop = (opcode >> 1) & 0x3ff;
uint32 ra = (opcode >> 16) & 0x1f; uint32 ra = (opcode >> 16) & 0x1f;
@@ -1570,25 +1628,25 @@ static void sigsegv_handler(int sig, sigcontext_struct *sc)
#if EMULATE_UNALIGNED_LOADSTORE_MULTIPLE #if EMULATE_UNALIGNED_LOADSTORE_MULTIPLE
case 46: // lmw case 46: // lmw
if (sig == SIGBUS) { if (sig == SIGBUS) {
uint32 ea = (ra == 0 ? 0 : r->gpr[ra]) + imm; uint32 ea = (ra == 0 ? 0 : r->gpr(ra)) + imm;
D(bug("WARNING: unaligned lmw to EA=%08x from IP=%08x\n", ea, r->nip)); D(bug("WARNING: unaligned lmw to EA=%08x from IP=%08x\n", ea, r->pc()));
for (int i = rd; i <= 31; i++) { for (int i = rd; i <= 31; i++) {
r->gpr[i] = ReadMacInt32(ea); r->gpr(i) = ReadMacInt32(ea);
ea += 4; ea += 4;
} }
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
} }
break; break;
case 47: // stmw case 47: // stmw
if (sig == SIGBUS) { if (sig == SIGBUS) {
uint32 ea = (ra == 0 ? 0 : r->gpr[ra]) + imm; uint32 ea = (ra == 0 ? 0 : r->gpr(ra)) + imm;
D(bug("WARNING: unaligned stmw to EA=%08x from IP=%08x\n", ea, r->nip)); D(bug("WARNING: unaligned stmw to EA=%08x from IP=%08x\n", ea, r->pc()));
for (int i = rd; i <= 31; i++) { for (int i = rd; i <= 31; i++) {
WriteMacInt32(ea, r->gpr[i]); WriteMacInt32(ea, r->gpr(i));
ea += 4; ea += 4;
} }
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
} }
break; break;
@@ -1597,20 +1655,20 @@ static void sigsegv_handler(int sig, sigcontext_struct *sc)
// Ignore ROM writes // Ignore ROM writes
if (transfer_type == TYPE_STORE && addr >= ROM_BASE && addr < ROM_BASE + ROM_SIZE) { if (transfer_type == TYPE_STORE && addr >= ROM_BASE && addr < ROM_BASE + ROM_SIZE) {
// D(bug("WARNING: %s write access to ROM at %08lx, pc %08lx\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->nip)); // D(bug("WARNING: %s write access to ROM at %08lx, pc %08lx\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->pc()));
if (addr_mode == MODE_U || addr_mode == MODE_UX) if (addr_mode == MODE_U || addr_mode == MODE_UX)
r->gpr[ra] = addr; r->gpr(ra) = addr;
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
} }
// Ignore illegal memory accesses? // Ignore illegal memory accesses?
if (PrefsFindBool("ignoresegv")) { if (PrefsFindBool("ignoresegv")) {
if (addr_mode == MODE_U || addr_mode == MODE_UX) if (addr_mode == MODE_U || addr_mode == MODE_UX)
r->gpr[ra] = addr; r->gpr(ra) = addr;
if (transfer_type == TYPE_LOAD) if (transfer_type == TYPE_LOAD)
r->gpr[rd] = 0; r->gpr(rd) = 0;
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
} }
@@ -1618,9 +1676,9 @@ static void sigsegv_handler(int sig, sigcontext_struct *sc)
if (!PrefsFindBool("nogui")) { if (!PrefsFindBool("nogui")) {
char str[256]; char str[256];
if (transfer_type == TYPE_LOAD || transfer_type == TYPE_STORE) if (transfer_type == TYPE_LOAD || transfer_type == TYPE_STORE)
sprintf(str, GetString(STR_MEM_ACCESS_ERR), transfer_size == SIZE_BYTE ? "byte" : transfer_size == SIZE_HALFWORD ? "halfword" : "word", transfer_type == TYPE_LOAD ? GetString(STR_MEM_ACCESS_READ) : GetString(STR_MEM_ACCESS_WRITE), addr, r->nip, r->gpr[24], r->gpr[1]); sprintf(str, GetString(STR_MEM_ACCESS_ERR), transfer_size == SIZE_BYTE ? "byte" : transfer_size == SIZE_HALFWORD ? "halfword" : "word", transfer_type == TYPE_LOAD ? GetString(STR_MEM_ACCESS_READ) : GetString(STR_MEM_ACCESS_WRITE), addr, r->pc(), r->gpr(24), r->gpr(1));
else else
sprintf(str, GetString(STR_UNKNOWN_SEGV_ERR), r->nip, r->gpr[24], r->gpr[1], opcode); sprintf(str, GetString(STR_UNKNOWN_SEGV_ERR), r->pc(), r->gpr(24), r->gpr(1), opcode);
ErrorAlert(str); ErrorAlert(str);
QuitEmulator(); QuitEmulator();
return; return;
@@ -1631,7 +1689,7 @@ static void sigsegv_handler(int sig, sigcontext_struct *sc)
crash_reason = (sig == SIGBUS) ? "SIGBUS" : "SIGSEGV"; crash_reason = (sig == SIGBUS) ? "SIGBUS" : "SIGSEGV";
if (!ready_for_signals) { if (!ready_for_signals) {
printf("%s\n"); printf("%s\n");
printf(" sigcontext %p, pt_regs %p\n", sc, r); printf(" sigcontext %p, machine_regs %p\n", scp, r);
printf( printf(
" pc %08lx lr %08lx ctr %08lx msr %08lx\n" " pc %08lx lr %08lx ctr %08lx msr %08lx\n"
" xer %08lx cr %08lx \n" " xer %08lx cr %08lx \n"
@@ -1644,22 +1702,22 @@ static void sigsegv_handler(int sig, sigcontext_struct *sc)
" r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n" " r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n"
" r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n", " r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n",
crash_reason, crash_reason,
r->nip, r->link, r->ctr, r->msr, r->pc(), r->lr(), r->ctr(), r->msr(),
r->xer, r->ccr, r->xer(), r->cr(),
r->gpr[0], r->gpr[1], r->gpr[2], r->gpr[3], r->gpr(0), r->gpr(1), r->gpr(2), r->gpr(3),
r->gpr[4], r->gpr[5], r->gpr[6], r->gpr[7], r->gpr(4), r->gpr(5), r->gpr(6), r->gpr(7),
r->gpr[8], r->gpr[9], r->gpr[10], r->gpr[11], r->gpr(8), r->gpr(9), r->gpr(10), r->gpr(11),
r->gpr[12], r->gpr[13], r->gpr[14], r->gpr[15], r->gpr(12), r->gpr(13), r->gpr(14), r->gpr(15),
r->gpr[16], r->gpr[17], r->gpr[18], r->gpr[19], r->gpr(16), r->gpr(17), r->gpr(18), r->gpr(19),
r->gpr[20], r->gpr[21], r->gpr[22], r->gpr[23], r->gpr(20), r->gpr(21), r->gpr(22), r->gpr(23),
r->gpr[24], r->gpr[25], r->gpr[26], r->gpr[27], r->gpr(24), r->gpr(25), r->gpr(26), r->gpr(27),
r->gpr[28], r->gpr[29], r->gpr[30], r->gpr[31]); r->gpr(28), r->gpr(29), r->gpr(30), r->gpr(31));
exit(1); exit(1);
QuitEmulator(); QuitEmulator();
return; return;
} else { } else {
// We crashed. Save registers, tell tick thread and loop forever // We crashed. Save registers, tell tick thread and loop forever
sigsegv_regs = *(sigregs *)r; build_sigregs(&sigsegv_regs, r);
emul_thread_fatal = true; emul_thread_fatal = true;
for (;;) ; for (;;) ;
} }
@@ -1671,17 +1729,17 @@ rti:;
* SIGILL handler * SIGILL handler
*/ */
static void sigill_handler(int sig, sigcontext_struct *sc) static void sigill_handler(int sig, siginfo_t *sip, void *scp)
{ {
pt_regs *r = sc->regs; machine_regs *r = MACHINE_REGISTERS(scp);
char str[256]; char str[256];
// Fault in Mac ROM or RAM? // Fault in Mac ROM or RAM?
bool mac_fault = (r->nip >= ROM_BASE) && (r->nip < (ROM_BASE + ROM_AREA_SIZE)) || (r->nip >= RAMBase) && (r->nip < (RAMBase + RAMSize)); bool mac_fault = (r->pc() >= ROM_BASE) && (r->pc() < (ROM_BASE + ROM_AREA_SIZE)) || (r->pc() >= RAMBase) && (r->pc() < (RAMBase + RAMSize));
if (mac_fault) { if (mac_fault) {
// Get opcode and divide into fields // Get opcode and divide into fields
uint32 opcode = *((uint32 *)r->nip); uint32 opcode = *((uint32 *)r->pc());
uint32 primop = opcode >> 26; uint32 primop = opcode >> 26;
uint32 exop = (opcode >> 1) & 0x3ff; uint32 exop = (opcode >> 1) & 0x3ff;
uint32 ra = (opcode >> 16) & 0x1f; uint32 ra = (opcode >> 16) & 0x1f;
@@ -1692,7 +1750,7 @@ static void sigill_handler(int sig, sigcontext_struct *sc)
switch (primop) { switch (primop) {
case 9: // POWER instructions case 9: // POWER instructions
case 22: case 22:
power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->nip, r->gpr[1], opcode); power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->pc(), r->gpr(1), opcode);
ErrorAlert(str); ErrorAlert(str);
QuitEmulator(); QuitEmulator();
return; return;
@@ -1700,14 +1758,14 @@ power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->nip, r->gpr[1
case 31: case 31:
switch (exop) { switch (exop) {
case 83: // mfmsr case 83: // mfmsr
r->gpr[rd] = 0xf072; r->gpr(rd) = 0xf072;
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
case 210: // mtsr case 210: // mtsr
case 242: // mtsrin case 242: // mtsrin
case 306: // tlbie case 306: // tlbie
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
case 339: { // mfspr case 339: { // mfspr
@@ -1723,15 +1781,15 @@ power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->nip, r->gpr[1
case 957: // PMC3 case 957: // PMC3
case 958: // PMC4 case 958: // PMC4
case 959: // SDA case 959: // SDA
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
case 25: // SDR1 case 25: // SDR1
r->gpr[rd] = 0xdead001f; r->gpr(rd) = 0xdead001f;
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
case 287: // PVR case 287: // PVR
r->gpr[rd] = PVR; r->gpr(rd) = PVR;
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
} }
break; break;
@@ -1767,7 +1825,7 @@ power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->nip, r->gpr[1
case 957: // PMC3 case 957: // PMC3
case 958: // PMC4 case 958: // PMC4
case 959: // SDA case 959: // SDA
r->nip += 4; r->pc() += 4;
goto rti; goto rti;
} }
break; break;
@@ -1786,7 +1844,7 @@ power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->nip, r->gpr[1
// In GUI mode, show error alert // In GUI mode, show error alert
if (!PrefsFindBool("nogui")) { if (!PrefsFindBool("nogui")) {
sprintf(str, GetString(STR_UNKNOWN_SEGV_ERR), r->nip, r->gpr[24], r->gpr[1], opcode); sprintf(str, GetString(STR_UNKNOWN_SEGV_ERR), r->pc(), r->gpr(24), r->gpr(1), opcode);
ErrorAlert(str); ErrorAlert(str);
QuitEmulator(); QuitEmulator();
return; return;
@@ -1797,7 +1855,7 @@ power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->nip, r->gpr[1
crash_reason = "SIGILL"; crash_reason = "SIGILL";
if (!ready_for_signals) { if (!ready_for_signals) {
printf("%s\n"); printf("%s\n");
printf(" sigcontext %p, pt_regs %p\n", sc, r); printf(" sigcontext %p, machine_regs %p\n", scp, r);
printf( printf(
" pc %08lx lr %08lx ctr %08lx msr %08lx\n" " pc %08lx lr %08lx ctr %08lx msr %08lx\n"
" xer %08lx cr %08lx \n" " xer %08lx cr %08lx \n"
@@ -1810,22 +1868,22 @@ power_inst: sprintf(str, GetString(STR_POWER_INSTRUCTION_ERR), r->nip, r->gpr[1
" r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n" " r24 %08lx r25 %08lx r26 %08lx r27 %08lx\n"
" r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n", " r28 %08lx r29 %08lx r30 %08lx r31 %08lx\n",
crash_reason, crash_reason,
r->nip, r->link, r->ctr, r->msr, r->pc(), r->lr(), r->ctr(), r->msr(),
r->xer, r->ccr, r->xer(), r->cr(),
r->gpr[0], r->gpr[1], r->gpr[2], r->gpr[3], r->gpr(0), r->gpr(1), r->gpr(2), r->gpr(3),
r->gpr[4], r->gpr[5], r->gpr[6], r->gpr[7], r->gpr(4), r->gpr(5), r->gpr(6), r->gpr(7),
r->gpr[8], r->gpr[9], r->gpr[10], r->gpr[11], r->gpr(8), r->gpr(9), r->gpr(10), r->gpr(11),
r->gpr[12], r->gpr[13], r->gpr[14], r->gpr[15], r->gpr(12), r->gpr(13), r->gpr(14), r->gpr(15),
r->gpr[16], r->gpr[17], r->gpr[18], r->gpr[19], r->gpr(16), r->gpr(17), r->gpr(18), r->gpr(19),
r->gpr[20], r->gpr[21], r->gpr[22], r->gpr[23], r->gpr(20), r->gpr(21), r->gpr(22), r->gpr(23),
r->gpr[24], r->gpr[25], r->gpr[26], r->gpr[27], r->gpr(24), r->gpr(25), r->gpr(26), r->gpr(27),
r->gpr[28], r->gpr[29], r->gpr[30], r->gpr[31]); r->gpr(28), r->gpr(29), r->gpr(30), r->gpr(31));
exit(1); exit(1);
QuitEmulator(); QuitEmulator();
return; return;
} else { } else {
// We crashed. Save registers, tell tick thread and loop forever // We crashed. Save registers, tell tick thread and loop forever
sigsegv_regs = *(sigregs *)r; build_sigregs(&sigsegv_regs, r);
emul_thread_fatal = true; emul_thread_fatal = true;
for (;;) ; for (;;) ;
} }