SignatureDB: Rewrite FormatHandler API

This commit is contained in:
Sepalani 2017-03-24 00:31:52 +00:00
parent 2daf5cb86f
commit a9b52ce91b
9 changed files with 150 additions and 68 deletions

View File

@ -99,7 +99,7 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
{
func.address = startAddr;
func.analyzed = true;
func.hash = SignatureDB::ComputeCodeChecksum(startAddr, addr);
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr);
if (numInternalBranches == 0)
func.flags |= FFLAG_STRAIGHT;
return true;
@ -120,7 +120,7 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
// Let's calc the checksum and get outta here
func.address = startAddr;
func.analyzed = true;
func.hash = SignatureDB::ComputeCodeChecksum(startAddr, addr);
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr);
if (numInternalBranches == 0)
func.flags |= FFLAG_STRAIGHT;
return true;
@ -136,7 +136,7 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
func.size *= 4; // into bytes
func.address = startAddr;
func.analyzed = 1;
func.hash = SignatureDB::ComputeCodeChecksum(startAddr, addr);
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr);
if (numInternalBranches == 0)
func.flags |= FFLAG_STRAIGHT;
return true;

View File

@ -72,7 +72,7 @@ void PPCSymbolDB::AddKnownSymbol(u32 startAddr, u32 size, const std::string& nam
Symbol* tempfunc = &iter->second;
tempfunc->name = name;
tempfunc->function_name = GetStrippedFunctionName(name);
tempfunc->hash = SignatureDB::ComputeCodeChecksum(startAddr, startAddr + size - 4);
tempfunc->hash = HashSignatureDB::ComputeCodeChecksum(startAddr, startAddr + size - 4);
tempfunc->type = type;
tempfunc->size = size;
}

View File

