mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Core: Show exception on misaligned jump.
This commit is contained in:
parent
b296bc7282
commit
80e481bbdc
@ -1086,6 +1086,12 @@ void __KernelStartIdleThreads(SceUID moduleId)
|
||||
}
|
||||
}
|
||||
|
||||
void KernelValidateThreadTarget(uint32_t pc) {
|
||||
if (!Memory::IsValidAddress(pc) || (pc & 3) != 0) {
|
||||
Core_ExecException(pc, currentMIPS->pc, ExecExceptionType::THREAD);
|
||||
}
|
||||
}
|
||||
|
||||
bool __KernelSwitchOffThread(const char *reason)
|
||||
{
|
||||
if (!reason)
|
||||
@ -1141,9 +1147,7 @@ bool __KernelSwitchToThread(SceUID threadID, const char *reason)
|
||||
if (current && current->isRunning())
|
||||
__KernelChangeReadyState(current, currentThread, true);
|
||||
|
||||
if (!Memory::IsValidAddress(t->context.pc)) {
|
||||
Core_ExecException(t->context.pc, currentMIPS->pc, ExecExceptionType::THREAD);
|
||||
}
|
||||
KernelValidateThreadTarget(t->context.pc);
|
||||
|
||||
__KernelSwitchContext(t, reason);
|
||||
return true;
|
||||
@ -1471,9 +1475,7 @@ void __KernelLoadContext(PSPThreadContext *ctx, bool vfpuEnabled) {
|
||||
memcpy(currentMIPS->vfpuCtrl, ctx->vfpuCtrl, sizeof(ctx->vfpuCtrl));
|
||||
}
|
||||
|
||||
if (!Memory::IsValidAddress(ctx->pc)) {
|
||||
Core_ExecException(ctx->pc, currentMIPS->pc, ExecExceptionType::THREAD);
|
||||
}
|
||||
KernelValidateThreadTarget(ctx->pc);
|
||||
|
||||
memcpy(currentMIPS->other, ctx->other, sizeof(ctx->other));
|
||||
// Not locking here, we assume the jit isn't switched during execution.
|
||||
@ -1924,9 +1926,7 @@ SceUID __KernelSetupRootThread(SceUID moduleID, int args, const char *argp, int
|
||||
|
||||
strcpy(thread->nt.name, "root");
|
||||
|
||||
if (!Memory::IsValidAddress(thread->context.pc)) {
|
||||
Core_ExecException(thread->context.pc, currentMIPS->pc, ExecExceptionType::THREAD);
|
||||
}
|
||||
KernelValidateThreadTarget(thread->context.pc);
|
||||
|
||||
__KernelLoadContext(&thread->context, (attr & PSP_THREAD_ATTR_VFPU) != 0);
|
||||
currentMIPS->r[MIPS_REG_A0] = args;
|
||||
@ -2057,9 +2057,7 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo
|
||||
|
||||
// Smaller is better for priority. Only switch if the new thread is better.
|
||||
if (cur && cur->nt.currentPriority > startThread->nt.currentPriority) {
|
||||
if (!Memory::IsValidAddress(startThread->context.pc)) {
|
||||
Core_ExecException(startThread->context.pc, currentMIPS->pc, ExecExceptionType::THREAD);
|
||||
}
|
||||
KernelValidateThreadTarget(startThread->context.pc);
|
||||
__KernelChangeReadyState(cur, currentThread, true);
|
||||
if (__InterruptsEnabled())
|
||||
hleReSchedule("thread started");
|
||||
@ -2939,9 +2937,7 @@ u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter)
|
||||
Memory::Write_U32(currentMIPS->r[MIPS_REG_SP], thread->currentStack.end - 8);
|
||||
Memory::Write_U32(currentMIPS->pc, thread->currentStack.end - 12);
|
||||
|
||||
if (!Memory::IsValidAddress(entryAddr)) {
|
||||
Core_ExecException(entryAddr, currentMIPS->pc, ExecExceptionType::THREAD);
|
||||
}
|
||||
KernelValidateThreadTarget(entryAddr);
|
||||
|
||||
currentMIPS->pc = entryAddr;
|
||||
currentMIPS->r[MIPS_REG_A0] = entryParameter;
|
||||
@ -2975,9 +2971,7 @@ void __KernelReturnFromExtendStack()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Memory::IsValidAddress(restorePC)) {
|
||||
Core_ExecException(restorePC, currentMIPS->pc, ExecExceptionType::THREAD);
|
||||
}
|
||||
KernelValidateThreadTarget(restorePC);
|
||||
|
||||
DEBUG_LOG(SCEKERNEL, "__KernelReturnFromExtendStack()");
|
||||
currentMIPS->r[MIPS_REG_RA] = restoreRA;
|
||||
@ -3259,9 +3253,7 @@ bool __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter)
|
||||
call->savedId = cur->currentMipscallId;
|
||||
call->reschedAfter = reschedAfter;
|
||||
|
||||
if (!Memory::IsValidAddress(call->entryPoint)) {
|
||||
Core_ExecException(call->entryPoint, currentMIPS->pc, ExecExceptionType::THREAD);
|
||||
}
|
||||
KernelValidateThreadTarget(call->entryPoint);
|
||||
|
||||
// Set up the new state
|
||||
currentMIPS->pc = call->entryPoint;
|
||||
@ -3312,9 +3304,7 @@ void __KernelReturnFromMipsCall()
|
||||
currentMIPS->r[MIPS_REG_RA] = Memory::Read_U32(sp + MIPS_REG_RA * 4);
|
||||
sp += 32 * 4;
|
||||
|
||||
if (!Memory::IsValidAddress(call->savedPc)) {
|
||||
Core_ExecException(call->savedPc, currentMIPS->pc, ExecExceptionType::THREAD);
|
||||
}
|
||||
KernelValidateThreadTarget(call->savedPc);
|
||||
|
||||
currentMIPS->pc = call->savedPc;
|
||||
// This is how we set the return value.
|
||||
|
@ -466,7 +466,7 @@ void ArmJit::Comp_Jump(MIPSOpcode op) {
|
||||
u32 targetAddr = (GetCompilerPC() & 0xF0000000) | off;
|
||||
|
||||
// Might be a stubbed address or something?
|
||||
if (!Memory::IsValidAddress(targetAddr)) {
|
||||
if (!Memory::IsValidAddress(targetAddr) || (targetAddr & 3) != 0) {
|
||||
if (js.nextExit == 0) {
|
||||
ERROR_LOG_REPORT(JIT, "Jump to invalid address: %08x", targetAddr);
|
||||
} else {
|
||||
|
@ -481,7 +481,7 @@ void Arm64Jit::Comp_Jump(MIPSOpcode op) {
|
||||
u32 targetAddr = (GetCompilerPC() & 0xF0000000) | off;
|
||||
|
||||
// Might be a stubbed address or something?
|
||||
if (!Memory::IsValidAddress(targetAddr)) {
|
||||
if (!Memory::IsValidAddress(targetAddr) || (targetAddr & 3) != 0) {
|
||||
if (js.nextExit == 0) {
|
||||
ERROR_LOG_REPORT(JIT, "Jump to invalid address: %08x", targetAddr);
|
||||
} else {
|
||||
|
@ -227,9 +227,10 @@ void IRJit::RunLoopUntil(u64 globalticks) {
|
||||
if (opcode == MIPS_EMUHACK_OPCODE) {
|
||||
u32 data = inst & 0xFFFFFF;
|
||||
IRBlock *block = blocks_.GetBlock(data);
|
||||
u32 startPC = mips_->pc;
|
||||
mips_->pc = IRInterpret(mips_, block->GetInstructions(), block->GetNumInstructions());
|
||||
if (!Memory::IsValidAddress(mips_->pc)) {
|
||||
Core_ExecException(mips_->pc, mips_->pc, ExecExceptionType::JUMP);
|
||||
if (!Memory::IsValidAddress(mips_->pc) || (mips_->pc & 3) != 0) {
|
||||
Core_ExecException(mips_->pc, startPC, ExecExceptionType::JUMP);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -57,8 +57,7 @@
|
||||
|
||||
static inline void DelayBranchTo(u32 where)
|
||||
{
|
||||
if (!Memory::IsValidAddress(where)) {
|
||||
// TODO: What about misaligned?
|
||||
if (!Memory::IsValidAddress(where) || (where & 3) != 0) {
|
||||
Core_ExecException(where, PC, ExecExceptionType::JUMP);
|
||||
}
|
||||
PC += 4;
|
||||
|
@ -612,7 +612,7 @@ void Jit::Comp_Jump(MIPSOpcode op) {
|
||||
u32 targetAddr = (GetCompilerPC() & 0xF0000000) | off;
|
||||
|
||||
// Might be a stubbed address or something?
|
||||
if (!Memory::IsValidAddress(targetAddr)) {
|
||||
if (!Memory::IsValidAddress(targetAddr) || (targetAddr & 3) != 0) {
|
||||
if (js.nextExit == 0) {
|
||||
ERROR_LOG_REPORT(JIT, "Jump to invalid address: %08x PC %08x LR %08x", targetAddr, GetCompilerPC(), currentMIPS->r[MIPS_REG_RA]);
|
||||
} else {
|
||||
|
@ -275,7 +275,7 @@ void Jit::Compile(u32 em_address) {
|
||||
ClearCache();
|
||||
}
|
||||
|
||||
if (!Memory::IsValidAddress(em_address)) {
|
||||
if (!Memory::IsValidAddress(em_address) || (em_address & 3) != 0) {
|
||||
Core_ExecException(em_address, em_address, ExecExceptionType::JUMP);
|
||||
return;
|
||||
}
|
||||
@ -672,7 +672,7 @@ static void HitInvalidBranch(uint32_t dest) {
|
||||
void Jit::WriteExit(u32 destination, int exit_num) {
|
||||
_dbg_assert_msg_(exit_num < MAX_JIT_BLOCK_EXITS, "Expected a valid exit_num");
|
||||
|
||||
if (!Memory::IsValidAddress(destination)) {
|
||||
if (!Memory::IsValidAddress(destination) || (destination & 3) != 0) {
|
||||
ERROR_LOG_REPORT(JIT, "Trying to write block exit to illegal destination %08x: pc = %08x", destination, currentMIPS->pc);
|
||||
MOV(32, MIPSSTATE_VAR(pc), Imm32(GetCompilerPC()));
|
||||
ABI_CallFunctionC(&HitInvalidBranch, destination);
|
||||
@ -721,6 +721,12 @@ void Jit::WriteExit(u32 destination, int exit_num) {
|
||||
}
|
||||
}
|
||||
|
||||
static u32 IsValidJumpTarget(uint32_t addr) {
|
||||
if (Memory::IsValidAddress(addr) && (addr & 3) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void HitInvalidJumpReg(uint32_t source) {
|
||||
Core_ExecException(currentMIPS->pc, source, ExecExceptionType::JUMP);
|
||||
currentMIPS->pc = source + 8;
|
||||
@ -762,7 +768,7 @@ void Jit::WriteExitDestInReg(X64Reg reg) {
|
||||
SetJumpTarget(tooLow);
|
||||
SetJumpTarget(tooHigh);
|
||||
|
||||
ABI_CallFunctionA((const void *)&Memory::IsValidAddress, R(reg));
|
||||
ABI_CallFunctionA((const void *)&IsValidJumpTarget, R(reg));
|
||||
|
||||
// If we're ignoring, coreState didn't trip - so trip it now.
|
||||
CMP(32, R(EAX), Imm32(0));
|
||||
|
Loading…
Reference in New Issue
Block a user