/************************************************************* Display the enforcer hit *************************************************************/ static void enforcer_display_hit (const TCHAR *addressmode, uae_u32 pc, uaecptr addr) { uae_u32 a7; uae_u32 sysbase; uae_u32 this_task; uae_u32 task_name; TCHAR *native_task_name = NULL; int i, j; static TCHAR buf[256],instrcode[256]; static TCHAR lines[INSTRUCTIONLINES/2][256]; static uaecptr bestpc_array[INSTRUCTIONLINES/2][5]; static int bestpc_idxs[INSTRUCTIONLINES/2]; TCHAR *enforcer_buf_ptr = enforcer_buf; uaecptr bestpc, pospc, nextpc, temppc; if (enforcer_hit) return; /* our function itself generated a hit ;), avoid endless loop */ if (regs.vbr < 0x100 && addr >= 0x0c && addr < 0x80) return; enforcer_hit = 1; sysbase = get_long (4); if (sysbase < 0x100 || !valid_address (sysbase, 1000)) goto end; this_task = get_long (sysbase + 276); if (this_task < 0x100 || !valid_address (this_task, 1000)) goto end; task_name = get_long (this_task + 10); /* ln_Name */ native_task_name = au ((char*)amiga2native (task_name, 100)); /*if (strcmp(native_task_name,"c:MCP")!=0) { Exception (0x2d,0); }*/ _tcscpy (enforcer_buf_ptr, _T("Enforcer Hit! Bad program\n")); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); _stprintf (buf, _T("Illegal %s: %08x"), addressmode, addr); _stprintf (enforcer_buf_ptr, _T("%-48sPC: %08x\n"), buf, pc); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); /* Data registers */ _stprintf (enforcer_buf_ptr, _T("Data: %08x %08x %08x %08x %08x %08x %08x %08x\n"), m68k_dreg (regs, 0), m68k_dreg (regs, 1), m68k_dreg (regs, 2), m68k_dreg (regs, 3), m68k_dreg (regs, 4), m68k_dreg (regs, 5), m68k_dreg (regs, 6), m68k_dreg (regs, 7)); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); /* Address registers */ _stprintf (enforcer_buf_ptr, _T("Addr: %08x %08x %08x %08x %08x %08x %08x %08x\n"), m68k_areg (regs, 0), m68k_areg (regs, 1), m68k_areg (regs, 2), m68k_areg (regs, 3), m68k_areg (regs, 4), m68k_areg (regs, 5), m68k_areg (regs, 6), m68k_areg (regs, 7)); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); /* Stack */ a7 = m68k_areg (regs, 7); for (i = 0; i < 8 * STACKLINES; i++) { a7 += 4; if (!(i % 8)) { _tcscpy (enforcer_buf_ptr, _T("Stck:")); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); } _stprintf (enforcer_buf_ptr, _T(" %08x"),get_long (a7)); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); if (i%8 == 7) *enforcer_buf_ptr++ = '\n'; } /* Segtracker output */ if (enforcer_decode_hunk_and_offset (buf, pc)) { _tcscpy (enforcer_buf_ptr, buf); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); } uae_u32 oldaddrs[BACKTRACELONGS]; a7 = m68k_areg (regs, 7); for (i = 0; i < BACKTRACELONGS; i++) { uae_u32 addr; a7 += 4; addr = get_long (a7); for (j = 0; j < i; j++) { if (oldaddrs[j] == addr) break; } oldaddrs[i] = addr; if (j == i && addr != pc) { if (enforcer_decode_hunk_and_offset (buf, addr)) { int l = _tcslen (buf); if (ENFORCER_BUF_SIZE - (enforcer_buf_ptr - enforcer_buf) > l + 256) { _tcscpy (enforcer_buf_ptr, buf); enforcer_buf_ptr += l; } } } } /* Decode the instructions around the pc where the enforcer hit was caused. * * At first, the area before the pc, this not always done correctly because * it's done backwards */ temppc = pc; memset (bestpc_array, 0, sizeof (bestpc_array)); for (i = 0; i < INSTRUCTIONLINES / 2; i++) bestpc_idxs[i] = -1; for (i = 0; i < INSTRUCTIONLINES / 2; i++) { pospc = temppc; bestpc = 0; if (bestpc_idxs[i] == -1) { for (j = 0; j < 5; j++) { pospc -= 2; sm68k_disasm (buf, NULL, pospc, &nextpc); if (nextpc == temppc) { bestpc_idxs[i] = j; bestpc_array[i][j] = bestpc = pospc; } } } else { bestpc = bestpc_array[i][bestpc_idxs[i]]; } if (!bestpc) { /* there was no best pc found, so it is high probable that * a former used best pc was wrong. * * We trace back and use the former best pc instead */ int former_idx; int leave = 0; do { if (!i) { leave = 1; break; } i--; former_idx = bestpc_idxs[i]; bestpc_idxs[i] = -1; bestpc_array[i][former_idx] = 0; for (j = former_idx - 1; j >= 0; j--) { if (bestpc_array[i][j]) { bestpc_idxs[i] = j; break; } } } while (bestpc_idxs[i] == -1); if (leave) break; if (i) temppc = bestpc_array[i-1][bestpc_idxs[i-1]]; else temppc = pc; i--; /* will be increased in after continue */ continue; } sm68k_disasm (buf, instrcode, bestpc, NULL); _stprintf (lines[i], _T("%08x : %-20s %s\n"), bestpc, instrcode, buf); temppc = bestpc; } i--; for (; i >= 0; i--) { _tcscpy (enforcer_buf_ptr, lines[i]); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); } /* Now the instruction after the pc including the pc */ temppc = pc; for (i = 0; i < (INSTRUCTIONLINES + 1) / 2; i++) { sm68k_disasm (buf, instrcode, temppc, &nextpc); _stprintf (enforcer_buf_ptr, _T("%08x : %s %-20s %s\n"), temppc, (i == 0 ? _T("*") : _T(" ")), instrcode, buf); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); temppc = nextpc; } if (!native_task_name) native_task_name = my_strdup(_T("Unknown")); _stprintf (enforcer_buf_ptr, _T("Name: \"%s\"\n\n"), native_task_name); enforcer_buf_ptr += _tcslen (enforcer_buf_ptr); console_out (enforcer_buf); write_log (_T("%s"), enforcer_buf); if (!debug_enforcer()) { sleep_millis (5); doflashscreen (); } end: xfree (native_task_name); enforcer_hit = 0; }
/************************************************************* Display the enforcer hit *************************************************************/ static void enforcer_display_hit (const char *addressmode, uae_u32 pc, uaecptr addr) { uae_u32 a7; uae_u32 sysbase; uae_u32 this_task; uae_u32 task_name; const char *native_task_name; int i, j; static char buf[256], instrcode[256]; static char lines[INSTRUCTIONLINES/2][256]; static uaecptr bestpc_array[INSTRUCTIONLINES/2][5]; static int bestpc_idxs[INSTRUCTIONLINES/2]; char *enforcer_buf_ptr = enforcer_buf; uaecptr bestpc, pospc, nextpc, temppc; if (enforcer_hit) return; /* our function itself generated a hit ;), avoid endless loop */ enforcer_hit = 1; if (!(sysbase = get_long (4))) return; if (!(this_task = get_long (sysbase + 276))) return; task_name = get_long (this_task + 10); /* ln_Name */ native_task_name = (char *) amiga2native (task_name, 100); strcpy (enforcer_buf_ptr, "Enforcer Hit! Bad program\n"); enforcer_buf_ptr += strlen (enforcer_buf_ptr); sprintf (buf, "Illegal %s: %08lx", addressmode, addr); sprintf (enforcer_buf_ptr,"%-48sPC: %0lx\n", buf, pc); enforcer_buf_ptr += strlen (enforcer_buf_ptr); /* Data registers */ sprintf (enforcer_buf_ptr, "Data: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", m68k_dreg (®s, 0), m68k_dreg (®s, 1), m68k_dreg (®s, 2), m68k_dreg (®s, 3), m68k_dreg (®s, 4), m68k_dreg (®s, 5), m68k_dreg (®s, 6), m68k_dreg (®s, 7)); enforcer_buf_ptr += strlen (enforcer_buf_ptr); /* Address registers */ sprintf (enforcer_buf_ptr, "Addr: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", m68k_areg (®s, 0), m68k_areg (®s, 1), m68k_areg (®s, 2), m68k_areg (®s, 3), m68k_areg (®s, 4), m68k_areg (®s, 5), m68k_areg (®s, 6), m68k_areg (®s, 7)); enforcer_buf_ptr += strlen(enforcer_buf_ptr); /* Stack */ a7 = m68k_areg (®s, 7); for (i = 0; i < 8 * STACKLINES; i++) { a7 -= 4; if (!(i % 8)) { strcpy (enforcer_buf_ptr,"Stck:"); enforcer_buf_ptr += strlen (enforcer_buf_ptr); } sprintf (enforcer_buf_ptr," %08lx", get_long (a7)); enforcer_buf_ptr += strlen (enforcer_buf_ptr); if (i%8 == 7) *enforcer_buf_ptr++ = '\n'; } /* Segtracker output */ a7 = m68k_areg (®s, 7); if (get_long (a7-4) != pc) { if (enforcer_decode_hunk_and_offset (buf, pc)) { strcpy (enforcer_buf_ptr, buf); enforcer_buf_ptr += strlen (enforcer_buf_ptr); } } for (i = 0; i < 8 * STACKLINES; i++) { a7 -= 4; if (enforcer_decode_hunk_and_offset (buf, get_long (a7))) { int l = strlen (buf); if (ENFORCER_BUF_SIZE - (enforcer_buf_ptr - enforcer_buf) > l + 256) { strcpy(enforcer_buf_ptr, buf); enforcer_buf_ptr += l; } } } /* Decode the instructions around the pc where the enforcer hit was caused. * * At first, the area before the pc, this not always done correctly because * it's done backwards */ temppc = pc; memset (bestpc_array, 0, sizeof (bestpc_array)); for (i = 0; i < INSTRUCTIONLINES / 2; i++) bestpc_idxs[i] = -1; for (i = 0; i < INSTRUCTIONLINES / 2; i++) { pospc = temppc; bestpc = 0; if (bestpc_idxs[i] == -1) { for (j = 0; j < 5; j++) { pospc -= 2; sm68k_disasm (buf, NULL, pospc, &nextpc); if (nextpc == temppc) { bestpc_idxs[i] = j; bestpc_array[i][j] = bestpc = pospc; } } } else { bestpc = bestpc_array[i][bestpc_idxs[i]]; } if (!bestpc) { /* there was no best pc found, so it is high probable that * a former used best pc was wrong. * * We trace back and use the former best pc instead */ int former_idx; int leave = 0; do { if (!i) { leave = 1; break; } i--; former_idx = bestpc_idxs[i]; bestpc_idxs[i] = -1; bestpc_array[i][former_idx] = 0; for (j = former_idx - 1; j >= 0; j--) { if (bestpc_array[i][j]) { bestpc_idxs[i] = j; break; } } } while (bestpc_idxs[i] == -1); if (leave) break; if (i) temppc = bestpc_array[i-1][bestpc_idxs[i-1]]; else temppc = pc; i--; /* will be increased in after continue */ continue; } sm68k_disasm (buf, instrcode, bestpc, NULL); sprintf (lines[i], "%08lx : %-20s %s\n", bestpc, instrcode, buf); temppc = bestpc; } i--; for (; i>=0; i--) { strcpy (enforcer_buf_ptr,lines[i]); enforcer_buf_ptr += strlen (enforcer_buf_ptr); } /* Now the instruction after the pc including the pc */ temppc = pc; for (i=0; i < (INSTRUCTIONLINES+1) / 2; i++) { sm68k_disasm (buf, instrcode, temppc, &nextpc); sprintf (enforcer_buf_ptr, "%08lx : %s %-20s %s\n", temppc, (i == 0 ? "*" : " "), instrcode, buf); enforcer_buf_ptr += strlen (enforcer_buf_ptr); temppc = nextpc; } if (!native_task_name) native_task_name = "Unknown"; sprintf (enforcer_buf_ptr, "Name: \"%s\"\n\n", native_task_name); enforcer_buf_ptr += strlen (enforcer_buf_ptr); console_out (enforcer_buf); write_log (enforcer_buf); enforcer_hit = 0; flashscreen = 30; }