Example #1
0
static void gdb_reply(const char* reply)
{
  u8 chk;
  u32 left;
  u8* ptr;
  int n;

  if (!gdb_active())
    return;

  memset(cmd_bfr, 0, sizeof cmd_bfr);

  cmd_len = strlen(reply);
  if (cmd_len + 4 > sizeof cmd_bfr)
    ERROR_LOG(GDB_STUB, "cmd_bfr overflow in gdb_reply");

  memcpy(cmd_bfr + 1, reply, cmd_len);

  cmd_len++;
  chk = gdb_calc_chksum();
  cmd_len--;
  cmd_bfr[0] = GDB_STUB_START;
  cmd_bfr[cmd_len + 1] = GDB_STUB_END;
  cmd_bfr[cmd_len + 2] = nibble2hex(chk >> 4);
  cmd_bfr[cmd_len + 3] = nibble2hex(chk);

  DEBUG_LOG(GDB_STUB, "gdb: reply (len: %d): %s", cmd_len, cmd_bfr);

  ptr = cmd_bfr;
  left = cmd_len + 4;
  while (left > 0)
  {
    n = send(sock, ptr, left, 0);
    if (n < 0)
    {
      ERROR_LOG(GDB_STUB, "gdb: send failed");
      return gdb_deinit();
    }
    left -= n;
    ptr += n;
  }
}
Example #2
0
void gdb_handle_exception()
{
  while (gdb_active())
  {
    if (!gdb_data_available())
      continue;
    gdb_read_command();
    if (cmd_len == 0)
      continue;

    switch (cmd_bfr[0])
    {
    case 'q':
      gdb_handle_query();
      break;
    case 'H':
      gdb_handle_set_thread();
      break;
    case '?':
      gdb_handle_signal();
      break;
    case 'k':
      gdb_deinit();
      INFO_LOG(GDB_STUB, "killed by gdb");
      return;
    case 'g':
      gdb_read_registers();
      break;
    case 'G':
      gdb_write_registers();
      break;
    case 'p':
      gdb_read_register();
      break;
    case 'P':
      gdb_write_register();
      break;
    case 'm':
      gdb_read_mem();
      break;
    case 'M':
      gdb_write_mem();
      PowerPC::ppcState.iCache.Reset();
      Host_UpdateDisasmDialog();
      break;
    case 's':
      gdb_step();
      return;
    case 'C':
    case 'c':
      gdb_continue();
      return;
    case 'z':
      gdb_remove_bp();
      break;
    case 'Z':
      _gdb_add_bp();
      break;
    default:
      gdb_reply("");
      break;
    }
  }
}
Example #3
0
int Interpreter::SingleStepInner()
{
	static UGeckoInstruction instCode;
	u32 function = HLE::GetFunctionIndex(PC);
	if (function != 0)
	{
		int type = HLE::GetFunctionTypeByIndex(function);
		if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE)
		{
			int flags = HLE::GetFunctionFlagsByIndex(function);
			if (HLE::IsEnabled(flags))
			{
				HLEFunction(function);
				if (type == HLE::HLE_HOOK_START)
				{
					// Run the original.
					function = 0;
				}
			}
			else
			{
				function = 0;
			}
		}
	}

	if (function == 0)
	{
		#ifdef USE_GDBSTUB
		if (gdb_active() && gdb_bp_x(PC))
		{
			Host_UpdateDisasmDialog();

			gdb_signal(SIGTRAP);
			gdb_handle_exception();
		}
		#endif

		NPC = PC + sizeof(UGeckoInstruction);
		instCode.hex = PowerPC::Read_Opcode(PC);

		// Uncomment to trace the interpreter
		//if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624)
		//	startTrace = 1;
		//else
		//	startTrace = 0;

		if (startTrace)
		{
			Trace(instCode);
		}

		if (instCode.hex != 0)
		{
			UReg_MSR& msr = (UReg_MSR&)MSR;
			if (msr.FP)  //If FPU is enabled, just execute
			{
				m_opTable[instCode.OPCD](instCode);
				if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
				{
					PowerPC::CheckExceptions();
					m_EndBlock = true;
				}
			}
			else
			{
				// check if we have to generate a FPU unavailable exception
				if (!PPCTables::UsesFPU(instCode))
				{
					m_opTable[instCode.OPCD](instCode);
					if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
					{
						PowerPC::CheckExceptions();
						m_EndBlock = true;
					}
				}
				else
				{
					PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE;
					PowerPC::CheckExceptions();
					m_EndBlock = true;
				}
			}
		}
		else
		{
			// Memory exception on instruction fetch
			PowerPC::CheckExceptions();
			m_EndBlock = true;
		}
	}
	last_pc = PC;
	PC = NPC;

	GekkoOPInfo *opinfo = GetOpInfo(instCode);
	return opinfo->numCycles;
}
Example #4
0
int Interpreter::SingleStepInner(void)
{
	static UGeckoInstruction instCode;
	u32 function = m_EndBlock ? HLE::GetFunctionIndex(PC) : 0; // Check for HLE functions after branches
	if (function != 0)
	{
		int type = HLE::GetFunctionTypeByIndex(function);
		if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE)
		{
			int flags = HLE::GetFunctionFlagsByIndex(function);
			if (HLE::IsEnabled(flags))
			{
				HLEFunction(function);
				if (type == HLE::HLE_HOOK_START)
				{
					// Run the original.
					function = 0;
				}
			}
			else
			{
				function = 0;
			}
		}
	}

	if (function == 0)
	{
		#ifdef USE_GDBSTUB
		if (gdb_active() && gdb_bp_x(PC)) {

			Host_UpdateDisasmDialog();

			gdb_signal(SIGTRAP);
			gdb_handle_exception();
		}
		#endif

		NPC = PC + sizeof(UGeckoInstruction);
		instCode.hex = Memory::Read_Opcode(PC);

		// Uncomment to trace the interpreter
		//if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624)
		//	startTrace = 1;
		//else
		//	startTrace = 0;

		if (startTrace)
		{
			Trace(instCode);
		}

		if (instCode.hex != 0)
		{
			UReg_MSR& msr = (UReg_MSR&)MSR;
			if (msr.FP)  //If FPU is enabled, just execute
			{
				m_opTable[instCode.OPCD](instCode);
				if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
				{
					PowerPC::CheckExceptions();
					m_EndBlock = true;
				}
			}
			else
			{
				// check if we have to generate a FPU unavailable exception
				if (!PPCTables::UsesFPU(instCode))
				{
					m_opTable[instCode.OPCD](instCode);
					if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
					{
						PowerPC::CheckExceptions();
						m_EndBlock = true;
					}
				}
				else
				{
					Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE);
					PowerPC::CheckExceptions();
					m_EndBlock = true;
				}
			}
		}
		else
		{
			// Memory exception on instruction fetch
			PowerPC::CheckExceptions();
			m_EndBlock = true;
		}
	}
	last_pc = PC;
	PC = NPC;

