Invalidate code that HLE and the debugger write over

Helper thread stubs, fake syscall stubs and the module start trampoline go into memory that may
have held code (freed kernel memory, a reused thread stack), and the debugger memory views can
edit code. Invalidate what they write, which so far only happened by accident when the write hit
the first instruction of a JIT block.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-11 10:33:30 +02:00
1 parent 59fed92dac
commit 0a8ec4d8f1
5 files changed
+21 -2

No files matched your search

+4
View File
@@ -24,6 +24,7 @@
#include "Core/HLE/KernelWaitHelpers.h"
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/MIPSCodeUtils.h"
HLEHelperThread::HLEHelperThread(const char *threadName, const u32 instructions[], u32 instrCount, u32 prio, int stacksize) {
@@ -36,6 +37,8 @@ HLEHelperThread::HLEHelperThread(const char *threadName, const u32 instructions[
// Just to simplify things, we add the return here.
Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), entry_ + instrBytes + 0);
Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), entry_ + instrBytes + 4);
// The memory may have held another helper's code, already compiled.
currentMIPS->InvalidateICacheRangeDeferred(entry_, totalBytes);
Create(threadName, prio, stacksize);
}
@@ -46,6 +49,7 @@ HLEHelperThread::HLEHelperThread(const char *threadName, const char *module, con
_dbg_assert_(Memory::IsValid4AlignedAddress(entry_)); // after AllocEntry.
Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), entry_ + 0);
Memory::WriteUnchecked_U32(MIPS_MAKE_SYSCALL(module, func), entry_ + 4);
currentMIPS->InvalidateICacheRangeDeferred(entry_, bytes);
Create(threadName, prio, stacksize);
}