Re-added buffer check on lookup core

This commit is contained in:
zilmar 2012-09-25 08:07:51 +10:00
parent b372675796
commit 5344507496
9 changed files with 235 additions and 84 deletions

View File

@ -276,6 +276,13 @@ bool CMipsMemoryVM::ValidVaddr ( DWORD VAddr ) const
return m_TLB_ReadMap[VAddr >> 12] != 0;
}
bool CMipsMemoryVM::VAddrToRealAddr ( DWORD VAddr, void * &RealAddress ) const
{
if (m_TLB_ReadMap[VAddr >> 12] == 0) { return false; }
RealAddress = (BYTE *)(m_TLB_ReadMap[VAddr >> 12] + VAddr);
return true;
}
bool CMipsMemoryVM::TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const
{
//Change the Virtual address to a Phyiscal Address

View File

@ -105,6 +105,7 @@ public:
// CTransVaddr interface
bool TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const;
bool ValidVaddr ( DWORD VAddr ) const;
bool VAddrToRealAddr ( DWORD VAddr, void * &RealAddress ) const;
// Labels
LPCTSTR LabelName ( DWORD Address ) const;

View File

@ -1,6 +1,7 @@
class CTransVaddr
{
public:
virtual bool TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const = 0;
virtual bool ValidVaddr ( DWORD VAddr ) const = 0;
virtual bool TranslateVaddr ( DWORD VAddr, DWORD &PAddr) const = 0;
virtual bool ValidVaddr ( DWORD VAddr ) const = 0;
virtual bool VAddrToRealAddr ( DWORD VAddr, void * &RealAddress ) const = 0;
};

View File

@ -10,6 +10,15 @@ CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos, bool bDelaySlot) :
m_bDelaySlot(bDelaySlot),
m_Test(1)
{
if (_TransVaddr->VAddrToRealAddr(VAddrEnter,*(reinterpret_cast<void **>(&m_MemLocation[0]))))
{
m_MemLocation[1] = m_MemLocation[0] + 1;
m_MemContents[0] = *m_MemLocation[0];
m_MemContents[1] = *m_MemLocation[1];
} else {
memset(m_MemLocation,0,sizeof(m_MemLocation));
memset(m_MemContents,0,sizeof(m_MemContents));
}
AnalyseBlock();
}

View File

@ -23,6 +23,9 @@ public:
CCodeSection * ExistingSection ( DWORD Addr ) { return m_EnterSection.ExistingSection(Addr,NextTest()); }
bool SectionAccessible ( DWORD m_SectionID ) { return m_EnterSection.SectionAccessible(m_SectionID,NextTest()); }
inline QWORD MemContents(int i) const { return m_MemContents[i]; }
inline QWORD * MemLocation(int i) const { return m_MemLocation[i]; }
EXIT_LIST m_ExitInfo;
DWORD NextTest ( void );
@ -39,4 +42,6 @@ private:
CCodeSection m_EnterSection;
DWORD m_Test;
MD5Digest m_Hash;
QWORD m_MemContents[2];
QWORD * m_MemLocation[2];
};

View File

@ -8,5 +8,9 @@ CCompiledFunc::CCompiledFunc( const CCodeBlock & CodeBlock ) :
m_Hash(CodeBlock.Hash()),
m_Next(NULL)
{
m_MemContents[0] = CodeBlock.MemContents(0);
m_MemContents[1] = CodeBlock.MemContents(1);
m_MemLocation[0] = CodeBlock.MemLocation(0);
m_MemLocation[1] = CodeBlock.MemLocation(1);
}

View File

@ -17,6 +17,10 @@ public:
inline CCompiledFunc * Next ( void ) const { return m_Next; }
inline void SetNext ( CCompiledFunc * Next ) { m_Next = Next; }
inline QWORD MemContents(int i) { return m_MemContents[i]; }
inline QWORD * MemLocation(int i) { return m_MemLocation[i]; }
private:
//Information
DWORD m_EnterPC; // The Entry PC
@ -30,7 +34,7 @@ private:
CCompiledFunc * m_Next;
//Validation
//QWORD MemContents[2], * MemLocation[2];
QWORD m_MemContents[2], * m_MemLocation[2];
};
typedef std::map<DWORD, CCompiledFunc *> CCompiledFuncList;

View File

