Hash the HLECache table

Workaround for #836
This commit is contained in:
x1nixmzeng 2018-01-09 22:24:41 +00:00
parent dd1fb45520
commit da677b1f18
3 changed files with 92 additions and 15 deletions

View File

@ -41,8 +41,6 @@
#include "CxbxKrnl.h" // For xbaddr
#include "HLEDataBase.h" // For PairScanLibSec
extern "C" const char *szHLELastCompileTime = __TIMESTAMP__;
const char *Lib_D3D8 = "D3D8";
const char *Sec_D3D = "D3D";
const char *Lib_D3D8LTCG = "D3D8LTCG";
@ -135,6 +133,80 @@ const HLEData HLEDataBase[] = {
// ******************************************************************
const uint32 HLEDataBaseCount = sizeof(HLEDataBase) / sizeof(HLEDataBase[0]);
// ******************************************************************
// * GetHLEDataBaseHash
// ******************************************************************
// TODO Write a constexpr variation on these methods
namespace HashHelpers
{
namespace Internal
{
// Adapted from https://gist.github.com/underscorediscovery/81308642d0325fd386237cfa3b44785c
const uint32 fnv1aprime = 0x1000193;
void hash_fnv1a(uint32& hash, const void* key, const uint32 len)
{
const char* data = (char*)key;
for (uint32 i = 0; i < len; ++i) {
uint8_t value = data[i];
hash ^= value;
hash *= fnv1aprime;
}
}
void HashAssumedLOOVPA(uint32& Hash, const OOVPA* pAssumedLOOVPA)
{
// Number of offset-value pairs in the "Header" LOOVPA structure
uint32 Size = pAssumedLOOVPA->Count * sizeof(OOVPA::LOVP);
// Size of "Header" structure
Size += sizeof(OOVPA);
// Part 1: The array of OOVPA::LOVP items
hash_fnv1a(Hash, pAssumedLOOVPA, Size);
}
void HashOOVPATable(uint32& Hash, const OOVPATable* pTable)
{
// Part 1: function name string
if (pTable->szFuncName != nullptr) {
hash_fnv1a(Hash, pTable->szFuncName, strlen(pTable->szFuncName));
}
// Part 2: version number
hash_fnv1a(Hash, &pTable->Version, sizeof(pTable->Version));
// Part 3: LOOVPA
if (pTable->Oovpa) {
HashAssumedLOOVPA(Hash, pTable->Oovpa);
}
}
void HashHLEData(uint32& Hash, const HLEData* pData)
{
for (uint32 i = 0; i < pData->OovpaTableCount; ++i) {
HashOOVPATable(Hash, &pData->OovpaTable[i]);
}
}
}
const uint32 HashHLEDataArray(const HLEData* pDataArray, uint32 Count)
{
uint32 Hash = 0x811c9dc5;
for (uint32 i = 0; i < Count; ++i) {
Internal::HashHLEData(Hash, pDataArray + i);
}
return Hash;
}
}
uint32 GetHLEDataBaseHash()
{
// Calculate this just once
static uint32 CalculatedHash = HashHelpers::HashHLEDataArray(HLEDataBase, HLEDataBaseCount);
return CalculatedHash;
}
// ******************************************************************
// * XRefDataBase
// ******************************************************************

View File

@ -36,11 +36,6 @@
#include "HLEDataBase\D3D8.OOVPA.h"
// ******************************************************************
// * szHLELastCompileTime
// ******************************************************************
extern "C" const char *szHLELastCompileTime;
//TODO: Need to remove these externs as v2 is no longer require it.
extern const char *Lib_D3D8;
extern const char *Lib_D3D8LTCG;
@ -78,6 +73,11 @@ HLEDataBase[];
// ******************************************************************
extern const uint32 HLEDataBaseCount;
// ******************************************************************
// * GetHLEDataBaseHash
// ******************************************************************
extern uint32 GetHLEDataBaseHash();
// ******************************************************************
// * XRefDataBaseOffset
// ******************************************************************

View File

@ -165,7 +165,7 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
printf("\n");
printf("*******************************************************************************\n");
printf("* Cxbx-Reloaded High Level Emulation database last modified %s\n", szHLELastCompileTime);
printf("* Cxbx-Reloaded High Level Emulation database\n");
printf("*******************************************************************************\n");
printf("\n");
@ -190,15 +190,17 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
if (PathFileExists(filename.c_str())) {
printf("Found HLE Cache File: %08X.ini\n", uiHash);
// Verify the version of the cache file against the HLE Database
char buffer[SHRT_MAX] = { 0 };
char* bufferPtr = buffer;
GetPrivateProfileString("Info", "HLEDatabaseVersion", NULL, buffer, sizeof(buffer), filename.c_str());
g_BuildVersion = GetPrivateProfileInt("Libs", "D3D8_BuildVersion", 0, filename.c_str());
if (strcmp(buffer, szHLELastCompileTime) == 0) {
// Verify the version of the cache file against the HLE Database
const uint32 HLECacheHash = GetPrivateProfileInt("Info", "HLECacheHash", 0, filename.c_str());
if (HLECacheHash == GetHLEDataBaseHash()) {
char buffer[SHRT_MAX] = { 0 };
char* bufferPtr = buffer;
printf("Using HLE Cache\n");
GetPrivateProfileSection("Symbols", buffer, sizeof(buffer), filename.c_str());
// Parse the .INI file into the map of symbol addresses
@ -624,7 +626,10 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
printf("\n");
// Write the HLE Database version string
WritePrivateProfileString("Info", "HLEDatabaseVersion", szHLELastCompileTime, filename.c_str());
{
std::string HLECacheHashString = std::to_string(GetHLEDataBaseHash());
WritePrivateProfileString("Info", "HLECacheHash", HLECacheHashString.c_str(), filename.c_str());
}
// Write the Certificate Details to the cache file
WritePrivateProfileString("Certificate", "Name", tAsciiTitle, filename.c_str());