diff --git a/Source/Core/Common/StringUtil.cpp b/Source/Core/Common/StringUtil.cpp
index 6f3567e782..95cc3b1586 100644
--- a/Source/Core/Common/StringUtil.cpp
+++ b/Source/Core/Common/StringUtil.cpp
@@ -373,6 +373,16 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
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
std::string UTF16ToUTF8(const std::wstring& input)
diff --git a/Source/Core/Common/StringUtil.h b/Source/Core/Common/StringUtil.h
index fcc8c34483..4f8f602933 100644
--- a/Source/Core/Common/StringUtil.h
+++ b/Source/Core/Common/StringUtil.h
@@ -116,6 +116,9 @@ void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _P
const std::string& _Filename);
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 SHIFTJISToUTF8(const std::string& str);
std::string UTF16ToUTF8(const std::wstring& str);
diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index 03f1dcfafe..5b263e45e6 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -31,7 +31,7 @@
#include "Core/PowerPC/PPCAnalyst.h"
#include "Core/PowerPC/PPCSymbolDB.h"
#include "Core/PowerPC/PowerPC.h"
-#include "Core/PowerPC/SignatureDB.h"
+#include "Core/PowerPC/SignatureDB/SignatureDB.h"
#include "DiscIO/Enums.h"
#include "DiscIO/NANDContentLoader.h"
diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index 0072c57254..6c007f68be 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -163,7 +163,9 @@ set(SRCS ActionReplay.cpp
PowerPC/PPCSymbolDB.cpp
PowerPC/PPCTables.cpp
PowerPC/Profiler.cpp
- PowerPC/SignatureDB.cpp
+ PowerPC/SignatureDB/CSVSignatureDB.cpp
+ PowerPC/SignatureDB/DSYSignatureDB.cpp
+ PowerPC/SignatureDB/SignatureDB.cpp
PowerPC/JitInterface.cpp
PowerPC/Interpreter/Interpreter_Branch.cpp
PowerPC/Interpreter/Interpreter.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index c851e266d4..274bcd7edd 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -245,6 +245,9 @@
+
+
+
@@ -254,7 +257,6 @@
-
@@ -438,6 +440,9 @@
+
+
+
@@ -446,7 +451,6 @@
-
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index a42cc100c7..1df6538b86 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -648,9 +648,6 @@
PowerPC
-
- PowerPC
-
PowerPC\JitCommon
@@ -754,6 +751,15 @@
IPC HLE %28IOS/Starlet%29\USB
+
+ PowerPC\SignatureDB
+
+
+ PowerPC\SignatureDB
+
+
+ PowerPC\SignatureDB
+
@@ -1238,9 +1244,6 @@
PowerPC
-
- PowerPC
-
PowerPC\JitCommon
@@ -1294,6 +1297,15 @@
IPC HLE %28IOS/Starlet%29\USB
+
+ PowerPC\SignatureDB
+
+
+ PowerPC\SignatureDB
+
+
+ PowerPC\SignatureDB
+
diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp
index 28949cfdd6..11db99c2e6 100644
--- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp
+++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp
@@ -15,7 +15,7 @@
#include "Core/PowerPC/PPCSymbolDB.h"
#include "Core/PowerPC/PPCTables.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
// After running, for each function we will know what functions it calls
diff --git a/Source/Core/Core/PowerPC/PPCSymbolDB.cpp b/Source/Core/Core/PowerPC/PPCSymbolDB.cpp
index b80fe9f4af..e20a1bfb0c 100644
--- a/Source/Core/Core/PowerPC/PPCSymbolDB.cpp
+++ b/Source/Core/Core/PowerPC/PPCSymbolDB.cpp
@@ -14,7 +14,7 @@
#include "Core/PowerPC/PPCAnalyst.h"
#include "Core/PowerPC/PPCSymbolDB.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)
{
diff --git a/Source/Core/Core/PowerPC/SignatureDB/CSVSignatureDB.cpp b/Source/Core/Core/PowerPC/SignatureDB/CSVSignatureDB.cpp
new file mode 100644
index 0000000000..de2bc20ff9
--- /dev/null
+++ b/Source/Core/Core/PowerPC/SignatureDB/CSVSignatureDB.cpp
@@ -0,0 +1,75 @@
+#include
+#include
+#include
+
+#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;
+}
diff --git a/Source/Core/Core/PowerPC/SignatureDB/CSVSignatureDB.h b/Source/Core/Core/PowerPC/SignatureDB/CSVSignatureDB.h
new file mode 100644
index 0000000000..6d9986d3f9
--- /dev/null
+++ b/Source/Core/Core/PowerPC/SignatureDB/CSVSignatureDB.h
@@ -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;
+};
diff --git a/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.cpp b/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.cpp
new file mode 100644
index 0000000000..31f9a02dd8
--- /dev/null
+++ b/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.cpp
@@ -0,0 +1,69 @@
+#include
+#include
+
+#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(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;
+}
diff --git a/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.h b/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.h
new file mode 100644
index 0000000000..ffad6baa3d
--- /dev/null
+++ b/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.h
@@ -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;
+};
diff --git a/Source/Core/Core/PowerPC/SignatureDB.cpp b/Source/Core/Core/PowerPC/SignatureDB/SignatureDB.cpp
similarity index 69%
rename from Source/Core/Core/PowerPC/SignatureDB.cpp
rename to Source/Core/Core/PowerPC/SignatureDB/SignatureDB.cpp
index 8936a1a9a9..93485c43d0 100644
--- a/Source/Core/Core/PowerPC/SignatureDB.cpp
+++ b/Source/Core/Core/PowerPC/SignatureDB/SignatureDB.cpp
@@ -7,69 +7,34 @@
#include "Common/CommonTypes.h"
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
+#include "Common/StringUtil.h"
#include "Core/PowerPC/PPCAnalyst.h"
#include "Core/PowerPC/PPCSymbolDB.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
+SignatureDB::CreateFormatHandler(const std::string& file_path)
{
-// On-disk format for SignatureDB entries.
-struct FuncDesc
-{
- 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;
+ if (StringEndsWith(file_path, ".csv"))
+ return std::make_unique();
+ return std::make_unique();
}
-bool SignatureDB::Save(const std::string& filename)
+bool SignatureDB::Load(const std::string& file_path)
{
- File::IOFile f(filename, "wb");
- if (!f)
- {
- 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);
- }
+ auto handler = CreateFormatHandler(file_path);
+ return handler->Load(file_path, m_database);
+}
- INFO_LOG(OSHLE, "Database save successful");
- return true;
+bool SignatureDB::Save(const std::string& file_path)
+{
+ auto handler = CreateFormatHandler(file_path);
+ return handler->Save(file_path, m_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.name = name;
- FuncDB::iterator iter = database.find(hash);
- if (iter == database.end())
- database[hash] = temp_dbfunc;
+ FuncDB::iterator iter = m_database.find(hash);
+ if (iter == m_database.end())
+ m_database[hash] = temp_dbfunc;
return hash;
}
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,
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()
{
- database.clear();
+ m_database.clear();
}
void SignatureDB::Apply(PPCSymbolDB* symbol_db)
{
- for (const auto& entry : database)
+ for (const auto& entry : m_database)
{
u32 hash = entry.first;
Symbol* function = symbol_db->GetSymbolFromHash(hash);
@@ -140,7 +105,7 @@ void SignatureDB::Initialize(PPCSymbolDB* symbol_db, const std::string& prefix)
DBFunc temp_dbfunc;
temp_dbfunc.name = symbol.second.name;
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;
}
+
+SignatureDBFormatHandler::~SignatureDBFormatHandler()
+{
+}
diff --git a/Source/Core/Core/PowerPC/SignatureDB.h b/Source/Core/Core/PowerPC/SignatureDB/SignatureDB.h
similarity index 55%
rename from Source/Core/Core/PowerPC/SignatureDB.h
rename to Source/Core/Core/PowerPC/SignatureDB/SignatureDB.h
index 6c081aacce..d0f0c46231 100644
--- a/Source/Core/Core/PowerPC/SignatureDB.h
+++ b/Source/Core/Core/PowerPC/SignatureDB/SignatureDB.h
@@ -5,6 +5,7 @@
#pragma once
#include