void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event)) { wxDialog* diag = new wxDialog(this, wxID_ANY, "Set value", wxDefaultPosition); wxBoxSizer* s_panel(new wxBoxSizer(wxVERTICAL)); wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL)); wxTextCtrl* p_pc(new wxTextCtrl(diag, wxID_ANY)); s_panel->Add(p_pc); s_panel->AddSpacer(8); s_panel->Add(s_b_panel); s_b_panel->Add(new wxButton(diag, wxID_OK), wxLEFT, 0, 5); s_b_panel->AddSpacer(5); s_b_panel->Add(new wxButton(diag, wxID_CANCEL), wxRIGHT, 0, 5); diag->SetSizerAndFit(s_panel); if (cpu) p_pc->SetValue(wxString::Format("%x", GetPc())); if (diag->ShowModal() == wxID_OK) { unsigned long pc = cpu ? GetPc() : 0x0; p_pc->GetValue().ToULong(&pc, 16); ShowAddr(CentrePc(pc)); } }
int cN2Prov0501::ProcessBx(unsigned char *data, int len, int pos) { if(data[pos-1]!=0xBC) { PRINTF(L_SYS_EMU,"%04X: bad nano %02X for ROM 120",id,data[pos-1]); return -1; } if(pos!=(0x93-0x80)) { // maybe exploitable PRINTF(L_SYS_EMU,"%04X: refuse to execute from %04x",id,0x80+pos); return -1; } if(Init(id,120)) { SetMem(0x80,data,len); SetPc(0x80+pos); SetSp(0x0FFF,0x0FE0); Set(0x0001,0xFF); Set(0x000E,0xFF); Set(0x0000,0x04); ClearBreakpoints(); AddBreakpoint(0x821f); AddBreakpoint(0x0000); AddRomCallbacks(); while(!Run(hasMaprom ? 20000:5000)) { if(GetPc()==0x821f) { GetMem(0x80,data,len); return a; } else if(GetPc()==0x0000) break; else if(!RomCallbacks()) break; } } return -1; }
int cN2Prov0501::RunEmu(unsigned char *data, int len, unsigned short load, unsigned short run, unsigned short stop, unsigned short fetch, int fetch_len) { if(Init(id,120)) { SetSp(0x0FFF,0x0EF8); SetMem(load,data,len); SetPc(run); ClearBreakpoints(); AddBreakpoint(stop); if(stop!=0x0000) AddBreakpoint(0x0000); AddRomCallbacks(); while(!Run(100000)) { if(GetPc()==0x0000 || GetPc()==stop) { GetMem(fetch,data,fetch_len); return 1; } else if(!RomCallbacks()) break; } } return -1; }
bool cN2Prov0501::RomCallbacks(void) { unsigned int ea=GetPc(); if(ea&0x8000) ea|=(cr<<16); switch(ea) { case 0x3840: //MAP Handler if(!ProcessMap(a)) return false; break; default: PRINTF(L_SYS_EMU,"%04X: unknown ROM breakpoint %04x",id,ea); return false; } if(ea>=0x8000) PopCr(); PopPc(); return true; }
void InterpreterDisAsmFrame::ShowAddr(u32 addr) { m_pc = addr; m_list->Freeze(); if (!cpu) { for (uint i = 0; i<m_item_count; ++i, m_pc += 4) { m_list->SetItem(i, 0, wxString::Format("[%08x] illegal address", m_pc)); } } else { const u32 cpu_offset = cpu->type == cpu_type::spu ? static_cast<SPUThread&>(*cpu).offset : 0; m_disasm->offset = (u8*)vm::base(cpu_offset); for (uint i = 0, count = 4; i<m_item_count; ++i, m_pc += count) { if (!vm::check_addr(cpu_offset + m_pc, 4)) { m_list->SetItem(i, 0, wxString(IsBreakPoint(m_pc) ? ">>> " : " ") + wxString::Format("[%08x] illegal address", m_pc)); count = 4; continue; } count = m_disasm->disasm(m_disasm->dump_pc = m_pc); m_list->SetItem(i, 0, wxString(IsBreakPoint(m_pc) ? ">>> " : " ") + fmt::FromUTF8(m_disasm->last_opcode)); wxColour colour; if (cpu->state.test(cpu_state_pause) && m_pc == GetPc()) { colour = wxColour("Green"); } else { colour = wxColour(IsBreakPoint(m_pc) ? "Wheat" : "White"); } m_list->SetItemBackgroundColour(i, colour); } } m_list->SetColumnWidth(0, -1); m_list->Thaw(); }
BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers) { int st; unw_context_t unwContext; unw_cursor_t cursor; #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_) DWORD64 curPc; #endif if ((context->ContextFlags & CONTEXT_EXCEPTION_ACTIVE) != 0) { // The current frame is a source of hardware exception. Due to the fact that // we use the low level unwinder to unwind just one frame a time, the // unwinder doesn't have the signal_frame flag set. So it doesn't // know that it should not decrement the PC before looking up the unwind info. // So we compensate it by incrementing the PC before passing it to the unwinder. // Without it, the unwinder would not find unwind info if the hardware exception // happened in the first instruction of a function. SetPc(context, GetPc(context) + 1); } #if UNWIND_CONTEXT_IS_UCONTEXT_T WinContextToUnwindContext(context, &unwContext); #else st = unw_getcontext(&unwContext); if (st < 0) { return FALSE; } #endif st = unw_init_local(&cursor, &unwContext); if (st < 0) { return FALSE; } #if !UNWIND_CONTEXT_IS_UCONTEXT_T // Set the unwind context to the specified windows context WinContextToUnwindCursor(context, &cursor); #endif #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_) // OSX and FreeBSD appear to do two different things when unwinding // 1: If it reaches where it cannot unwind anymore, say a // managed frame. It wil return 0, but also update the $pc // 2: If it unwinds all the way to _start it will return // 0 from the step, but $pc will stay the same. // The behaviour of libunwind from nongnu.org is to null the PC // So we bank the original PC here, so we can compare it after // the step curPc = GetPc(context); #endif st = unw_step(&cursor); if (st < 0) { return FALSE; } // Check if the frame we have unwound to is a frame that caused // synchronous signal, like a hardware exception and record it // in the context flags. st = unw_is_signal_frame(&cursor); if (st > 0) { context->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE; } else { context->ContextFlags &= ~CONTEXT_EXCEPTION_ACTIVE; } // Update the passed in windows context to reflect the unwind // UnwindContextToWinContext(&cursor, context); #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_) if (st == 0 && GetPc(context) == curPc) { SetPc(context, 0); } #endif if (contextPointers != NULL) { GetContextPointers(&cursor, &unwContext, contextPointers); } return TRUE; }
void InterpreterDisAsmFrame::Show_PC(wxCommandEvent& WXUNUSED(event)) { if (cpu) ShowAddr(CentrePc(GetPc())); }
BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers) { int st; unw_context_t unwContext; unw_cursor_t cursor; #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_) DWORD64 curPc; #endif #if UNWIND_CONTEXT_IS_UCONTEXT_T WinContextToUnwindContext(context, &unwContext); #else st = unw_getcontext(&unwContext); if (st < 0) { return FALSE; } #endif st = unw_init_local(&cursor, &unwContext); if (st < 0) { return FALSE; } #if !UNWIND_CONTEXT_IS_UCONTEXT_T // Set the unwind context to the specified windows context WinContextToUnwindCursor(context, &cursor); #endif #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_) // OSX and FreeBSD appear to do two different things when unwinding // 1: If it reaches where it cannot unwind anymore, say a // managed frame. It wil return 0, but also update the $pc // 2: If it unwinds all the way to _start it will return // 0 from the step, but $pc will stay the same. // The behaviour of libunwind from nongnu.org is to null the PC // So we bank the original PC here, so we can compare it after // the step curPc = GetPc(context); #endif st = unw_step(&cursor); if (st < 0) { return FALSE; } // Update the passed in windows context to reflect the unwind // UnwindContextToWinContext(&cursor, context); #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_) if (st == 0 && GetPc(context) == curPc) { SetPc(context, 0); } #endif if (contextPointers != NULL) { GetContextPointers(&cursor, &unwContext, contextPointers); } return TRUE; }