Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
void PPCThread::NextPc()
{
	if(isBranch)
	{
		NextBranchPc();
		isBranch = false;
		return;
	}

	SetPc(PC + 4);
}
Ejemplo n.º 4
0
void CPUThread::NextPc(u8 instr_size)
{
	if(m_is_branch)
	{
		m_is_branch = false;

		SetPc(nPC);
	}
	else
	{
		PC += instr_size;
	}
}
Ejemplo n.º 5
0
void CPUThread::Reset()
{
	CloseStack();

	SetPc(0);
	cycle = 0;
	m_is_branch = false;

	m_status = Stopped;
	m_error = 0;
	
	DoReset();
}
Ejemplo n.º 6
0
void PPCThread::Reset()
{
	CloseStack();

	SetPc(0);
	cycle = 0;

	isBranch = false;

	m_status = Stopped;
	m_error = 0;
	
	DoReset();
}
Ejemplo n.º 7
0
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();
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
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 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;
}
Ejemplo n.º 15
0
void PPCThread::NextBranchPc()
{
	SetPc(nPC);
}
Ejemplo n.º 16
0
void PPCThread::PrevPc()
{
	SetPc(PC - 4);
}