Core: Remove Memory exception filer
This commit is contained in:
parent
65a9097980
commit
73c9174ce9
|
@ -292,7 +292,6 @@ CJniBridegSettings::CJniBridegSettings()
|
||||||
ADD_SETTING(Debugger_TraceTLB);
|
ADD_SETTING(Debugger_TraceTLB);
|
||||||
ADD_SETTING(Debugger_TraceUserInterface);
|
ADD_SETTING(Debugger_TraceUserInterface);
|
||||||
ADD_SETTING(Debugger_TraceRomList);
|
ADD_SETTING(Debugger_TraceRomList);
|
||||||
ADD_SETTING(Debugger_TraceExceptionHandler);
|
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
ADD_SETTING(Plugin_RSP_Current);
|
ADD_SETTING(Plugin_RSP_Current);
|
||||||
|
|
|
@ -70,7 +70,6 @@ void SetTraceModuleNames(void)
|
||||||
TraceSetModuleName(TraceTLB, "TLB");
|
TraceSetModuleName(TraceTLB, "TLB");
|
||||||
TraceSetModuleName(TraceUserInterface, "User Interface");
|
TraceSetModuleName(TraceUserInterface, "User Interface");
|
||||||
TraceSetModuleName(TraceRomList, "Rom List");
|
TraceSetModuleName(TraceRomList, "Rom List");
|
||||||
TraceSetModuleName(TraceExceptionHandler, "Exception Handler");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateTraceLevel(void * /*NotUsed*/)
|
void UpdateTraceLevel(void * /*NotUsed*/)
|
||||||
|
@ -95,7 +94,6 @@ void UpdateTraceLevel(void * /*NotUsed*/)
|
||||||
g_ModuleLogLevel[TraceTLB] = (uint8_t)g_Settings->LoadDword(Debugger_TraceTLB);
|
g_ModuleLogLevel[TraceTLB] = (uint8_t)g_Settings->LoadDword(Debugger_TraceTLB);
|
||||||
g_ModuleLogLevel[TraceUserInterface] = (uint8_t)g_Settings->LoadDword(Debugger_TraceUserInterface);
|
g_ModuleLogLevel[TraceUserInterface] = (uint8_t)g_Settings->LoadDword(Debugger_TraceUserInterface);
|
||||||
g_ModuleLogLevel[TraceRomList] = (uint8_t)g_Settings->LoadDword(Debugger_TraceRomList);
|
g_ModuleLogLevel[TraceRomList] = (uint8_t)g_Settings->LoadDword(Debugger_TraceRomList);
|
||||||
g_ModuleLogLevel[TraceExceptionHandler] = (uint8_t)g_Settings->LoadDword(Debugger_TraceExceptionHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupTrace(void)
|
void SetupTrace(void)
|
||||||
|
@ -122,7 +120,6 @@ void SetupTrace(void)
|
||||||
g_Settings->RegisterChangeCB(Debugger_TraceTLB, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
g_Settings->RegisterChangeCB(Debugger_TraceTLB, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
||||||
g_Settings->RegisterChangeCB(Debugger_TraceUserInterface, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
g_Settings->RegisterChangeCB(Debugger_TraceUserInterface, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
||||||
g_Settings->RegisterChangeCB(Debugger_TraceRomList, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
g_Settings->RegisterChangeCB(Debugger_TraceRomList, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
||||||
g_Settings->RegisterChangeCB(Debugger_TraceExceptionHandler, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
|
||||||
g_Settings->RegisterChangeCB(Debugger_AppLogFlush, g_LogFile, (CSettings::SettingChangedFunc)LogFlushChanged);
|
g_Settings->RegisterChangeCB(Debugger_AppLogFlush, g_LogFile, (CSettings::SettingChangedFunc)LogFlushChanged);
|
||||||
UpdateTraceLevel(nullptr);
|
UpdateTraceLevel(nullptr);
|
||||||
|
|
||||||
|
@ -153,7 +150,6 @@ void CleanupTrace(void)
|
||||||
g_Settings->UnregisterChangeCB(Debugger_TraceTLB, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
g_Settings->UnregisterChangeCB(Debugger_TraceTLB, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
||||||
g_Settings->UnregisterChangeCB(Debugger_TraceUserInterface, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
g_Settings->UnregisterChangeCB(Debugger_TraceUserInterface, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
||||||
g_Settings->UnregisterChangeCB(Debugger_TraceRomList, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
g_Settings->UnregisterChangeCB(Debugger_TraceRomList, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
||||||
g_Settings->UnregisterChangeCB(Debugger_TraceExceptionHandler, nullptr, (CSettings::SettingChangedFunc)UpdateTraceLevel);
|
|
||||||
g_Settings->UnregisterChangeCB(Debugger_AppLogFlush, g_LogFile, (CSettings::SettingChangedFunc)LogFlushChanged);
|
g_Settings->UnregisterChangeCB(Debugger_AppLogFlush, g_LogFile, (CSettings::SettingChangedFunc)LogFlushChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,15 +244,8 @@ bool AppInit(CNotification * Notify, const char * BaseDirectory, int argc, char
|
||||||
|
|
||||||
SetupTrace();
|
SetupTrace();
|
||||||
FixDirectories();
|
FixDirectories();
|
||||||
CMipsMemoryVM::ReserveMemory();
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
IncreaseThreadPriority();
|
IncreaseThreadPriority();
|
||||||
#else
|
|
||||||
if (!CMipsMemoryVM::SetupSegvHandler())
|
|
||||||
{
|
|
||||||
WriteTrace(TraceAppInit, TraceDebug, "Setup SEGV handler failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
g_Enhancements = new CEnhancements();
|
g_Enhancements = new CEnhancements();
|
||||||
|
|
||||||
|
@ -318,8 +307,6 @@ void AppCleanup(void)
|
||||||
delete g_Lang;
|
delete g_Lang;
|
||||||
g_Lang = nullptr;
|
g_Lang = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMipsMemoryVM::FreeReservedMemory();
|
|
||||||
TraceDone();
|
TraceDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,682 +0,0 @@
|
||||||
#include "stdafx.h"
|
|
||||||
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
|
|
||||||
#include <Project64-core/N64System/N64System.h>
|
|
||||||
#include <Project64-core/N64System/Recompiler/Recompiler.h>
|
|
||||||
#include <Project64-core/N64System/SystemGlobals.h>
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
#ifdef __arm__
|
|
||||||
#include <Project64-core/N64System/Recompiler/Arm/ArmOpCode.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__i386__) || defined(_M_IX86)
|
|
||||||
|
|
||||||
bool CMipsMemoryVM::FilterX86Exception(uint32_t MemAddress, X86_CONTEXT & context)
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceVerbose, "MemAddress: %X", MemAddress);
|
|
||||||
uint32_t * Reg;
|
|
||||||
|
|
||||||
if (g_MMU == nullptr)
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "g_MMU == nullptr");
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((int32_t)(MemAddress) < 0 || MemAddress > 0x1FFFFFFF)
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "Invalid memory address: %X", MemAddress);
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t * TypePos = (uint8_t *)*(context.Eip);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceVerbose, "TypePos[0] = %02X TypePos[1] = %02X", TypePos[0], TypePos[2]);
|
|
||||||
|
|
||||||
Reg = nullptr;
|
|
||||||
if (*TypePos == 0xF3 && (*(TypePos + 1) == 0xA4 || *(TypePos + 1) == 0xA5))
|
|
||||||
{
|
|
||||||
uint32_t Start = (*context.Edi - (uint32_t)g_MMU->m_RDRAM);
|
|
||||||
uint32_t End = Start + *context.Ecx;
|
|
||||||
if ((int32_t)Start < 0)
|
|
||||||
{
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (End < g_MMU->RdramSize() && g_Recompiler)
|
|
||||||
{
|
|
||||||
for (uint32_t count = (Start & ~0xFFF); count < End; count += 0x1000)
|
|
||||||
{
|
|
||||||
g_Recompiler->ClearRecompCode_Phys(count, 0x1000, CRecompiler::Remove_ProtectedMem);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (Start >= 0x04000000 && End < 0x04002000 && g_Recompiler)
|
|
||||||
{
|
|
||||||
g_Recompiler->ClearRecompCode_Phys(Start & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t * ReadPos;
|
|
||||||
if (*TypePos == 0x0F && *(TypePos + 1) == 0xB6)
|
|
||||||
{
|
|
||||||
ReadPos = TypePos + 2;
|
|
||||||
}
|
|
||||||
else if (*TypePos == 0x0F && *(TypePos + 1) == 0xB7)
|
|
||||||
{
|
|
||||||
ReadPos = TypePos + 2;
|
|
||||||
}
|
|
||||||
else if (*TypePos == 0x0F && *(TypePos + 1) == 0xBE)
|
|
||||||
{
|
|
||||||
ReadPos = TypePos + 2;
|
|
||||||
}
|
|
||||||
else if (*TypePos == 0x0F && *(TypePos + 1) == 0xBF)
|
|
||||||
{
|
|
||||||
ReadPos = TypePos + 2;
|
|
||||||
}
|
|
||||||
else if (*TypePos == 0x66)
|
|
||||||
{
|
|
||||||
ReadPos = TypePos + 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ReadPos = TypePos + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (*ReadPos & 0x38)
|
|
||||||
{
|
|
||||||
case 0x00: Reg = context.Eax; break;
|
|
||||||
case 0x08: Reg = context.Ecx; break;
|
|
||||||
case 0x10: Reg = context.Edx; break;
|
|
||||||
case 0x18: Reg = context.Ebx; break;
|
|
||||||
case 0x20: Reg = context.Esp; break;
|
|
||||||
case 0x28: Reg = context.Ebp; break;
|
|
||||||
case 0x30: Reg = context.Esi; break;
|
|
||||||
case 0x38: Reg = context.Edi; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ((*ReadPos & 0xC7))
|
|
||||||
{
|
|
||||||
case 0: ReadPos += 1; break;
|
|
||||||
case 1: ReadPos += 1; break;
|
|
||||||
case 2: ReadPos += 1; break;
|
|
||||||
case 3: ReadPos += 1; break;
|
|
||||||
case 4:
|
|
||||||
ReadPos += 1;
|
|
||||||
switch ((*ReadPos & 0xC7))
|
|
||||||
{
|
|
||||||
case 0: ReadPos += 1; break;
|
|
||||||
case 1: ReadPos += 1; break;
|
|
||||||
case 2: ReadPos += 1; break;
|
|
||||||
case 3: ReadPos += 1; break;
|
|
||||||
case 5: ReadPos += 5; break;
|
|
||||||
case 6: ReadPos += 1; break;
|
|
||||||
case 7: ReadPos += 1; break;
|
|
||||||
case 0x80: ReadPos += 1; break;
|
|
||||||
default:
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5: ReadPos += 5; break;
|
|
||||||
case 6: ReadPos += 1; break;
|
|
||||||
case 7: ReadPos += 1; break;
|
|
||||||
case 0x40: ReadPos += 2; break;
|
|
||||||
case 0x41: ReadPos += 2; break;
|
|
||||||
case 0x42: ReadPos += 2; break;
|
|
||||||
case 0x43: ReadPos += 2; break;
|
|
||||||
case 0x44: ReadPos += 3; break;
|
|
||||||
case 0x46: ReadPos += 2; break;
|
|
||||||
case 0x47: ReadPos += 2; break;
|
|
||||||
case 0x80: ReadPos += 5; break;
|
|
||||||
case 0x81: ReadPos += 5; break;
|
|
||||||
case 0x82: ReadPos += 5; break;
|
|
||||||
case 0x83: ReadPos += 5; break;
|
|
||||||
case 0x86: ReadPos += 5; break;
|
|
||||||
case 0x87: ReadPos += 5; break;
|
|
||||||
default:
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Reg == nullptr)
|
|
||||||
{
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (*TypePos)
|
|
||||||
{
|
|
||||||
case 0x0F:
|
|
||||||
switch (*(TypePos + 1))
|
|
||||||
{
|
|
||||||
case 0xB6:
|
|
||||||
{
|
|
||||||
uint8_t Value = 0;
|
|
||||||
g_MMU->LB_PhysicalAddress(MemAddress ^ 3, Value);
|
|
||||||
*(uint32_t *)Reg = Value;
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 0xB7:
|
|
||||||
{
|
|
||||||
uint16_t Value = 0;
|
|
||||||
g_MMU->LH_PhysicalAddress(MemAddress ^ 2, Value);
|
|
||||||
*(uint32_t *)Reg = Value;
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 0xBE:
|
|
||||||
{
|
|
||||||
uint8_t Value = 0;
|
|
||||||
g_MMU->LB_PhysicalAddress(MemAddress ^ 3, Value);
|
|
||||||
*(int32_t *)Reg = (int8_t)Value;
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 0xBF:
|
|
||||||
{
|
|
||||||
uint16_t Value = 0;
|
|
||||||
g_MMU->LH_PhysicalAddress(MemAddress ^ 2, Value);
|
|
||||||
*(int32_t *)Reg = (int16_t)Value;
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x66:
|
|
||||||
switch (*(TypePos + 1))
|
|
||||||
{
|
|
||||||
case 0x8B:
|
|
||||||
{
|
|
||||||
uint16_t Value = 0;
|
|
||||||
g_MMU->LH_PhysicalAddress(MemAddress ^ 2, Value);
|
|
||||||
*(uint32_t *)Reg = Value;
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 0x89:
|
|
||||||
g_MMU->SH_PhysicalAddress(MemAddress ^ 2, *(uint16_t *)Reg);
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
case 0xA3:
|
|
||||||
g_MMU->SH_PhysicalAddress(MemAddress ^ 2, *(uint16_t *)context.Eax);
|
|
||||||
*context.Eip += 6;
|
|
||||||
return true;
|
|
||||||
case 0xC7:
|
|
||||||
if (Reg != context.Eax)
|
|
||||||
{
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
g_MMU->SH_PhysicalAddress(MemAddress ^ 2, *(uint16_t *)ReadPos);
|
|
||||||
*context.Eip = (uint32_t)(ReadPos + 2);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x88:
|
|
||||||
g_MMU->SB_PhysicalAddress(MemAddress ^ 3, *(uint8_t *)Reg);
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
case 0x8A:
|
|
||||||
{
|
|
||||||
uint8_t Value = 0;
|
|
||||||
g_MMU->LB_PhysicalAddress(MemAddress ^ 3, Value);
|
|
||||||
*(uint32_t *)Reg = Value;
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 0x8B:
|
|
||||||
g_MMU->LW_PhysicalAddress(MemAddress, *((uint32_t *)Reg));
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
case 0x89:
|
|
||||||
g_MMU->SW_PhysicalAddress(MemAddress, *(uint32_t *)Reg);
|
|
||||||
*context.Eip = (uint32_t)ReadPos;
|
|
||||||
return true;
|
|
||||||
case 0xC6:
|
|
||||||
if (Reg != context.Eax)
|
|
||||||
{
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
g_MMU->SB_PhysicalAddress(MemAddress ^ 3, *(uint8_t *)ReadPos);
|
|
||||||
*context.Eip = (uint32_t)(ReadPos + 1);
|
|
||||||
return true;
|
|
||||||
case 0xC7:
|
|
||||||
if (Reg != context.Eax)
|
|
||||||
{
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
g_MMU->SW_PhysicalAddress(MemAddress, *(uint32_t *)ReadPos);
|
|
||||||
*context.Eip = (uint32_t)(ReadPos + 4);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __arm__
|
|
||||||
void CMipsMemoryVM::DumpArmExceptionInfo(uint32_t MemAddress, mcontext_t & context)
|
|
||||||
{
|
|
||||||
ArmThumbOpcode * OpCode = (ArmThumbOpcode *)context.arm_pc;
|
|
||||||
Arm32Opcode * OpCode32 = (Arm32Opcode *)context.arm_pc;
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "Program counter 0x%lx", g_Reg->m_PROGRAM_COUNTER);
|
|
||||||
for (int i = 0, n = (sizeof(g_BaseSystem->m_LastSuccessSyncPC) / sizeof(g_BaseSystem->m_LastSuccessSyncPC[0])); i < n; i++)
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "m_LastSuccessSyncPC[%d] = 0x%lx", i, g_BaseSystem->m_LastSuccessSyncPC[i]);
|
|
||||||
}
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "MemAddress = 0x%lx", MemAddress);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r0 = 0x%lx", context.arm_r0);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r1 = 0x%lx", context.arm_r1);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r2 = 0x%lx", context.arm_r2);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r3 = 0x%lx", context.arm_r3);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r4 = 0x%lx", context.arm_r4);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r5 = 0x%lx", context.arm_r5);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r6 = 0x%lx", context.arm_r6);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r7 = 0x%lx", context.arm_r7);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r8 = 0x%lx", context.arm_r8);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r9 = 0x%lx", context.arm_r9);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r10 = 0x%lx", context.arm_r10);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_fp = 0x%lx", context.arm_fp);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_ip = 0x%lx", context.arm_ip);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_sp = 0x%lx", context.arm_sp);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_lr = 0x%lx", context.arm_lr);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_pc = 0x%lx", context.arm_pc);
|
|
||||||
|
|
||||||
uint8_t * TypePos = (uint8_t *)context.arm_pc;
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "TypePos: %02X %02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0], TypePos[1], TypePos[2], TypePos[3], TypePos[4], TypePos[5], TypePos[6], TypePos[7], TypePos[8]);
|
|
||||||
|
|
||||||
TypePos = (uint8_t *)context.arm_pc - 0x40;
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "code:");
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x00], TypePos[0x01], TypePos[0x02], TypePos[0x03], TypePos[0x04], TypePos[0x05], TypePos[0x06], TypePos[0x07]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x08], TypePos[0x09], TypePos[0x0A], TypePos[0x0B], TypePos[0x0C], TypePos[0x0D], TypePos[0x0E], TypePos[0x0F]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x10], TypePos[0x11], TypePos[0x12], TypePos[0x13], TypePos[0x14], TypePos[0x15], TypePos[0x16], TypePos[0x17]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x18], TypePos[0x19], TypePos[0x1A], TypePos[0x1B], TypePos[0x1C], TypePos[0x1D], TypePos[0x1E], TypePos[0x1F]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x20], TypePos[0x21], TypePos[0x22], TypePos[0x23], TypePos[0x24], TypePos[0x25], TypePos[0x26], TypePos[0x27]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x28], TypePos[0x29], TypePos[0x2A], TypePos[0x2B], TypePos[0x2C], TypePos[0x2D], TypePos[0x2E], TypePos[0x2F]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x30], TypePos[0x31], TypePos[0x32], TypePos[0x33], TypePos[0x34], TypePos[0x35], TypePos[0x36], TypePos[0x37]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x38], TypePos[0x39], TypePos[0x3A], TypePos[0x3B], TypePos[0x3C], TypePos[0x3D], TypePos[0x3E], TypePos[0x3F]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x40], TypePos[0x41], TypePos[0x42], TypePos[0x43], TypePos[0x44], TypePos[0x45], TypePos[0x46], TypePos[0x47]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x48], TypePos[0x49], TypePos[0x4A], TypePos[0x4B], TypePos[0x4C], TypePos[0x4D], TypePos[0x4E], TypePos[0x4F]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x50], TypePos[0x51], TypePos[0x52], TypePos[0x53], TypePos[0x54], TypePos[0x55], TypePos[0x56], TypePos[0x57]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x58], TypePos[0x59], TypePos[0x5A], TypePos[0x5B], TypePos[0x5C], TypePos[0x5D], TypePos[0x5E], TypePos[0x5F]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x60], TypePos[0x61], TypePos[0x62], TypePos[0x63], TypePos[0x64], TypePos[0x65], TypePos[0x66], TypePos[0x67]);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "%02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0x68], TypePos[0x69], TypePos[0x6A], TypePos[0x6B], TypePos[0x6C], TypePos[0x6D], TypePos[0x6E], TypePos[0x6F]);
|
|
||||||
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.Hex: %X", OpCode->Hex);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.opcode: %X", OpCode->Reg.opcode);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rm: %X", OpCode->Reg.rm);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rn: %X", OpCode->Reg.rn);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rt: %X", OpCode->Reg.rt);
|
|
||||||
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32.Hex: %X", OpCode32->Hex);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.opcode: %X", OpCode32->uint16.opcode);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.rm: %X", OpCode32->uint16.rm);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.rn: %X", OpCode32->uint16.rn);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.rt: %X", OpCode32->uint16.rt);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.imm2: %X", OpCode32->uint16.imm2);
|
|
||||||
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.opcode: %X", OpCode32->uint32.opcode);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.rn: %X", OpCode32->uint32.rn);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.rt: %X", OpCode32->uint32.rt);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.opcode2: %X", OpCode32->uint32.opcode2);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.rm: %X", OpCode32->uint32.rm);
|
|
||||||
|
|
||||||
for (int count = 0; count < 32; count++)
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "GPR[%s] 0x%08X%08X", CRegName::GPR[count], g_Reg->m_GPR[count].W[1], g_Reg->m_GPR[count].W[0]);
|
|
||||||
}
|
|
||||||
TraceFlushLog();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context)
|
|
||||||
{
|
|
||||||
if ((int32_t)(MemAddress) < 0 || MemAddress > 0x1FFFFFFF)
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "Invalid memory address: %X", MemAddress);
|
|
||||||
DumpArmExceptionInfo(MemAddress, context);
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t * ArmRegisters[16] = {
|
|
||||||
(uint32_t *)&context.arm_r0,
|
|
||||||
(uint32_t *)&context.arm_r1,
|
|
||||||
(uint32_t *)&context.arm_r2,
|
|
||||||
(uint32_t *)&context.arm_r3,
|
|
||||||
(uint32_t *)&context.arm_r4,
|
|
||||||
(uint32_t *)&context.arm_r5,
|
|
||||||
(uint32_t *)&context.arm_r6,
|
|
||||||
(uint32_t *)&context.arm_r7,
|
|
||||||
(uint32_t *)&context.arm_r8,
|
|
||||||
(uint32_t *)&context.arm_r9,
|
|
||||||
(uint32_t *)&context.arm_r10,
|
|
||||||
(uint32_t *)&context.arm_fp,
|
|
||||||
(uint32_t *)&context.arm_ip,
|
|
||||||
(uint32_t *)&context.arm_sp,
|
|
||||||
(uint32_t *)&context.arm_lr,
|
|
||||||
(uint32_t *)&context.arm_pc,
|
|
||||||
};
|
|
||||||
|
|
||||||
ArmThumbOpcode * OpCode = (ArmThumbOpcode *)context.arm_pc;
|
|
||||||
Arm32Opcode * OpCode32 = (Arm32Opcode *)context.arm_pc;
|
|
||||||
if (OpCode->Reg.opcode == ArmLDR_Reg)
|
|
||||||
{
|
|
||||||
g_MMU->LW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode->Reg.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (OpCode->Reg.opcode == ArmSTR_Reg)
|
|
||||||
{
|
|
||||||
g_MMU->SW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode->Reg.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->imm2.opcode == 0xF84 && OpCode32->imm2.Opcode2 == 0)
|
|
||||||
{
|
|
||||||
// 42 f8 03 c0 str.w ip, [r2, r3]
|
|
||||||
g_MMU->SW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode32->imm2.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->imm12.opcode == 0xF8C)
|
|
||||||
{
|
|
||||||
// c9 f8 00 b0 str.w r11, [r9]
|
|
||||||
g_MMU->SW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode32->imm2.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->imm12.opcode == 0xF8D)
|
|
||||||
{
|
|
||||||
// dc f8 70 70 ldr.w r7, [ip, #112]
|
|
||||||
g_MMU->LW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode32->imm12.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->reg_cond_imm5.opcode == 3 && OpCode32->reg_cond_imm5.opcode1 == 0 && OpCode32->reg_cond_imm5.opcode2 == 0 && OpCode32->reg_cond_imm5.opcode3 == 0)
|
|
||||||
{
|
|
||||||
// 17847001 strne r7, [r4, r1]
|
|
||||||
// e789300c str r3, [r9, ip]
|
|
||||||
g_MMU->SW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode32->reg_cond_imm5.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode->Reg.opcode == 0x2A) // STRB
|
|
||||||
{
|
|
||||||
g_MMU->SB_PhysicalAddress(MemAddress ^ 3, *ArmRegisters[OpCode->Reg.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->reg_cond_imm5.opcode == 3 && OpCode32->reg_cond_imm5.opcode1 == 1 && OpCode32->reg_cond_imm5.opcode2 == 0 && OpCode32->reg_cond_imm5.opcode3 == 0)
|
|
||||||
{
|
|
||||||
// 17c32001 strbne r2, [r3, r1]
|
|
||||||
g_MMU->SB_PhysicalAddress(MemAddress ^ 3, *ArmRegisters[OpCode32->reg_cond_imm5.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->reg_cond_imm8.opcode == 0 && OpCode32->reg_cond_imm8.opcode1 == 1 && OpCode32->reg_cond_imm8.opcode2 == 0 && OpCode32->reg_cond_imm8.opcode3 == 0xB)
|
|
||||||
{
|
|
||||||
// 11c020b0 strhne r2, [r0]
|
|
||||||
g_MMU->SH_PhysicalAddress(MemAddress ^ 2, *ArmRegisters[OpCode32->reg_cond_imm8.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode->Imm5.opcode == 0x10)
|
|
||||||
{
|
|
||||||
// 00 80 strh r0, [r0, #0]
|
|
||||||
g_MMU->SH_PhysicalAddress(MemAddress ^ 2, *ArmRegisters[OpCode->Imm5.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode->Reg.opcode == 0x29)
|
|
||||||
{
|
|
||||||
// 14 52 strh r4, [r2, r0]
|
|
||||||
g_MMU->SH_PhysicalAddress(MemAddress ^ 2, *ArmRegisters[OpCode->Reg.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode->Imm5.opcode == 0xC)
|
|
||||||
{
|
|
||||||
// 2e 60 str r6, [r5, #0]
|
|
||||||
g_MMU->SH_PhysicalAddress(MemAddress ^ 2, *ArmRegisters[OpCode->Imm5.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode->Imm5.opcode == 0xD)
|
|
||||||
{
|
|
||||||
// 3F 68 ldr r7, [r7, #0]
|
|
||||||
g_MMU->LW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode->Imm5.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode->Imm5.opcode == 0xE)
|
|
||||||
{
|
|
||||||
// b8 70 strb r0, [r7, #2]
|
|
||||||
g_MMU->SB_PhysicalAddress(MemAddress ^ 3, *ArmRegisters[OpCode->Imm5.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->reg_cond.opcode == 0 && OpCode32->reg_cond.opcode1 == 0 && OpCode32->reg_cond.opcode2 == 0 && OpCode32->reg_cond.opcode3 == 0xB)
|
|
||||||
{
|
|
||||||
// 118320b1 strhne r2, [r3, r1]
|
|
||||||
g_MMU->SH_PhysicalAddress(MemAddress ^ 2, *ArmRegisters[OpCode32->reg_cond.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->reg_cond_imm12.opcode == 2 && OpCode32->reg_cond_imm12.opcode1 == 0 && OpCode32->reg_cond_imm12.opcode2 == 0)
|
|
||||||
{
|
|
||||||
// e48a1004 str r1, [sl], #4
|
|
||||||
g_MMU->SW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode32->reg_cond_imm12.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (OpCode32->uint16.opcode == ArmLDRH_W)
|
|
||||||
{
|
|
||||||
// f833 c001 ldrh.w ip, [r3, r1]
|
|
||||||
g_MMU->LH_PhysicalAddress(MemAddress ^ 2, ArmRegisters[OpCode32->uint16.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->uint32.opcode == ArmLDRH_Reg && OpCode32->uint32.opcode2 == 0xB)
|
|
||||||
{
|
|
||||||
// e19a20b2 ldrh r2, [sl, r2]
|
|
||||||
g_MMU->LH_PhysicalAddress(MemAddress ^ 2, ArmRegisters[OpCode32->uint32.rt], false);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->reg_cond.opcode == 0 && OpCode32->reg_cond.opcode1 == 0 && OpCode32->reg_cond.opcode2 == 1 && OpCode32->reg_cond.opcode3 == 0xB)
|
|
||||||
{
|
|
||||||
// 119330b1 ldrhne r3, [r3, r1]
|
|
||||||
// 11d000b0 ldrhne r0, [r0]
|
|
||||||
!g_MMU->LH_PhysicalAddress(MemAddress ^ 2, ArmRegisters[OpCode32->reg_cond.rt], false);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (OpCode32->reg_cond_imm5.opcode == 3 && OpCode32->reg_cond_imm5.opcode1 == 0 && OpCode32->reg_cond_imm5.opcode2 == 1 && OpCode32->reg_cond_imm5.opcode3 == 0)
|
|
||||||
{
|
|
||||||
// 1790a001 ldrne sl, [r0, r1]
|
|
||||||
g_MMU->LW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode32->reg_cond_imm5.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OpCode32->imm2.opcode == 0xF85 && OpCode32->imm2.Opcode2 == 0)
|
|
||||||
{
|
|
||||||
// 52 f8 21 30 ldr.w r3, [r2, r1, lsl #2]
|
|
||||||
g_MMU->LW_PhysicalAddress(MemAddress, *ArmRegisters[OpCode32->imm2.rt]);
|
|
||||||
context.arm_pc = context.arm_pc + 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
DumpArmExceptionInfo(MemAddress, context);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
bool CMipsMemoryVM::SetupSegvHandler(void)
|
|
||||||
{
|
|
||||||
struct sigaction sig_act;
|
|
||||||
sig_act.sa_flags = SA_SIGINFO | SA_RESTART;
|
|
||||||
sig_act.sa_sigaction = segv_handler;
|
|
||||||
return sigaction(SIGSEGV, &sig_act, nullptr) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMipsMemoryVM::segv_handler(int signal, siginfo_t * siginfo, void * sigcontext)
|
|
||||||
{
|
|
||||||
ucontext_t * ucontext = (ucontext_t *)sigcontext;
|
|
||||||
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "Segmentation fault!");
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "info.si_signo = %d", signal);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "info.si_errno = %d", siginfo->si_errno);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "info.si_code = %d", siginfo->si_code);
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "info.si_addr = %p", siginfo->si_addr);
|
|
||||||
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "%s: si_addr: %p", __FUNCTION__, siginfo->si_addr);
|
|
||||||
|
|
||||||
uint32_t MemAddress = (char *)siginfo->si_addr - (char *)g_MMU->Rdram();
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "MemAddress = %X", MemAddress);
|
|
||||||
#ifdef __i386__
|
|
||||||
for (int i = 0; i < NGREG; i++)
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "reg[%02d] = 0x%08x", i, ucontext->uc_mcontext.gregs[i]);
|
|
||||||
}
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "REG_EIP = %X", ucontext->uc_mcontext.gregs[REG_EIP]);
|
|
||||||
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "Data:");
|
|
||||||
for (uint8_t * TypePos = (uint8_t *)ucontext->uc_mcontext.gregs[REG_EIP] - 0x200; TypePos < (uint8_t *)ucontext->uc_mcontext.gregs[REG_EIP] + 0x30; TypePos += 8)
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "%X: %02X %02X %02X %02X %02X %02X %02X %02X", (uint32_t)TypePos, TypePos[0], TypePos[1], TypePos[2], TypePos[3], TypePos[4], TypePos[5], TypePos[6], TypePos[7]);
|
|
||||||
}
|
|
||||||
|
|
||||||
X86_CONTEXT context;
|
|
||||||
context.Edi = (uint32_t *)&ucontext->uc_mcontext.gregs[REG_EDI];
|
|
||||||
context.Esi = (uint32_t *)&ucontext->uc_mcontext.gregs[REG_ESI];
|
|
||||||
context.Ebx = (uint32_t *)&ucontext->uc_mcontext.gregs[REG_EBX];
|
|
||||||
context.Edx = (uint32_t *)&ucontext->uc_mcontext.gregs[REG_EDX];
|
|
||||||
context.Ecx = (uint32_t *)&ucontext->uc_mcontext.gregs[REG_ECX];
|
|
||||||
context.Eax = (uint32_t *)&ucontext->uc_mcontext.gregs[REG_EAX];
|
|
||||||
context.Eip = (uint32_t *)&ucontext->uc_mcontext.gregs[REG_EIP];
|
|
||||||
context.Esp = (uint32_t *)&ucontext->uc_mcontext.gregs[REG_ESP];
|
|
||||||
context.Ebp = (uint32_t *)&ucontext->uc_mcontext.gregs[REG_EBP];
|
|
||||||
|
|
||||||
if (FilterX86Exception(MemAddress, context))
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "Success!");
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "REG_EIP = %X", ucontext->uc_mcontext.gregs[REG_EIP]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#elif defined(__arm__)
|
|
||||||
if (FilterArmException(MemAddress, ucontext->uc_mcontext))
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "Success!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceError, "Failed! Quitting now...");
|
|
||||||
exit(0); // Can't return to main, this is where the segmentation fault occurred
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
int32_t CMipsMemoryVM::MemoryFilter(uint32_t dwExptCode, void * lpExceptionPointer)
|
|
||||||
{
|
|
||||||
#if defined(_M_IX86) && defined(_WIN32)
|
|
||||||
if (dwExptCode != EXCEPTION_ACCESS_VIOLATION || g_MMU == nullptr)
|
|
||||||
{
|
|
||||||
if (HaveDebugger())
|
|
||||||
{
|
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the pointer since we are not having win32 structures in headers
|
|
||||||
LPEXCEPTION_POINTERS lpEP = (LPEXCEPTION_POINTERS)lpExceptionPointer;
|
|
||||||
uint32_t MemAddress = (char *)lpEP->ExceptionRecord->ExceptionInformation[1] - (char *)g_MMU->Rdram();
|
|
||||||
|
|
||||||
X86_CONTEXT context;
|
|
||||||
context.Edi = (uint32_t *)&lpEP->ContextRecord->Edi;
|
|
||||||
context.Esi = (uint32_t *)&lpEP->ContextRecord->Esi;
|
|
||||||
context.Ebx = (uint32_t *)&lpEP->ContextRecord->Ebx;
|
|
||||||
context.Edx = (uint32_t *)&lpEP->ContextRecord->Edx;
|
|
||||||
context.Ecx = (uint32_t *)&lpEP->ContextRecord->Ecx;
|
|
||||||
context.Eax = (uint32_t *)&lpEP->ContextRecord->Eax;
|
|
||||||
context.Eip = (uint32_t *)&lpEP->ContextRecord->Eip;
|
|
||||||
context.Esp = (uint32_t *)&lpEP->ContextRecord->Esp;
|
|
||||||
context.Ebp = (uint32_t *)&lpEP->ContextRecord->Ebp;
|
|
||||||
|
|
||||||
if (FilterX86Exception(MemAddress, context))
|
|
||||||
{
|
|
||||||
WriteTrace(TraceExceptionHandler, TraceNotice, "Success!");
|
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
|
||||||
}
|
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
|
||||||
#else
|
|
||||||
dwExptCode = dwExptCode; //unreferenced formal parameter
|
|
||||||
lpExceptionPointer = lpExceptionPointer; // unreferenced formal parameter
|
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -9,8 +9,6 @@
|
||||||
#include <Project64-core\N64System\SystemGlobals.h>
|
#include <Project64-core\N64System\SystemGlobals.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
uint8_t * CMipsMemoryVM::m_Reserve1 = nullptr;
|
|
||||||
uint8_t * CMipsMemoryVM::m_Reserve2 = nullptr;
|
|
||||||
uint32_t CMipsMemoryVM::RegModValue;
|
uint32_t CMipsMemoryVM::RegModValue;
|
||||||
|
|
||||||
#pragma warning(disable : 4355) // Disable 'this' : used in base member initializer list
|
#pragma warning(disable : 4355) // Disable 'this' : used in base member initializer list
|
||||||
|
@ -109,54 +107,16 @@ void CMipsMemoryVM::Reset(bool /*EraseMemory*/)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMipsMemoryVM::ReserveMemory()
|
bool CMipsMemoryVM::Initialize(void)
|
||||||
{
|
|
||||||
#if defined(__i386__) || defined(_M_IX86)
|
|
||||||
m_Reserve1 = (uint8_t *)AllocateAddressSpace(0x20000000, (void *)g_Settings->LoadDword(Setting_FixedRdramAddress));
|
|
||||||
#else
|
|
||||||
m_Reserve1 = (uint8_t *)AllocateAddressSpace(0x20000000);
|
|
||||||
#endif
|
|
||||||
m_Reserve2 = (uint8_t *)AllocateAddressSpace(0x04002000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMipsMemoryVM::FreeReservedMemory()
|
|
||||||
{
|
|
||||||
if (m_Reserve1)
|
|
||||||
{
|
|
||||||
FreeAddressSpace(m_Reserve1, 0x20000000);
|
|
||||||
m_Reserve1 = nullptr;
|
|
||||||
}
|
|
||||||
if (m_Reserve2)
|
|
||||||
{
|
|
||||||
FreeAddressSpace(m_Reserve2, 0x20000000);
|
|
||||||
m_Reserve2 = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMipsMemoryVM::Initialize(bool SyncSystem)
|
|
||||||
{
|
{
|
||||||
if (m_RDRAM != nullptr)
|
if (m_RDRAM != nullptr)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
m_RDRAM = (uint8_t *)AllocateAddressSpace(0x02000000, (void *)g_Settings->LoadDword(Setting_FixedRdramAddress));
|
||||||
if (!SyncSystem && m_RDRAM == nullptr && m_Reserve1 != nullptr)
|
|
||||||
{
|
|
||||||
m_RDRAM = m_Reserve1;
|
|
||||||
m_Reserve1 = nullptr;
|
|
||||||
}
|
|
||||||
if (SyncSystem && m_RDRAM == nullptr && m_Reserve2 != nullptr)
|
|
||||||
{
|
|
||||||
m_RDRAM = m_Reserve2;
|
|
||||||
m_Reserve2 = nullptr;
|
|
||||||
}
|
|
||||||
if (m_RDRAM == nullptr)
|
if (m_RDRAM == nullptr)
|
||||||
{
|
{
|
||||||
m_RDRAM = (uint8_t *)AllocateAddressSpace(0x20000000);
|
WriteTrace(TraceN64System, TraceError, "Failed to reserve RDRAM (Size: 0x%X)", 0x02000000);
|
||||||
}
|
|
||||||
if (m_RDRAM == nullptr)
|
|
||||||
{
|
|
||||||
WriteTrace(TraceN64System, TraceError, "Failed to reserve RDRAM (Size: 0x%X)", 0x20000000);
|
|
||||||
FreeMemory();
|
FreeMemory();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -212,25 +172,8 @@ void CMipsMemoryVM::FreeMemory()
|
||||||
{
|
{
|
||||||
if (m_RDRAM)
|
if (m_RDRAM)
|
||||||
{
|
{
|
||||||
if (DecommitMemory(m_RDRAM, 0x20000000))
|
DecommitMemory(m_RDRAM, 0x02000000);
|
||||||
{
|
FreeAddressSpace(m_RDRAM, 0x02000000);
|
||||||
if (m_Reserve1 == nullptr)
|
|
||||||
{
|
|
||||||
m_Reserve1 = m_RDRAM;
|
|
||||||
}
|
|
||||||
else if (m_Reserve2 == nullptr)
|
|
||||||
{
|
|
||||||
m_Reserve2 = m_RDRAM;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FreeAddressSpace(m_RDRAM, 0x20000000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FreeAddressSpace(m_RDRAM, 0x20000000);
|
|
||||||
}
|
|
||||||
m_RDRAM = nullptr;
|
m_RDRAM = nullptr;
|
||||||
}
|
}
|
||||||
if (m_TLB_ReadMap)
|
if (m_TLB_ReadMap)
|
||||||
|
|
|
@ -55,10 +55,7 @@ public:
|
||||||
CMipsMemoryVM(CN64System & System, bool SavesReadOnly);
|
CMipsMemoryVM(CN64System & System, bool SavesReadOnly);
|
||||||
~CMipsMemoryVM();
|
~CMipsMemoryVM();
|
||||||
|
|
||||||
static void ReserveMemory();
|
bool Initialize(void);
|
||||||
static void FreeReservedMemory();
|
|
||||||
|
|
||||||
bool Initialize(bool SyncSystem);
|
|
||||||
void Reset(bool EraseMemory);
|
void Reset(bool EraseMemory);
|
||||||
|
|
||||||
uint8_t *& Rdram()
|
uint8_t *& Rdram()
|
||||||
|
@ -110,11 +107,6 @@ public:
|
||||||
|
|
||||||
int32_t MemoryFilter(uint32_t dwExptCode, void * lpExceptionPointer);
|
int32_t MemoryFilter(uint32_t dwExptCode, void * lpExceptionPointer);
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
static bool SetupSegvHandler(void);
|
|
||||||
static void segv_handler(int signal, siginfo_t * siginfo, void * sigcontext);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ClearMemoryWriteMap(uint32_t VAddr, uint32_t Length);
|
void ClearMemoryWriteMap(uint32_t VAddr, uint32_t Length);
|
||||||
|
|
||||||
// Functions for TLB notification
|
// Functions for TLB notification
|
||||||
|
@ -205,7 +197,6 @@ private:
|
||||||
#endif
|
#endif
|
||||||
void FreeMemory();
|
void FreeMemory();
|
||||||
|
|
||||||
static uint8_t *m_Reserve1, *m_Reserve2;
|
|
||||||
CN64System & m_System;
|
CN64System & m_System;
|
||||||
CRegisters & m_Reg;
|
CRegisters & m_Reg;
|
||||||
CTLB & m_TLB;
|
CTLB & m_TLB;
|
||||||
|
|
|
@ -61,7 +61,7 @@ CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesR
|
||||||
}
|
}
|
||||||
m_Limiter.SetHertz(gameHertz);
|
m_Limiter.SetHertz(gameHertz);
|
||||||
g_Settings->SaveDword(GameRunning_ScreenHertz, gameHertz);
|
g_Settings->SaveDword(GameRunning_ScreenHertz, gameHertz);
|
||||||
if (!m_MMU_VM.Initialize(SyncSystem))
|
if (!m_MMU_VM.Initialize())
|
||||||
{
|
{
|
||||||
WriteTrace(TraceN64System, TraceWarning, "MMU failed to initialize");
|
WriteTrace(TraceN64System, TraceWarning, "MMU failed to initialize");
|
||||||
WriteTrace(TraceN64System, TraceDebug, "Done");
|
WriteTrace(TraceN64System, TraceDebug, "Done");
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="AppInit.cpp" />
|
<ClCompile Include="AppInit.cpp" />
|
||||||
<ClCompile Include="Logging.cpp" />
|
<ClCompile Include="Logging.cpp" />
|
||||||
<ClCompile Include="MemoryExceptionFilter.cpp" />
|
|
||||||
<ClCompile Include="Multilanguage\Language.cpp" />
|
<ClCompile Include="Multilanguage\Language.cpp" />
|
||||||
<ClCompile Include="N64System\EmulationThread.cpp" />
|
<ClCompile Include="N64System\EmulationThread.cpp" />
|
||||||
<ClCompile Include="N64System\Enhancement\Enhancement.cpp" />
|
<ClCompile Include="N64System\Enhancement\Enhancement.cpp" />
|
||||||
|
|
|
@ -309,9 +309,6 @@
|
||||||
<ClCompile Include="N64System\Recompiler\x86\x86RegInfo.cpp">
|
<ClCompile Include="N64System\Recompiler\x86\x86RegInfo.cpp">
|
||||||
<Filter>Source Files\N64 System\Recompiler\x86</Filter>
|
<Filter>Source Files\N64 System\Recompiler\x86</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="MemoryExceptionFilter.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="N64System\Recompiler\RegBase.cpp">
|
<ClCompile Include="N64System\Recompiler\RegBase.cpp">
|
||||||
<Filter>Source Files\N64 System\Recompiler</Filter>
|
<Filter>Source Files\N64 System\Recompiler</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -373,7 +373,6 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory)
|
||||||
AddHandler(Debugger_TraceTLB, new CSettingTypeApplication("Logging", "TLB", (uint32_t)g_ModuleLogLevel[TraceTLB]));
|
AddHandler(Debugger_TraceTLB, new CSettingTypeApplication("Logging", "TLB", (uint32_t)g_ModuleLogLevel[TraceTLB]));
|
||||||
AddHandler(Debugger_TraceUserInterface, new CSettingTypeApplication("Logging", "User Interface", (uint32_t)g_ModuleLogLevel[TraceUserInterface]));
|
AddHandler(Debugger_TraceUserInterface, new CSettingTypeApplication("Logging", "User Interface", (uint32_t)g_ModuleLogLevel[TraceUserInterface]));
|
||||||
AddHandler(Debugger_TraceRomList, new CSettingTypeApplication("Logging", "Rom List", (uint32_t)g_ModuleLogLevel[TraceRomList]));
|
AddHandler(Debugger_TraceRomList, new CSettingTypeApplication("Logging", "Rom List", (uint32_t)g_ModuleLogLevel[TraceRomList]));
|
||||||
AddHandler(Debugger_TraceExceptionHandler, new CSettingTypeApplication("Logging", "Exception Handler", (uint32_t)g_ModuleLogLevel[TraceExceptionHandler]));
|
|
||||||
|
|
||||||
// Plugin
|
// Plugin
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -290,7 +290,6 @@ enum SettingID
|
||||||
Debugger_TraceTLB,
|
Debugger_TraceTLB,
|
||||||
Debugger_TraceUserInterface,
|
Debugger_TraceUserInterface,
|
||||||
Debugger_TraceRomList,
|
Debugger_TraceRomList,
|
||||||
Debugger_TraceExceptionHandler,
|
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
Plugin_RSP_Current,
|
Plugin_RSP_Current,
|
||||||
|
|
|
@ -20,6 +20,5 @@ enum TraceModuleProject64
|
||||||
TraceTLB,
|
TraceTLB,
|
||||||
TraceUserInterface,
|
TraceUserInterface,
|
||||||
TraceRomList,
|
TraceRomList,
|
||||||
TraceExceptionHandler,
|
|
||||||
MaxTraceModuleProject64,
|
MaxTraceModuleProject64,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue