2010-06-04 06:25:07 +00:00
|
|
|
#include "stdafx.h"
|
2008-09-18 03:15:49 +00:00
|
|
|
|
2010-05-25 09:15:19 +00:00
|
|
|
CFunctionMap::CFunctionMap() :
|
2010-06-07 02:23:58 +00:00
|
|
|
m_FunctionTable(NULL),
|
|
|
|
m_DelaySlotTable(NULL)
|
2010-05-25 09:15:19 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
CFunctionMap::~CFunctionMap()
|
|
|
|
{
|
2010-06-12 02:02:06 +00:00
|
|
|
CleanBuffers();
|
2010-05-25 09:15:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CFunctionMap::AllocateMemory()
|
|
|
|
{
|
2010-06-04 06:25:07 +00:00
|
|
|
if (m_FunctionTable == NULL)
|
|
|
|
{
|
|
|
|
m_FunctionTable = (PCCompiledFunc_TABLE *)VirtualAlloc(NULL,0xFFFFF * sizeof(CCompiledFunc *),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
|
|
|
|
if (m_FunctionTable == NULL) {
|
2010-06-22 20:36:28 +00:00
|
|
|
WriteTrace(TraceError,"CFunctionMap::AllocateMemory: failed to allocate function table");
|
2010-06-04 06:25:07 +00:00
|
|
|
_Notify->FatalError(MSG_MEM_ALLOC_ERROR);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
memset(m_FunctionTable,0,0xFFFFF * sizeof(CCompiledFunc *));
|
2010-05-25 09:15:19 +00:00
|
|
|
}
|
2010-06-07 02:23:58 +00:00
|
|
|
if (m_DelaySlotTable == NULL)
|
|
|
|
{
|
|
|
|
m_DelaySlotTable = (BYTE **)VirtualAlloc(NULL,0xFFFFF * sizeof(BYTE *),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
|
|
|
|
if (m_DelaySlotTable == NULL) {
|
2010-06-22 20:36:28 +00:00
|
|
|
WriteTrace(TraceError,"CFunctionMap::AllocateMemory: failed to allocate delay slot table");
|
2010-06-07 02:23:58 +00:00
|
|
|
_Notify->FatalError(MSG_MEM_ALLOC_ERROR);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
memset(m_DelaySlotTable,0,0xFFFFF * sizeof(BYTE *));
|
|
|
|
}
|
2010-05-25 09:15:19 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-06-12 02:02:06 +00:00
|
|
|
void CFunctionMap::CleanBuffers ( void )
|
|
|
|
{
|
|
|
|
if (m_FunctionTable)
|
|
|
|
{
|
|
|
|
for (int i = 0, n = 0x100000; i < n; i++)
|
|
|
|
{
|
|
|
|
if (m_FunctionTable[i] != NULL)
|
|
|
|
{
|
|
|
|
delete m_FunctionTable[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VirtualFree( m_FunctionTable, 0 , MEM_RELEASE);
|
|
|
|
m_FunctionTable = NULL;
|
|
|
|
}
|
|
|
|
if (m_DelaySlotTable)
|
|
|
|
{
|
|
|
|
VirtualFree( m_DelaySlotTable, 0 , MEM_RELEASE);
|
|
|
|
m_DelaySlotTable = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFunctionMap::Reset ( void )
|
|
|
|
{
|
|
|
|
bool bAllocate = m_FunctionTable != NULL;
|
|
|
|
CleanBuffers();
|
|
|
|
if (bAllocate)
|
|
|
|
{
|
|
|
|
AllocateMemory();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2010-06-04 06:25:07 +00:00
|
|
|
/*
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
CFunctionMap::~CFunctionMap()
|
|
|
|
{
|
|
|
|
Reset(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void * CFunctionMap::CompilerFindFunction( CFunctionMap * _this, DWORD vAddr )
|
|
|
|
{
|
|
|
|
return _this->FindFunction(vAddr);
|
|
|
|
}
|
|
|
|
|
2010-05-25 09:15:19 +00:00
|
|
|
CCompiledFunc * CFunctionMap::FindFunction( DWORD vAddr, int Length )
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
DWORD SectionEnd = (vAddr + Length + 0xFFF) >> 0xC;
|
|
|
|
for (DWORD Section = (vAddr >> 0x0C); Section < SectionEnd; Section++)
|
|
|
|
{
|
2010-05-25 09:15:19 +00:00
|
|
|
CCompiledFunc table = m_FunctionTable[Section];
|
2008-09-18 03:15:49 +00:00
|
|
|
if (table == NULL)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD Start = 0;
|
|
|
|
/*if (Section == (vAddr >> 0x0C))
|
|
|
|
{
|
|
|
|
Start = ((vAddr & 0xFFF) >> 2);
|
|
|
|
}*/
|
2010-05-25 09:15:19 +00:00
|
|
|
/*int SearchEnd = (Length - ((Section - (vAddr >> 0x0C)) * (0x1000 >> 2))) >> 2;
|
2008-09-18 03:15:49 +00:00
|
|
|
if (Start + SearchEnd > (0x1000 >> 2))
|
|
|
|
{
|
|
|
|
SearchEnd = (0x1000 >> 2);
|
|
|
|
}
|
|
|
|
for (int i = Start; i < SearchEnd; i++)
|
|
|
|
{
|
2010-05-25 09:15:19 +00:00
|
|
|
PCCompiledFunc & info = table[i];
|
2008-09-18 03:15:49 +00:00
|
|
|
if (info)
|
|
|
|
{
|
|
|
|
if (info->VEndPC() < vAddr)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFunctionMap::Reset( bool AllocateMemory )
|
|
|
|
{
|
|
|
|
if (m_FunctionTable)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < 0xFFFFF; i ++)
|
|
|
|
{
|
|
|
|
if (m_FunctionTable[i] == NULL)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2010-05-25 09:15:19 +00:00
|
|
|
CCompiledFunc table = m_FunctionTable[i];
|
2008-09-18 03:15:49 +00:00
|
|
|
for (int x = 0; x < (0x1000) >> 2; x++)
|
|
|
|
{
|
2010-05-25 09:15:19 +00:00
|
|
|
PCCompiledFunc info = table[x];
|
2008-09-18 03:15:49 +00:00
|
|
|
if (info == NULL)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
while (info->Next)
|
|
|
|
{
|
2010-05-25 09:15:19 +00:00
|
|
|
PCCompiledFunc todelete = info;
|
2008-09-18 03:15:49 +00:00
|
|
|
info = info->Next;
|
|
|
|
delete todelete;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete info;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete table;
|
|
|
|
}
|
|
|
|
if (!AllocateMemory)
|
|
|
|
{
|
|
|
|
VirtualFree(m_FunctionTable,0,MEM_RELEASE);
|
|
|
|
m_FunctionTable = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( AllocateMemory)
|
|
|
|
{
|
|
|
|
if (m_FunctionTable == NULL)
|
|
|
|
{
|
2010-05-25 09:15:19 +00:00
|
|
|
m_FunctionTable = (CCompiledFunc *)VirtualAlloc(NULL,0xFFFFF * sizeof(CCompiledFunc *),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
|
2008-09-18 03:15:49 +00:00
|
|
|
if (m_FunctionTable == NULL) {
|
2010-06-22 20:36:28 +00:00
|
|
|
_Notify->FatalError(MSG_MEM_ALLOC_ERROR);
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
memset(m_FunctionTable,0,0xFFFFF * sizeof(DWORD));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-25 09:15:19 +00:00
|
|
|
CCompiledFunc * CFunctionMap::AddFunctionInfo( DWORD vAddr, DWORD pAddr )
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2010-05-25 09:15:19 +00:00
|
|
|
CCompiledFunc & table = m_FunctionTable[vAddr >> 0xC];
|
2008-09-18 03:15:49 +00:00
|
|
|
if (table == NULL)
|
|
|
|
{
|
2010-05-25 09:15:19 +00:00
|
|
|
table = new PCCompiledFunc[(0x1000 >> 2)];
|
2008-09-18 03:15:49 +00:00
|
|
|
if (table == NULL)
|
|
|
|
{
|
2010-06-22 20:36:28 +00:00
|
|
|
_Notify->FatalError(MSG_MEM_ALLOC_ERROR);
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
2010-05-25 09:15:19 +00:00
|
|
|
memset(table,0,sizeof(PCCompiledFunc) * (0x1000 >> 2));
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
2010-05-25 09:15:19 +00:00
|
|
|
PCCompiledFunc & info = table[(vAddr & 0xFFF) >> 2];
|
2008-09-18 03:15:49 +00:00
|
|
|
if (info != NULL)
|
|
|
|
{
|
2010-05-25 09:15:19 +00:00
|
|
|
PCCompiledFunc old_info = info;
|
|
|
|
info = new CCompiledFunc(vAddr,pAddr);
|
2008-09-18 03:15:49 +00:00
|
|
|
info->Next = old_info;
|
|
|
|
} else {
|
2010-05-25 09:15:19 +00:00
|
|
|
info = new CCompiledFunc(vAddr,pAddr);
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
2010-05-25 09:15:19 +00:00
|
|
|
void CFunctionMap::Remove(CCompiledFunc * info)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
DWORD vAddr = info->VStartPC();
|
2010-05-25 09:15:19 +00:00
|
|
|
CCompiledFunc & table = m_FunctionTable[vAddr >> 0xC];
|
2008-09-18 03:15:49 +00:00
|
|
|
if (table == NULL)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-05-25 09:15:19 +00:00
|
|
|
PCCompiledFunc & current_info = table[(vAddr & 0xFFF) >> 2];
|
2008-09-18 03:15:49 +00:00
|
|
|
if (current_info == NULL)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (current_info == info)
|
|
|
|
{
|
|
|
|
delete info;
|
|
|
|
table[(vAddr & 0xFFF) >> 2] = NULL;
|
|
|
|
} else {
|
2010-06-22 20:36:28 +00:00
|
|
|
_Notify->BreakPoint(__FILE__,__LINE__);
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
}
|
2010-05-25 09:15:19 +00:00
|
|
|
*/
|