#if defined(_DEBUG) || defined(DEBUGFAST)
	if (PowerPC::ppcState.gpr[1] == 0)
	{
		WARN_LOG(POWERPC, "%i Corrupt stack", PowerPC::ppcState.DebugCount);
	}
	PowerPC::ppcState.DebugCount++;
#endif
	patches();

	GekkoOPInfo *opinfo = GetOpInfo(instCode);
	return opinfo->numCyclesMinusOne + 1;
}
Example #5
0
int Interpreter::SingleStepInner()
{
  if (HandleFunctionHooking(PC))
  {
    UpdatePC();
    return PPCTables::GetOpInfo(m_prev_inst)->numCycles;
  }

#ifdef USE_GDBSTUB
  if (gdb_active() && gdb_bp_x(PC))
  {
    Host_UpdateDisasmDialog();

    gdb_signal(GDB_SIGTRAP);
    gdb_handle_exception();
  }
#endif

  NPC = PC + sizeof(UGeckoInstruction);
  m_prev_inst.hex = PowerPC::Read_Opcode(PC);

  // Uncomment to trace the interpreter
  // if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624)
  //	startTrace = 1;
  // else
  //	startTrace = 0;

  if (startTrace)
  {
    Trace(m_prev_inst);
  }

  if (m_prev_inst.hex != 0)
  {
    if (IsInvalidPairedSingleExecution(m_prev_inst))
    {
      GenerateProgramException();
      CheckExceptions();
    }
    else if (MSR.FP)
    {
      m_op_table[m_prev_inst.OPCD](m_prev_inst);
      if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
      {
        CheckExceptions();
      }
    }
    else
    {
      // check if we have to generate a FPU unavailable exception or a program exception.
      if (PPCTables::UsesFPU(m_prev_inst))
      {
        PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE;
        CheckExceptions();
      }
      else
      {
        m_op_table[m_prev_inst.OPCD](m_prev_inst);
        if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
        {
          CheckExceptions();
        }
      }
    }
  }
  else
  {
    // Memory exception on instruction fetch
    CheckExceptions();
  }

  UpdatePC();
  return PPCTables::GetOpInfo(m_prev_inst)->numCycles;
}
Example #6
0
int Interpreter::SingleStepInner()
{
  if (!HandleFunctionHooking(PC))
  {
#ifdef USE_GDBSTUB
    if (gdb_active() && gdb_bp_x(PC))
    {
      Host_UpdateDisasmDialog();

      gdb_signal(SIGTRAP);
      gdb_handle_exception();
    }
#endif

    NPC = PC + sizeof(UGeckoInstruction);
    m_prev_inst.hex = PowerPC::Read_Opcode(PC);

    // Uncomment to trace the interpreter
    // if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624)
    //	startTrace = 1;
    // else
    //	startTrace = 0;

    if (startTrace)
    {
      Trace(m_prev_inst);
    }

    if (m_prev_inst.hex != 0)
    {
      if (MSR.FP)  // If FPU is enabled, just execute
      {
        m_op_table[m_prev_inst.OPCD](m_prev_inst);
        if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
        {
          PowerPC::CheckExceptions();
          m_end_block = true;
        }
      }
      else
      {
        // check if we have to generate a FPU unavailable exception
        if (!PPCTables::UsesFPU(m_prev_inst))
        {
          m_op_table[m_prev_inst.OPCD](m_prev_inst);
          if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
          {
            PowerPC::CheckExceptions();
            m_end_block = true;
          }
        }
        else
        {
          PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE;
          PowerPC::CheckExceptions();
          m_end_block = true;
        }
      }
    }
    else
    {
      // Memory exception on instruction fetch
      PowerPC::CheckExceptions();
      m_end_block = true;
    }
  }
  last_pc = PC;
  PC = NPC;

  const GekkoOPInfo* opinfo = PPCTables::GetOpInfo(m_prev_inst);
  return opinfo->numCycles;
}