@ -52,7 +52,23 @@ void CRecompiler::Run()
}
else
{
RecompilerMain_Lookup();
CInterpreterCPU::BuildCPU();
if (bUseTlb())
{
if (bSMM_ValidFunc())
{
RecompilerMain_Lookup_validate_TLB();
} else {
RecompilerMain_Lookup_TLB();
}
} else {
if (bSMM_ValidFunc())
{
RecompilerMain_Lookup_validate();
} else {
RecompilerMain_Lookup();
}
}
}
}
__except( _MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) )
@ -293,92 +309,39 @@ void CRecompiler::RecompilerMain_VirtualTable_validate ( void )
void CRecompiler::RecompilerMain_Lookup( void )
{
DWORD PhysicalAddr;
CInterpreterCPU::BuildCPU();
if (bUseTlb())
while(!m_EndEmulation)
{
while(!m_EndEmulation)
DWORD PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF;
if (PhysicalAddr < RdramSize())
{
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{
_Reg->DoTLBMiss(false,PROGRAM_COUNTER);
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER);
m_EndEmulation = true;
break;
}
continue;
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
}
if (PhysicalAddr < RdramSize())
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
}
} else {
while(!m_EndEmulation)
{
PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF;
if (PhysicalAddr < RdramSize())
if (_SyncSystem)
{
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
}
}
@ -534,6 +497,161 @@ void CRecompiler::RecompilerMain_Lookup( void )
}*/
}
void CRecompiler::RecompilerMain_Lookup_TLB( void )
{
DWORD PhysicalAddr;
while(!m_EndEmulation)
{
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
{
_Reg->DoTLBMiss(false,PROGRAM_COUNTER);
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
{
DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER);
m_EndEmulation = true;
}
continue;
}
if (PhysicalAddr < RdramSize())
{
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
}
}
}
void CRecompiler::RecompilerMain_Lookup_validate( void )
{
while(!m_EndEmulation)
{
DWORD PhysicalAddr = PROGRAM_COUNTER & 0x1FFFFFFF;
if (PhysicalAddr < RdramSize())
{
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
} else {
if (*(info->MemLocation(0)) != info->MemContents(0) ||
*(info->MemLocation(1)) != info->MemContents(1))
{
ClearRecompCode_Virt((info->EnterPC() - 0x1000) & ~0xFFF,0x3000,Remove_ValidateFunc);
info = NULL;
continue;
}
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
}
}
}
void CRecompiler::RecompilerMain_Lookup_validate_TLB( void )
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
DWORD PhysicalAddr;
while(!m_EndEmulation)
{
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
{
_Reg->DoTLBMiss(false,PROGRAM_COUNTER);
if (!_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr))
{
DisplayError("Failed to translate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER);
m_EndEmulation = true;
}
continue;
}
if (PhysicalAddr < RdramSize())
{
CCompiledFunc * info = JumpTable()[PhysicalAddr >> 2];
if (info == NULL)
{
info = CompilerCode();
if (info == NULL || m_EndEmulation)
{
break;
}
if (bSMM_Protect())
{
_MMU->ProtectMemory(PROGRAM_COUNTER & ~0xFFF,PROGRAM_COUNTER | 0xFFF);
}
JumpTable()[PhysicalAddr >> 2] = info;
}
(info->Function())();
} else {
DWORD opsExecuted = 0;
while (_TransVaddr->TranslateVaddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= RdramSize())
{
CInterpreterCPU::ExecuteOps(CountPerOp());
opsExecuted += CountPerOp();
}
if (_SyncSystem)
{
_System->UpdateSyncCPU(_SyncSystem,opsExecuted);
_System->SyncCPU(_SyncSystem);
}
}
}
#endif
}
void CRecompiler::Reset()
{
ResetRecompCode();

View File

@ -57,9 +57,11 @@ private:
// Main loops for the different look up methods
void RecompilerMain_VirtualTable ( void );
void RecompilerMain_VirtualTable_validate ( void );
void RecompilerMain_ChangeMemory ( void );
void RecompilerMain_Lookup ( void );
void RecompilerMain_Lookup_TLB ( void );
void RecompilerMain_ChangeMemory ( void );
void RecompilerMain_Lookup ( void );
void RecompilerMain_Lookup_TLB ( void );
void RecompilerMain_Lookup_validate ( void );
void RecompilerMain_Lookup_validate_TLB ( void );
void RemoveFunction (CCompiledFunc * FunInfo, bool DelaySlot, REMOVE_REASON Reason );
};