@ -13,7 +13,7 @@
// CSV separated with tabs
// Checksum | Size | Symbol | [Object Location |] Object Name
bool CSVSignatureDB::Load(const std::string& file_path, SignatureDB::FuncDB& database) const
bool CSVSignatureDB::Load(const std::string& file_path)
{
std::string line;
std::ifstream ifs;
@ -32,7 +32,7 @@ bool CSVSignatureDB::Load(const std::string& file_path, SignatureDB::FuncDB& dat
{
if (std::getline(iss, symbol, '\t') && std::getline(iss, object_location, '\t'))
std::getline(iss, object_name);
SignatureDB::DBFunc func;
HashSignatureDB::DBFunc func;
func.name = symbol;
func.size = size;
// Doesn't have an object location
@ -45,7 +45,7 @@ bool CSVSignatureDB::Load(const std::string& file_path, SignatureDB::FuncDB& dat
func.object_location = object_location;
func.object_name = object_name;
}
database[checksum] = func;
m_database[checksum] = func;
}
else
{
@ -56,7 +56,7 @@ bool CSVSignatureDB::Load(const std::string& file_path, SignatureDB::FuncDB& dat
return true;
}
bool CSVSignatureDB::Save(const std::string& file_path, const SignatureDB::FuncDB& database) const
bool CSVSignatureDB::Save(const std::string& file_path) const
{
File::IOFile f(file_path, "w");
@ -65,7 +65,7 @@ bool CSVSignatureDB::Save(const std::string& file_path, const SignatureDB::FuncD
ERROR_LOG(OSHLE, "CSV database save failed");
return false;
}
for (const auto& func : database)
for (const auto& func : m_database)
{
// The object name/location are unused for the time being.
// To be implemented.

View File

@ -6,10 +6,10 @@
#include "Core/PowerPC/SignatureDB/SignatureDB.h"
class CSVSignatureDB final : public SignatureDBFormatHandler
class CSVSignatureDB final : public HashSignatureDB
{
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;
bool Load(const std::string& file_path) override;
bool Save(const std::string& file_path) const override;
};

View File

@ -22,7 +22,7 @@ struct FuncDesc
};
} // namespace
bool DSYSignatureDB::Load(const std::string& file_path, SignatureDB::FuncDB& database) const
bool DSYSignatureDB::Load(const std::string& file_path)
{
File::IOFile f(file_path, "rb");
@ -38,16 +38,16 @@ bool DSYSignatureDB::Load(const std::string& file_path, SignatureDB::FuncDB& dat
f.ReadArray(&temp, 1);
temp.name[sizeof(temp.name) - 1] = 0;
SignatureDB::DBFunc func;
HashSignatureDB::DBFunc func;
func.name = temp.name;
func.size = temp.size;
database[temp.checksum] = func;
m_database[temp.checksum] = func;
}
return true;
}
bool DSYSignatureDB::Save(const std::string& file_path, const SignatureDB::FuncDB& database) const
bool DSYSignatureDB::Save(const std::string& file_path) const
{
File::IOFile f(file_path, "wb");
@ -56,9 +56,9 @@ bool DSYSignatureDB::Save(const std::string& file_path, const SignatureDB::FuncD
ERROR_LOG(OSHLE, "Database save failed");
return false;
}
u32 fcount = static_cast<u32>(database.size());
u32 fcount = static_cast<u32>(m_database.size());
f.WriteArray(&fcount, 1);
for (const auto& entry : database)
for (const auto& entry : m_database)
{
FuncDesc temp;
memset(&temp, 0, sizeof(temp));

View File

@ -6,10 +6,10 @@
#include "Core/PowerPC/SignatureDB/SignatureDB.h"
class DSYSignatureDB final : public SignatureDBFormatHandler
class DSYSignatureDB final : public HashSignatureDB
{
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;
bool Load(const std::string& file_path) override;
bool Save(const std::string& file_path) const override;
};

View File

@ -17,28 +17,72 @@
#include "Core/PowerPC/SignatureDB/CSVSignatureDB.h"
#include "Core/PowerPC/SignatureDB/DSYSignatureDB.h"
std::unique_ptr<SignatureDBFormatHandler>
SignatureDB::CreateFormatHandler(const std::string& file_path) const
SignatureDB::SignatureDB(SignatureDB::HandlerType handler)
: m_handler(std::move(CreateFormatHandler(handler)))
{
}
SignatureDB::SignatureDB(const std::string& file_path) : SignatureDB(GetHandlerType(file_path))
{
}
SignatureDB::HandlerType SignatureDB::GetHandlerType(const std::string& file_path)
{
if (StringEndsWith(file_path, ".csv"))
return SignatureDB::HandlerType::CSV;
return SignatureDB::HandlerType::DSY;
}
std::unique_ptr<SignatureDBFormatHandler>
SignatureDB::CreateFormatHandler(SignatureDB::HandlerType handler) const
{
switch (handler)
{
default:
case SignatureDB::HandlerType::DSY:
return std::make_unique<DSYSignatureDB>();
case SignatureDB::HandlerType::CSV:
return std::make_unique<CSVSignatureDB>();
return std::make_unique<DSYSignatureDB>();
}
}
void SignatureDB::Clear()
{
m_handler->Clear();
}
bool SignatureDB::Load(const std::string& file_path)
{
auto handler = CreateFormatHandler(file_path);
return handler->Load(file_path, m_database);
return m_handler->Load(file_path);
}
bool SignatureDB::Save(const std::string& file_path) const
{
auto handler = CreateFormatHandler(file_path);
return handler->Save(file_path, m_database);
return m_handler->Save(file_path);
}
void SignatureDB::List() const
{
m_handler->List();
}
void SignatureDB::Populate(const PPCSymbolDB* func_db, const std::string& filter)
{
m_handler->Populate(func_db, filter);
}
void SignatureDB::Apply(PPCSymbolDB* func_db) const
{
m_handler->Apply(func_db);
}
bool SignatureDB::Add(u32 start_addr, u32 size, const std::string& name)
{
return m_handler->Add(start_addr, size, name);
}
// Adds a known function to the hash database
/*u32 SignatureDB::Add(u32 startAddr, u32 size, const std::string& name)
bool HashSignatureDB::Add(u32 startAddr, u32 size, const std::string& name)
{
u32 hash = ComputeCodeChecksum(startAddr, startAddr + size - 4);
@ -48,12 +92,14 @@ bool SignatureDB::Save(const std::string& file_path) const
FuncDB::iterator iter = m_database.find(hash);
if (iter == m_database.end())
{
m_database[hash] = temp_dbfunc;
return true;
}
return false;
}
return hash;
}*/
void SignatureDB::List() const
void HashSignatureDB::List() const
{
for (const auto& entry : m_database)
{
@ -63,12 +109,12 @@ void SignatureDB::List() const
INFO_LOG(OSHLE, "%zu functions known in current database.", m_database.size());
}
void SignatureDB::Clear()
void HashSignatureDB::Clear()
{
m_database.clear();
}
void SignatureDB::Apply(PPCSymbolDB* symbol_db) const
void HashSignatureDB::Apply(PPCSymbolDB* symbol_db) const
{
for (const auto& entry : m_database)
{
@ -92,7 +138,7 @@ void SignatureDB::Apply(PPCSymbolDB* symbol_db) const
symbol_db->Index();
}
void SignatureDB::Populate(const PPCSymbolDB* symbol_db, const std::string& filter)
void HashSignatureDB::Populate(const PPCSymbolDB* symbol_db, const std::string& filter)
{
for (const auto& symbol : symbol_db->Symbols())
{
@ -108,7 +154,7 @@ void SignatureDB::Populate(const PPCSymbolDB* symbol_db, const std::string& filt
}
}
/*static*/ u32 SignatureDB::ComputeCodeChecksum(u32 offsetStart, u32 offsetEnd)
u32 HashSignatureDB::ComputeCodeChecksum(u32 offsetStart, u32 offsetEnd)
{
u32 sum = 0;
for (u32 offset = offsetStart; offset <= offsetEnd; offset += 4)

View File

@ -17,6 +17,51 @@ class SignatureDBFormatHandler;
class SignatureDB
{
public:
enum class HandlerType
{
DSY,
CSV
};
explicit SignatureDB(HandlerType handler = HandlerType::DSY);
explicit SignatureDB(const std::string& file_path);
static HandlerType GetHandlerType(const std::string& file_path);
void Clear();
// 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& file_path) const;
void List() const;
void Populate(const PPCSymbolDB* func_db, const std::string& filter = "");
void Apply(PPCSymbolDB* func_db) const;
bool Add(u32 start_addr, u32 size, const std::string& name);
private:
std::unique_ptr<SignatureDBFormatHandler> CreateFormatHandler(HandlerType handler) const;
std::unique_ptr<SignatureDBFormatHandler> m_handler;
};
class SignatureDBFormatHandler
{
public:
virtual ~SignatureDBFormatHandler();
virtual void Clear() = 0;
virtual bool Load(const std::string& file_path) = 0;
virtual bool Save(const std::string& file_path) const = 0;
virtual void List() const = 0;
virtual void Populate(const PPCSymbolDB* func_db, const std::string& filter = "") = 0;
virtual void Apply(PPCSymbolDB* func_db) const = 0;
virtual bool Add(u32 startAddr, u32 size, const std::string& name) = 0;
};
class HashSignatureDB : public SignatureDBFormatHandler
{
public:
struct DBFunc
{
@ -28,31 +73,18 @@ public:
};
using FuncDB = std::map<u32, DBFunc>;
// Returns the hash.
u32 Add(u32 startAddr, u32 size, const std::string& name);
// 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& file_path) const;
void List() const;
void Clear();
void Populate(const PPCSymbolDB* func_db, const std::string& filter = "");
void Apply(PPCSymbolDB* func_db) const;
static u32 ComputeCodeChecksum(u32 offsetStart, u32 offsetEnd);
private:
std::unique_ptr<SignatureDBFormatHandler> CreateFormatHandler(const std::string& file_path) const;
virtual void Clear() override;
virtual void List() const override;
virtual void Populate(const PPCSymbolDB* func_db, const std::string& filter = "") override;
virtual void Apply(PPCSymbolDB* func_db) const override;
virtual bool Add(u32 startAddr, u32 size, const std::string& name) override;
protected:
// 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;
};

View File

@ -352,9 +352,10 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this);
if (!path.IsEmpty())
{
SignatureDB db;
std::string save_path = WxStrToStr(path);
SignatureDB db(save_path);
db.Populate(&g_symbolDB, prefix);
db.Save(WxStrToStr(path));
db.Save(save_path);
db.List();
}
}
@ -375,11 +376,12 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
wxEmptyString, signature_selector, wxFD_SAVE, this);
if (!path.IsEmpty())
{
SignatureDB db;
std::string signature_path = WxStrToStr(path);
SignatureDB db(signature_path);
db.Populate(&g_symbolDB, prefix);
db.List();
db.Load(WxStrToStr(path));
db.Save(WxStrToStr(path));
db.Load(signature_path);
db.Save(signature_path);
db.List();
}
}
@ -392,8 +394,9 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
wxEmptyString, signature_selector, wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
if (!path.IsEmpty())
{
SignatureDB db;
db.Load(WxStrToStr(path));
std::string load_path = WxStrToStr(path);
SignatureDB db(load_path);
db.Load(load_path);
db.Apply(&g_symbolDB);
db.List();
NotifyMapLoaded();
@ -407,14 +410,15 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
wxEmptyString, signature_selector, wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
if (!path1.IsEmpty())
{
SignatureDB db;
std::string load_path1 = WxStrToStr(path1);
SignatureDB db(load_path1);
wxString path2 =
wxFileSelector(_("Choose secondary input file"), File::GetSysDirectory(), wxEmptyString,
wxEmptyString, signature_selector, wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
if (!path2.IsEmpty())
{
db.Load(load_path1);
db.Load(WxStrToStr(path2));
db.Load(WxStrToStr(path1));
path2 = wxFileSelector(_("Save combined output file as"), File::GetSysDirectory(),
wxEmptyString, ".dsy", signature_selector,