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; }
void CPUThread::Run() { if(IsRunning()) Stop(); if(IsPaused()) { Resume(); return; } #ifndef QT_UI wxGetApp().SendDbgCommand(DID_START_THREAD, this); #endif m_status = Running; SetPc(entry); InitStack(); InitRegs(); DoRun(); Emu.CheckStatus(); #ifndef QT_UI wxGetApp().SendDbgCommand(DID_STARTED_THREAD, this); #endif }
void PPCThread::NextPc() { if(isBranch) { NextBranchPc(); isBranch = false; return; } SetPc(PC + 4); }
void CPUThread::NextPc(u8 instr_size) { if(m_is_branch) { m_is_branch = false; SetPc(nPC); } else { PC += instr_size; } }
void CPUThread::Reset() { CloseStack(); SetPc(0); cycle = 0; m_is_branch = false; m_status = Stopped; m_error = 0; DoReset(); }
void PPCThread::Reset() { CloseStack(); SetPc(0); cycle = 0; isBranch = false; m_status = Stopped; m_error = 0; DoReset(); }
void CPUThread::Reset() { CloseStack(); m_sync_wait = 0; m_wait_thread_id = -1; SetPc(0); cycle = 0; m_is_branch = false; m_status = Stopped; m_error = 0; DoReset(); }
void CPUThread::Run() { if(!IsStopped()) Stop(); Reset(); SendDbgCommand(DID_START_THREAD, this); m_status = Running; SetPc(entry); InitStack(); InitRegs(); DoRun(); Emu.CheckStatus(); SendDbgCommand(DID_STARTED_THREAD, this); }
void PPUThread::InitRegs() { const u32 pc = entry ? vm::read32(entry) : 0; const u32 rtoc = entry ? vm::read32(entry + 4) : 0; //ConLog.Write("entry = 0x%x", entry); //ConLog.Write("rtoc = 0x%x", rtoc); SetPc(pc); /* const s32 thread_num = Emu.GetCPU().GetThreadNumById(GetType(), GetId()); if(thread_num < 0) { LOG_ERROR(PPU, "GetThreadNumById failed."); Emu.Pause(); return; } */ /* const s32 tls_size = Emu.GetTLSFilesz() * thread_num; if(tls_size >= Emu.GetTLSMemsz()) { LOG_ERROR(PPU, "Out of TLS memory."); Emu.Pause(); return; } */ GPR[1] = AlignAddr(m_stack_addr + m_stack_size, 0x200) - 0x200; GPR[2] = rtoc; GPR[13] = Memory.PRXMem.GetStartAddr() + 0x7060; LR = Emu.GetPPUThreadExit(); CTR = PC; CR.CR = 0x22000082; VSCR.NJ = 1; TB = 0; }
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; }
void PPCThread::Run() { if(IsRunned()) Stop(); if(IsPaused()) { Resume(); return; } wxGetApp().SendDbgCommand(DID_START_THREAD, this); m_status = Runned; SetPc(entry); InitStack(); InitRegs(); DoRun(); Emu.CheckStatus(); wxGetApp().SendDbgCommand(DID_STARTED_THREAD, this); }
void PPUThread::InitRegs() { const u32 pc = Memory.Read32(entry); const u32 rtoc = Memory.Read32(entry + 4); //ConLog.Write("entry = 0x%x", entry); //ConLog.Write("rtoc = 0x%x", rtoc); SetPc(pc); /* const s32 thread_num = Emu.GetCPU().GetThreadNumById(GetType(), GetId()); if(thread_num < 0) { ConLog.Error("GetThreadNumById failed."); Emu.Pause(); return; } */ /* const s32 tls_size = Emu.GetTLSFilesz() * thread_num; if(tls_size >= Emu.GetTLSMemsz()) { ConLog.Error("Out of TLS memory."); Emu.Pause(); return; } */ m_stack_point = Memory.AlignAddr(m_stack_point, 0x200) - 0x200; GPR[1] = m_stack_point; GPR[2] = rtoc; /* for(int i=4; i<32; ++i) { if(i != 6) GPR[i] = (i+1) * 0x10000; } */ if(m_argv_addr.size()) { u64 argc = m_argv_addr.size(); m_stack_point -= 0xc + 4 * argc; u64 argv = m_stack_point; mem64_ptr_t argv_list(argv); for(int i=0; i<argc; ++i) argv_list += m_argv_addr[i]; GPR[3] = argc; GPR[4] = argv; GPR[5] = argv ? argv + 0xc + 4 * argc : 0; //unk } else { GPR[3] = m_args[0]; GPR[4] = m_args[1]; GPR[5] = m_args[2]; GPR[6] = m_args[3]; } GPR[0] = pc; GPR[8] = entry; GPR[11] = 0x80; GPR[12] = Emu.GetMallocPageSize(); GPR[13] = Memory.PRXMem.GetStartAddr() + 0x7060; GPR[28] = GPR[4]; GPR[29] = GPR[3]; GPR[31] = GPR[5]; LR = Emu.GetPPUThreadExit(); CTR = PC; CR.CR = 0x22000082; VSCR.NJ = 1; TB = 0; }
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; }
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; }
void PPCThread::NextBranchPc() { SetPc(nPC); }
void PPCThread::PrevPc() { SetPc(PC - 4); }