mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Make fastmem memory exceptions report the exceptions to Core correctly.
This commit is contained in:
parent
465367bf1b
commit
a56f391713
@ -40,7 +40,7 @@ static BadAccessHandler g_badAccessHandler;
|
||||
|
||||
static PVOID g_vectoredExceptionHandle;
|
||||
|
||||
static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) {
|
||||
static LONG NTAPI GlobalExceptionHandler(PEXCEPTION_POINTERS pPtrs) {
|
||||
switch (pPtrs->ExceptionRecord->ExceptionCode) {
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
{
|
||||
@ -96,7 +96,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) {
|
||||
|
||||
INFO_LOG(SYSTEM, "Installing exception handler");
|
||||
g_badAccessHandler = badAccessHandler;
|
||||
g_vectoredExceptionHandle = AddVectoredExceptionHandler(TRUE, Handler);
|
||||
g_vectoredExceptionHandle = AddVectoredExceptionHandler(TRUE, GlobalExceptionHandler);
|
||||
}
|
||||
|
||||
void UninstallExceptionHandler() {
|
||||
|
@ -80,6 +80,7 @@ void Core_SetPowerSaving(bool mode);
|
||||
bool Core_GetPowerSaving();
|
||||
|
||||
enum class MemoryExceptionType {
|
||||
NONE,
|
||||
READ_WORD,
|
||||
WRITE_WORD,
|
||||
READ_BLOCK,
|
||||
|
@ -513,28 +513,38 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
||||
|
||||
// TODO: Share the struct between the various analyzers, that will allow us to share most of
|
||||
// the implementations here.
|
||||
bool success = false;
|
||||
|
||||
MemoryExceptionType type = MemoryExceptionType::NONE;
|
||||
|
||||
#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86)
|
||||
// X86, X86-64. Variable instruction size so need to analyze the mov instruction in detail.
|
||||
|
||||
// To ignore the access, we need to disassemble the instruction and modify context->CTX_PC
|
||||
LSInstructionInfo info;
|
||||
X86AnalyzeMOV(codePtr, info);
|
||||
success = X86AnalyzeMOV(codePtr, info);
|
||||
#elif PPSSPP_ARCH(ARM64)
|
||||
uint32_t word;
|
||||
memcpy(&word, codePtr, 4);
|
||||
// To ignore the access, we need to disassemble the instruction and modify context->CTX_PC
|
||||
Arm64LSInstructionInfo info;
|
||||
Arm64AnalyzeLoadStore((uint64_t)codePtr, word, &info);
|
||||
success = Arm64AnalyzeLoadStore((uint64_t)codePtr, word, &info);
|
||||
#elif PPSSPP_ARCH(ARM)
|
||||
uint32_t word;
|
||||
memcpy(&word, codePtr, 4);
|
||||
// To ignore the access, we need to disassemble the instruction and modify context->CTX_PC
|
||||
ArmLSInstructionInfo info;
|
||||
ArmAnalyzeLoadStore((uint32_t)codePtr, word, &info);
|
||||
success = ArmAnalyzeLoadStore((uint32_t)codePtr, word, &info);
|
||||
#endif
|
||||
if (success) {
|
||||
if (info.isMemoryWrite) {
|
||||
type = MemoryExceptionType::WRITE_WORD;
|
||||
} else {
|
||||
type = MemoryExceptionType::READ_WORD;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Config.bIgnoreBadMemAccess) {
|
||||
if (success && g_Config.bIgnoreBadMemAccess) {
|
||||
if (!info.isMemoryWrite) {
|
||||
// It was a read. Fill the destination register with 0.
|
||||
// TODO
|
||||
@ -546,6 +556,10 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
||||
ERROR_LOG(MEMMAP, "Bad memory access detected and ignored: %08x (%p)", guestAddress, (void *)hostAddress);
|
||||
}
|
||||
} else {
|
||||
// Either bIgnoreBadMemAccess is off, or we failed recovery analysis.
|
||||
uint32_t approximatePC = currentMIPS->pc;
|
||||
Core_MemoryException(guestAddress, currentMIPS->pc, type);
|
||||
|
||||
// Redirect execution to a crash handler that will exit the game.
|
||||
context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler();
|
||||
ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation.", guestAddress, (void *)hostAddress);
|
||||
|
@ -1158,7 +1158,7 @@ void EmuScreen::update() {
|
||||
PSP_CoreParameter().pixelHeight = pixel_yres * bounds.h / dp_yres;
|
||||
#endif
|
||||
|
||||
if (!invalid_) {
|
||||
if (!invalid_ && coreState != CORE_RUNTIME_ERROR) {
|
||||
UpdateUIState(UISTATE_INGAME);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user