Merge pull request #4497 from sepalani/totaldb.csv
Import/Export signature files as CSV
This commit is contained in:
commit
4e405010a3
|
@ -373,6 +373,16 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StringBeginsWith(const std::string& str, const std::string& begin)
|
||||||
|
{
|
||||||
|
return str.size() >= begin.size() && std::equal(begin.begin(), begin.end(), str.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringEndsWith(const std::string& str, const std::string& end)
|
||||||
|
{
|
||||||
|
return str.size() >= end.size() && std::equal(end.rbegin(), end.rend(), str.rbegin());
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
std::string UTF16ToUTF8(const std::wstring& input)
|
std::string UTF16ToUTF8(const std::wstring& input)
|
||||||
|
|
|
@ -116,6 +116,9 @@ void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _P
|
||||||
const std::string& _Filename);
|
const std::string& _Filename);
|
||||||
std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest);
|
std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest);
|
||||||
|
|
||||||
|
bool StringBeginsWith(const std::string& str, const std::string& begin);
|
||||||
|
bool StringEndsWith(const std::string& str, const std::string& end);
|
||||||
|
|
||||||
std::string CP1252ToUTF8(const std::string& str);
|
std::string CP1252ToUTF8(const std::string& str);
|
||||||
std::string SHIFTJISToUTF8(const std::string& str);
|
std::string SHIFTJISToUTF8(const std::string& str);
|
||||||
std::string UTF16ToUTF8(const std::wstring& str);
|
std::string UTF16ToUTF8(const std::wstring& str);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "Core/PowerPC/PPCAnalyst.h"
|
#include "Core/PowerPC/PPCAnalyst.h"
|
||||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/PowerPC/SignatureDB.h"
|
#include "Core/PowerPC/SignatureDB/SignatureDB.h"
|
||||||
|
|
||||||
#include "DiscIO/Enums.h"
|
#include "DiscIO/Enums.h"
|
||||||
#include "DiscIO/NANDContentLoader.h"
|
#include "DiscIO/NANDContentLoader.h"
|
||||||
|
|
|
@ -163,7 +163,9 @@ set(SRCS ActionReplay.cpp
|
||||||
PowerPC/PPCSymbolDB.cpp
|
PowerPC/PPCSymbolDB.cpp
|
||||||
PowerPC/PPCTables.cpp
|
PowerPC/PPCTables.cpp
|
||||||
PowerPC/Profiler.cpp
|
PowerPC/Profiler.cpp
|
||||||
PowerPC/SignatureDB.cpp
|
PowerPC/SignatureDB/CSVSignatureDB.cpp
|
||||||
|
PowerPC/SignatureDB/DSYSignatureDB.cpp
|
||||||
|
PowerPC/SignatureDB/SignatureDB.cpp
|
||||||
PowerPC/JitInterface.cpp
|
PowerPC/JitInterface.cpp
|
||||||
PowerPC/Interpreter/Interpreter_Branch.cpp
|
PowerPC/Interpreter/Interpreter_Branch.cpp
|
||||||
PowerPC/Interpreter/Interpreter.cpp
|
PowerPC/Interpreter/Interpreter.cpp
|
||||||
|
|
|
@ -245,6 +245,9 @@
|
||||||
<ClCompile Include="PowerPC\JitCommon\JitAsmCommon.cpp" />
|
<ClCompile Include="PowerPC\JitCommon\JitAsmCommon.cpp" />
|
||||||
<ClCompile Include="PowerPC\JitCommon\JitBase.cpp" />
|
<ClCompile Include="PowerPC\JitCommon\JitBase.cpp" />
|
||||||
<ClCompile Include="PowerPC\JitCommon\JitCache.cpp" />
|
<ClCompile Include="PowerPC\JitCommon\JitCache.cpp" />
|
||||||
|
<ClCompile Include="PowerPC\SignatureDB\CSVSignatureDB.cpp" />
|
||||||
|
<ClCompile Include="PowerPC\SignatureDB\DSYSignatureDB.cpp" />
|
||||||
|
<ClCompile Include="PowerPC\SignatureDB\SignatureDB.cpp" />
|
||||||
<ClCompile Include="PowerPC\CachedInterpreter.cpp" />
|
<ClCompile Include="PowerPC\CachedInterpreter.cpp" />
|
||||||
<ClCompile Include="PowerPC\JitInterface.cpp" />
|
<ClCompile Include="PowerPC\JitInterface.cpp" />
|
||||||
<ClCompile Include="PowerPC\MMU.cpp" />
|
<ClCompile Include="PowerPC\MMU.cpp" />
|
||||||
|
@ -254,7 +257,6 @@
|
||||||
<ClCompile Include="PowerPC\PPCSymbolDB.cpp" />
|
<ClCompile Include="PowerPC\PPCSymbolDB.cpp" />
|
||||||
<ClCompile Include="PowerPC\PPCTables.cpp" />
|
<ClCompile Include="PowerPC\PPCTables.cpp" />
|
||||||
<ClCompile Include="PowerPC\Profiler.cpp" />
|
<ClCompile Include="PowerPC\Profiler.cpp" />
|
||||||
<ClCompile Include="PowerPC\SignatureDB.cpp" />
|
|
||||||
<ClCompile Include="State.cpp" />
|
<ClCompile Include="State.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -438,6 +440,9 @@
|
||||||
<ClInclude Include="PowerPC\JitCommon\JitAsmCommon.h" />
|
<ClInclude Include="PowerPC\JitCommon\JitAsmCommon.h" />
|
||||||
<ClInclude Include="PowerPC\JitCommon\JitBase.h" />
|
<ClInclude Include="PowerPC\JitCommon\JitBase.h" />
|
||||||
<ClInclude Include="PowerPC\JitCommon\JitCache.h" />
|
<ClInclude Include="PowerPC\JitCommon\JitCache.h" />
|
||||||
|
<ClInclude Include="PowerPC\SignatureDB\CSVSignatureDB.h" />
|
||||||
|
<ClInclude Include="PowerPC\SignatureDB\DSYSignatureDB.h" />
|
||||||
|
<ClInclude Include="PowerPC\SignatureDB\SignatureDB.h" />
|
||||||
<ClInclude Include="PowerPC\CachedInterpreter.h" />
|
<ClInclude Include="PowerPC\CachedInterpreter.h" />
|
||||||
<ClInclude Include="PowerPC\JitInterface.h" />
|
<ClInclude Include="PowerPC\JitInterface.h" />
|
||||||
<ClInclude Include="PowerPC\PowerPC.h" />
|
<ClInclude Include="PowerPC\PowerPC.h" />
|
||||||
|
@ -446,7 +451,6 @@
|
||||||
<ClInclude Include="PowerPC\PPCSymbolDB.h" />
|
<ClInclude Include="PowerPC\PPCSymbolDB.h" />
|
||||||
<ClInclude Include="PowerPC\PPCTables.h" />
|
<ClInclude Include="PowerPC\PPCTables.h" />
|
||||||
<ClInclude Include="PowerPC\Profiler.h" />
|
<ClInclude Include="PowerPC\Profiler.h" />
|
||||||
<ClInclude Include="PowerPC\SignatureDB.h" />
|
|
||||||
<ClInclude Include="State.h" />
|
<ClInclude Include="State.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -648,9 +648,6 @@
|
||||||
<ClCompile Include="PowerPC\Profiler.cpp">
|
<ClCompile Include="PowerPC\Profiler.cpp">
|
||||||
<Filter>PowerPC</Filter>
|
<Filter>PowerPC</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="PowerPC\SignatureDB.cpp">
|
|
||||||
<Filter>PowerPC</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="PowerPC\JitCommon\JitAsmCommon.cpp">
|
<ClCompile Include="PowerPC\JitCommon\JitAsmCommon.cpp">
|
||||||
<Filter>PowerPC\JitCommon</Filter>
|
<Filter>PowerPC\JitCommon</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -754,6 +751,15 @@
|
||||||
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb_ven.cpp">
|
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb_ven.cpp">
|
||||||
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="PowerPC\SignatureDB\CSVSignatureDB.cpp">
|
||||||
|
<Filter>PowerPC\SignatureDB</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="PowerPC\SignatureDB\DSYSignatureDB.cpp">
|
||||||
|
<Filter>PowerPC\SignatureDB</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="PowerPC\SignatureDB\SignatureDB.cpp">
|
||||||
|
<Filter>PowerPC\SignatureDB</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="BootManager.h" />
|
<ClInclude Include="BootManager.h" />
|
||||||
|
@ -1238,9 +1244,6 @@
|
||||||
<ClInclude Include="PowerPC\Profiler.h">
|
<ClInclude Include="PowerPC\Profiler.h">
|
||||||
<Filter>PowerPC</Filter>
|
<Filter>PowerPC</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="PowerPC\SignatureDB.h">
|
|
||||||
<Filter>PowerPC</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="PowerPC\JitCommon\JitAsmCommon.h">
|
<ClInclude Include="PowerPC\JitCommon\JitAsmCommon.h">
|
||||||
<Filter>PowerPC\JitCommon</Filter>
|
<Filter>PowerPC\JitCommon</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -1294,6 +1297,15 @@
|
||||||
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_ven.h">
|
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_ven.h">
|
||||||
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="PowerPC\SignatureDB\CSVSignatureDB.h">
|
||||||
|
<Filter>PowerPC\SignatureDB</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="PowerPC\SignatureDB\DSYSignatureDB.h">
|
||||||
|
<Filter>PowerPC\SignatureDB</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="PowerPC\SignatureDB\SignatureDB.h">
|
||||||
|
<Filter>PowerPC\SignatureDB</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="CMakeLists.txt" />
|
<Text Include="CMakeLists.txt" />
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/PowerPC/SignatureDB.h"
|
#include "Core/PowerPC/SignatureDB/SignatureDB.h"
|
||||||
|
|
||||||
// Analyzes PowerPC code in memory to find functions
|
// Analyzes PowerPC code in memory to find functions
|
||||||
// After running, for each function we will know what functions it calls
|
// After running, for each function we will know what functions it calls
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "Core/PowerPC/PPCAnalyst.h"
|
#include "Core/PowerPC/PPCAnalyst.h"
|
||||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/PowerPC/SignatureDB.h"
|
#include "Core/PowerPC/SignatureDB/SignatureDB.h"
|
||||||
|
|
||||||
static std::string GetStrippedFunctionName(const std::string& symbol_name)
|
static std::string GetStrippedFunctionName(const std::string& symbol_name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "Common/FileUtil.h"
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
|
|
||||||
|
#include "Core/PowerPC/SignatureDB/CSVSignatureDB.h"
|
||||||
|
|
||||||
|
// CSV separated with tabs
|
||||||
|
// Checksum | Size | Symbol | [Object Location |] Object Name
|
||||||
|
bool CSVSignatureDB::Load(const std::string& file_path, SignatureDB::FuncDB& database) const
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::ifstream ifs;
|
||||||
|
OpenFStream(ifs, file_path, std::ios_base::in);
|
||||||
|
|
||||||
|
if (!ifs)
|
||||||
|
return false;
|
||||||
|
for (size_t i = 1; std::getline(ifs, line); i += 1)
|
||||||
|
{
|
||||||
|
std::istringstream iss(line);
|
||||||
|
u32 checksum, size;
|
||||||
|
std::string tab, symbol, object_location, object_name;
|
||||||
|
|
||||||
|
iss >> std::hex >> checksum >> std::hex >> size;
|
||||||
|
if (iss && std::getline(iss, tab, '\t'))
|
||||||
|
{
|
||||||
|
if (std::getline(iss, symbol, '\t') && std::getline(iss, object_location, '\t'))
|
||||||
|
std::getline(iss, object_name);
|
||||||
|
SignatureDB::DBFunc func;
|
||||||
|
func.name = symbol;
|
||||||
|
func.size = size;
|
||||||
|
// Doesn't have an object location
|
||||||
|
if (object_name.empty())
|
||||||
|
{
|
||||||
|
func.object_name = object_location;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
func.object_location = object_location;
|
||||||
|
func.object_name = object_name;
|
||||||
|
}
|
||||||
|
database[checksum] = func;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN_LOG(OSHLE, "CSV database failed to parse line %zu", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVSignatureDB::Save(const std::string& file_path, const SignatureDB::FuncDB& database) const
|
||||||
|
{
|
||||||
|
File::IOFile f(file_path, "w");
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
ERROR_LOG(OSHLE, "CSV database save failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const auto& func : database)
|
||||||
|
{
|
||||||
|
// The object name/location are unused for the time being.
|
||||||
|
// To be implemented.
|
||||||
|
fprintf(f.GetHandle(), "%08x\t%08x\t%s\t%s\t%s\n", func.first, func.second.size,
|
||||||
|
func.second.name.c_str(), func.second.object_location.c_str(),
|
||||||
|
func.second.object_name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO_LOG(OSHLE, "CSV database save successful");
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Core/PowerPC/SignatureDB/SignatureDB.h"
|
||||||
|
|
||||||
|
class CSVSignatureDB final : public SignatureDBFormatHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~CSVSignatureDB() = default;
|
||||||
|
bool Load(const std::string& file_path, SignatureDB::FuncDB& database) const override;
|
||||||
|
bool Save(const std::string& file_path, const SignatureDB::FuncDB& database) const override;
|
||||||
|
};
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/FileUtil.h"
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
|
|
||||||
|
#include "Core/PowerPC/SignatureDB/DSYSignatureDB.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// On-disk format for SignatureDB entries.
|
||||||
|
struct FuncDesc
|
||||||
|
{
|
||||||
|
u32 checksum;
|
||||||
|
u32 size;
|
||||||
|
char name[128];
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool DSYSignatureDB::Load(const std::string& file_path, SignatureDB::FuncDB& database) const
|
||||||
|
{
|
||||||
|
File::IOFile f(file_path, "rb");
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
return false;
|
||||||
|
u32 fcount = 0;
|
||||||
|
f.ReadArray(&fcount, 1);
|
||||||
|
for (size_t i = 0; i < fcount; i++)
|
||||||
|
{
|
||||||
|
FuncDesc temp;
|
||||||
|
memset(&temp, 0, sizeof(temp));
|
||||||
|
|
||||||
|
f.ReadArray(&temp, 1);
|
||||||
|
temp.name[sizeof(temp.name) - 1] = 0;
|
||||||
|
|
||||||
|
SignatureDB::DBFunc func;
|
||||||
|
func.name = temp.name;
|
||||||
|
func.size = temp.size;
|
||||||
|
database[temp.checksum] = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DSYSignatureDB::Save(const std::string& file_path, const SignatureDB::FuncDB& database) const
|
||||||
|
{
|
||||||
|
File::IOFile f(file_path, "wb");
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
ERROR_LOG(OSHLE, "Database save failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
u32 fcount = static_cast<u32>(database.size());
|
||||||
|
f.WriteArray(&fcount, 1);
|
||||||
|
for (const auto& entry : database)
|
||||||
|
{
|
||||||
|
FuncDesc temp;
|
||||||
|
memset(&temp, 0, sizeof(temp));
|
||||||
|
temp.checksum = entry.first;
|
||||||
|
temp.size = entry.second.size;
|
||||||
|
strncpy(temp.name, entry.second.name.c_str(), 127);
|
||||||
|
f.WriteArray(&temp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO_LOG(OSHLE, "Database save successful");
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Core/PowerPC/SignatureDB/SignatureDB.h"
|
||||||
|
|
||||||
|
class DSYSignatureDB final : public SignatureDBFormatHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~DSYSignatureDB() = default;
|
||||||
|
bool Load(const std::string& file_path, SignatureDB::FuncDB& database) const override;
|
||||||
|
bool Save(const std::string& file_path, const SignatureDB::FuncDB& database) const override;
|
||||||
|
};
|
|
@ -7,69 +7,34 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
#include "Core/PowerPC/PPCAnalyst.h"
|
#include "Core/PowerPC/PPCAnalyst.h"
|
||||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/PowerPC/SignatureDB.h"
|
#include "Core/PowerPC/SignatureDB/SignatureDB.h"
|
||||||
|
|
||||||
namespace
|
// Format Handlers
|
||||||
|
#include "Core/PowerPC/SignatureDB/CSVSignatureDB.h"
|
||||||
|
#include "Core/PowerPC/SignatureDB/DSYSignatureDB.h"
|
||||||
|
|
||||||
|
std::unique_ptr<SignatureDBFormatHandler>
|
||||||
|
SignatureDB::CreateFormatHandler(const std::string& file_path)
|
||||||
{
|
{
|
||||||
// On-disk format for SignatureDB entries.
|
if (StringEndsWith(file_path, ".csv"))
|
||||||
struct FuncDesc
|
return std::make_unique<CSVSignatureDB>();
|
||||||
{
|
return std::make_unique<DSYSignatureDB>();
|
||||||
u32 checkSum;
|
|
||||||
u32 size;
|
|
||||||
char name[128];
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool SignatureDB::Load(const std::string& filename)
|
|
||||||
{
|
|
||||||
File::IOFile f(filename, "rb");
|
|
||||||
if (!f)
|
|
||||||
return false;
|
|
||||||
u32 fcount = 0;
|
|
||||||
f.ReadArray(&fcount, 1);
|
|
||||||
for (size_t i = 0; i < fcount; i++)
|
|
||||||
{
|
|
||||||
FuncDesc temp;
|
|
||||||
memset(&temp, 0, sizeof(temp));
|
|
||||||
|
|
||||||
f.ReadArray(&temp, 1);
|
|
||||||
temp.name[sizeof(temp.name) - 1] = 0;
|
|
||||||
|
|
||||||
DBFunc dbf;
|
|
||||||
dbf.name = temp.name;
|
|
||||||
dbf.size = temp.size;
|
|
||||||
database[temp.checkSum] = dbf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
bool SignatureDB::Load(const std::string& file_path)
|
||||||
|
{
|
||||||
|
auto handler = CreateFormatHandler(file_path);
|
||||||
|
return handler->Load(file_path, m_database);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SignatureDB::Save(const std::string& filename)
|
bool SignatureDB::Save(const std::string& file_path)
|
||||||
{
|
{
|
||||||
File::IOFile f(filename, "wb");
|
auto handler = CreateFormatHandler(file_path);
|
||||||
if (!f)
|
return handler->Save(file_path, m_database);
|
||||||
{
|
|
||||||
ERROR_LOG(OSHLE, "Database save failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
u32 fcount = (u32)database.size();
|
|
||||||
f.WriteArray(&fcount, 1);
|
|
||||||
for (const auto& entry : database)
|
|
||||||
{
|
|
||||||
FuncDesc temp;
|
|
||||||
memset(&temp, 0, sizeof(temp));
|
|
||||||
temp.checkSum = entry.first;
|
|
||||||
temp.size = entry.second.size;
|
|
||||||
strncpy(temp.name, entry.second.name.c_str(), 127);
|
|
||||||
f.WriteArray(&temp, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(OSHLE, "Database save successful");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a known function to the hash database
|
// Adds a known function to the hash database
|
||||||
|
@ -81,31 +46,31 @@ u32 SignatureDB::Add(u32 startAddr, u32 size, const std::string& name)
|
||||||
temp_dbfunc.size = size;
|
temp_dbfunc.size = size;
|
||||||
temp_dbfunc.name = name;
|
temp_dbfunc.name = name;
|
||||||
|
|
||||||
FuncDB::iterator iter = database.find(hash);
|
FuncDB::iterator iter = m_database.find(hash);
|
||||||
if (iter == database.end())
|
if (iter == m_database.end())
|
||||||
database[hash] = temp_dbfunc;
|
m_database[hash] = temp_dbfunc;
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignatureDB::List()
|
void SignatureDB::List()
|
||||||
{
|
{
|
||||||
for (const auto& entry : database)
|
for (const auto& entry : m_database)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(OSHLE, "%s : %i bytes, hash = %08x", entry.second.name.c_str(), entry.second.size,
|
DEBUG_LOG(OSHLE, "%s : %i bytes, hash = %08x", entry.second.name.c_str(), entry.second.size,
|
||||||
entry.first);
|
entry.first);
|
||||||
}
|
}
|
||||||
INFO_LOG(OSHLE, "%zu functions known in current database.", database.size());
|
INFO_LOG(OSHLE, "%zu functions known in current database.", m_database.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignatureDB::Clear()
|
void SignatureDB::Clear()
|
||||||
{
|
{
|
||||||
database.clear();
|
m_database.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignatureDB::Apply(PPCSymbolDB* symbol_db)
|
void SignatureDB::Apply(PPCSymbolDB* symbol_db)
|
||||||
{
|
{
|
||||||
for (const auto& entry : database)
|
for (const auto& entry : m_database)
|
||||||
{
|
{
|
||||||
u32 hash = entry.first;
|
u32 hash = entry.first;
|
||||||
Symbol* function = symbol_db->GetSymbolFromHash(hash);
|
Symbol* function = symbol_db->GetSymbolFromHash(hash);
|
||||||
|
@ -140,7 +105,7 @@ void SignatureDB::Initialize(PPCSymbolDB* symbol_db, const std::string& prefix)
|
||||||
DBFunc temp_dbfunc;
|
DBFunc temp_dbfunc;
|
||||||
temp_dbfunc.name = symbol.second.name;
|
temp_dbfunc.name = symbol.second.name;
|
||||||
temp_dbfunc.size = symbol.second.size;
|
temp_dbfunc.size = symbol.second.size;
|
||||||
database[symbol.second.hash] = temp_dbfunc;
|
m_database[symbol.second.hash] = temp_dbfunc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,3 +168,7 @@ void SignatureDB::Initialize(PPCSymbolDB* symbol_db, const std::string& prefix)
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SignatureDBFormatHandler::~SignatureDBFormatHandler()
|
||||||
|
{
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
@ -12,28 +13,27 @@
|
||||||
// You're not meant to keep around SignatureDB objects persistently. Use 'em, throw them away.
|
// You're not meant to keep around SignatureDB objects persistently. Use 'em, throw them away.
|
||||||
|
|
||||||
class PPCSymbolDB;
|
class PPCSymbolDB;
|
||||||
|
class SignatureDBFormatHandler;
|
||||||
|
|
||||||
class SignatureDB
|
class SignatureDB
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
struct DBFunc
|
struct DBFunc
|
||||||
{
|
{
|
||||||
std::string name;
|
|
||||||
u32 size;
|
u32 size;
|
||||||
|
std::string name;
|
||||||
|
std::string object_name;
|
||||||
|
std::string object_location;
|
||||||
DBFunc() : size(0) {}
|
DBFunc() : size(0) {}
|
||||||
};
|
};
|
||||||
|
using FuncDB = std::map<u32, DBFunc>;
|
||||||
|
|
||||||
// Map from signature to function. We store the DB in this map because it optimizes the
|
|
||||||
// most common operation - lookup. We don't care about ordering anyway.
|
|
||||||
typedef std::map<u32, DBFunc> FuncDB;
|
|
||||||
FuncDB database;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Returns the hash.
|
// Returns the hash.
|
||||||
u32 Add(u32 startAddr, u32 size, const std::string& name);
|
u32 Add(u32 startAddr, u32 size, const std::string& name);
|
||||||
|
|
||||||
bool Load(const std::string&
|
// Does not clear. Remember to clear first if that's what you want.
|
||||||
filename); // Does not clear. Remember to clear first if that's what you want.
|
bool Load(const std::string& file_path);
|
||||||
bool Save(const std::string& filename);
|
bool Save(const std::string& file_path);
|
||||||
void Clear();
|
void Clear();
|
||||||
void List();
|
void List();
|
||||||
|
|
||||||
|
@ -41,4 +41,18 @@ public:
|
||||||
void Apply(PPCSymbolDB* func_db);
|
void Apply(PPCSymbolDB* func_db);
|
||||||
|
|
||||||
static u32 ComputeCodeChecksum(u32 offsetStart, u32 offsetEnd);
|
static u32 ComputeCodeChecksum(u32 offsetStart, u32 offsetEnd);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<SignatureDBFormatHandler> CreateFormatHandler(const std::string& file_path);
|
||||||
|
// Map from signature to function. We store the DB in this map because it optimizes the
|
||||||
|
// most common operation - lookup. We don't care about ordering anyway.
|
||||||
|
FuncDB m_database;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SignatureDBFormatHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~SignatureDBFormatHandler();
|
||||||
|
virtual bool Load(const std::string& file_path, SignatureDB::FuncDB& database) const = 0;
|
||||||
|
virtual bool Save(const std::string& file_path, const SignatureDB::FuncDB& database) const = 0;
|
||||||
};
|
};
|
|
@ -32,7 +32,7 @@
|
||||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/PowerPC/Profiler.h"
|
#include "Core/PowerPC/Profiler.h"
|
||||||
#include "Core/PowerPC/SignatureDB.h"
|
#include "Core/PowerPC/SignatureDB/SignatureDB.h"
|
||||||
|
|
||||||
#include "DolphinWX/Debugger/BreakpointWindow.h"
|
#include "DolphinWX/Debugger/BreakpointWindow.h"
|
||||||
#include "DolphinWX/Debugger/CodeWindow.h"
|
#include "DolphinWX/Debugger/CodeWindow.h"
|
||||||
|
@ -161,6 +161,9 @@ void CCodeWindow::OnProfilerMenu(wxCommandEvent& event)
|
||||||
|
|
||||||
void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
|
static const wxString signature_selector = _("Dolphin Signature File (*.dsy)") + "|*.dsy|" +
|
||||||
|
_("Dolphin Signature CSV File (*.csv)") + "|*.csv|" +
|
||||||
|
wxGetTranslation(wxALL_FILES);
|
||||||
Parent->ClearStatusBar();
|
Parent->ClearStatusBar();
|
||||||
|
|
||||||
if (!Core::IsRunning())
|
if (!Core::IsRunning())
|
||||||
|
@ -309,8 +312,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
std::string prefix(WxStrToStr(input_prefix.GetValue()));
|
std::string prefix(WxStrToStr(input_prefix.GetValue()));
|
||||||
|
|
||||||
wxString path = wxFileSelector(_("Save signature as"), File::GetSysDirectory(), wxEmptyString,
|
wxString path = wxFileSelector(_("Save signature as"), File::GetSysDirectory(), wxEmptyString,
|
||||||
wxEmptyString, _("Dolphin Signature File (*.dsy)") +
|
wxEmptyString, signature_selector,
|
||||||
"|*.dsy|" + wxGetTranslation(wxALL_FILES),
|
|
||||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this);
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this);
|
||||||
if (!path.IsEmpty())
|
if (!path.IsEmpty())
|
||||||
{
|
{
|
||||||
|
@ -332,10 +334,9 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
std::string prefix(WxStrToStr(input_prefix.GetValue()));
|
std::string prefix(WxStrToStr(input_prefix.GetValue()));
|
||||||
|
|
||||||
wxString path = wxFileSelector(
|
wxString path =
|
||||||
_("Append signature to"), File::GetSysDirectory(), wxEmptyString, wxEmptyString,
|
wxFileSelector(_("Append signature to"), File::GetSysDirectory(), wxEmptyString,
|
||||||
_("Dolphin Signature File (*.dsy)") + "|*.dsy|" + wxGetTranslation(wxALL_FILES),
|
wxEmptyString, signature_selector, wxFD_SAVE, this);
|
||||||
wxFD_SAVE, this);
|
|
||||||
if (!path.IsEmpty())
|
if (!path.IsEmpty())
|
||||||
{
|
{
|
||||||
SignatureDB db;
|
SignatureDB db;
|
||||||
|
@ -350,10 +351,9 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
break;
|
break;
|
||||||
case IDM_USE_SIGNATURE_FILE:
|
case IDM_USE_SIGNATURE_FILE:
|
||||||
{
|
{
|
||||||
wxString path = wxFileSelector(
|
wxString path =
|
||||||
_("Apply signature file"), File::GetSysDirectory(), wxEmptyString, wxEmptyString,
|
wxFileSelector(_("Apply signature file"), File::GetSysDirectory(), wxEmptyString,
|
||||||
_("Dolphin Signature File (*.dsy)") + "|*.dsy|" + wxGetTranslation(wxALL_FILES),
|
wxEmptyString, signature_selector, wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
|
||||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
|
|
||||||
if (!path.IsEmpty())
|
if (!path.IsEmpty())
|
||||||
{
|
{
|
||||||
SignatureDB db;
|
SignatureDB db;
|
||||||
|
@ -366,25 +366,22 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
|
||||||
break;
|
break;
|
||||||
case IDM_COMBINE_SIGNATURE_FILES:
|
case IDM_COMBINE_SIGNATURE_FILES:
|
||||||
{
|
{
|
||||||
wxString path1 = wxFileSelector(
|
wxString path1 =
|
||||||
_("Choose priority input file"), File::GetSysDirectory(), wxEmptyString, wxEmptyString,
|
wxFileSelector(_("Choose priority input file"), File::GetSysDirectory(), wxEmptyString,
|
||||||
_("Dolphin Signature File (*.dsy)") + "|*.dsy|" + wxGetTranslation(wxALL_FILES),
|
wxEmptyString, signature_selector, wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
|
||||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
|
|
||||||
if (!path1.IsEmpty())
|
if (!path1.IsEmpty())
|
||||||
{
|
{
|
||||||
SignatureDB db;
|
SignatureDB db;
|
||||||
wxString path2 = wxFileSelector(
|
wxString path2 =
|
||||||
_("Choose secondary input file"), File::GetSysDirectory(), wxEmptyString, wxEmptyString,
|
wxFileSelector(_("Choose secondary input file"), File::GetSysDirectory(), wxEmptyString,
|
||||||
_("Dolphin Signature File (*.dsy)") + "|*.dsy|" + wxGetTranslation(wxALL_FILES),
|
wxEmptyString, signature_selector, wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
|
||||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
|
|
||||||
if (!path2.IsEmpty())
|
if (!path2.IsEmpty())
|
||||||
{
|
{
|
||||||
db.Load(WxStrToStr(path2));
|
db.Load(WxStrToStr(path2));
|
||||||
db.Load(WxStrToStr(path1));
|
db.Load(WxStrToStr(path1));
|
||||||
|
|
||||||
path2 = wxFileSelector(_("Save combined output file as"), File::GetSysDirectory(),
|
path2 = wxFileSelector(_("Save combined output file as"), File::GetSysDirectory(),
|
||||||
wxEmptyString, ".dsy", _("Dolphin Signature File (*.dsy)") +
|
wxEmptyString, ".dsy", signature_selector,
|
||||||
"|*.dsy|" + wxGetTranslation(wxALL_FILES),
|
|
||||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this);
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this);
|
||||||
db.Save(WxStrToStr(path2));
|
db.Save(WxStrToStr(path2));
|
||||||
db.List();
|
db.List();
|
||||||
|
|
|
@ -16,3 +16,27 @@ TEST(StringUtil, JoinStrings)
|
||||||
EXPECT_EQ("a, bb, c", JoinStrings({"a", "bb", "c"}, ", "));
|
EXPECT_EQ("a, bb, c", JoinStrings({"a", "bb", "c"}, ", "));
|
||||||
EXPECT_EQ("???", JoinStrings({"?", "?"}, "?"));
|
EXPECT_EQ("???", JoinStrings({"?", "?"}, "?"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(StringUtil, StringBeginsWith)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(true, StringBeginsWith("abc", "a"));
|
||||||
|
EXPECT_EQ(false, StringBeginsWith("abc", "b"));
|
||||||
|
EXPECT_EQ(true, StringBeginsWith("abc", "ab"));
|
||||||
|
EXPECT_EQ(false, StringBeginsWith("a", "ab"));
|
||||||
|
EXPECT_EQ(false, StringBeginsWith("", "a"));
|
||||||
|
EXPECT_EQ(false, StringBeginsWith("", "ab"));
|
||||||
|
EXPECT_EQ(true, StringBeginsWith("abc", ""));
|
||||||
|
EXPECT_EQ(true, StringBeginsWith("", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(StringUtil, StringEndsWith)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(true, StringEndsWith("abc", "c"));
|
||||||
|
EXPECT_EQ(false, StringEndsWith("abc", "b"));
|
||||||
|
EXPECT_EQ(true, StringEndsWith("abc", "bc"));
|
||||||
|
EXPECT_EQ(false, StringEndsWith("a", "ab"));
|
||||||
|
EXPECT_EQ(false, StringEndsWith("", "a"));
|
||||||
|
EXPECT_EQ(false, StringEndsWith("", "ab"));
|
||||||
|
EXPECT_EQ(true, StringEndsWith("abc", ""));
|
||||||
|
EXPECT_EQ(true, StringEndsWith("", ""));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue