mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Light refactor of the IDetour interface
- Use std::map for mapping vtables to interface objects, previously done with a set and a vector. - Objects are no longer inline, which significantly reduced output code size as all redundant dynamic initializers (created for each translation unit) have been pruned.
This commit is contained in:
parent
ed1b365c12
commit
7762c4b2ce
@ -170,9 +170,10 @@ void Systems_Init()
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
// Hook functions
|
||||
for (const IDetour* pDetour : g_DetourVector)
|
||||
for (const auto& elem : g_DetourMap)
|
||||
{
|
||||
pDetour->Attach();
|
||||
const IDetour* detour = elem.second;
|
||||
detour->Attach();
|
||||
}
|
||||
|
||||
// Patch instructions
|
||||
@ -215,9 +216,10 @@ void Systems_Shutdown()
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
// Unhook functions
|
||||
for (const IDetour* pDetour : g_DetourVector)
|
||||
for (const auto& elem : g_DetourMap)
|
||||
{
|
||||
pDetour->Detach();
|
||||
const IDetour* detour = elem.second;
|
||||
detour->Detach();
|
||||
}
|
||||
|
||||
// Commit the transaction
|
||||
@ -342,11 +344,13 @@ void DetourInit() // Run the sigscan
|
||||
g_SigCache.SetDisabled(bNoSmap);
|
||||
g_SigCache.LoadCache(SIGDB_FILE);
|
||||
|
||||
for (const IDetour* pDetour : g_DetourVector)
|
||||
for (const auto& elem : g_DetourMap)
|
||||
{
|
||||
pDetour->GetCon(); // Constants.
|
||||
pDetour->GetFun(); // Functions.
|
||||
pDetour->GetVar(); // Variables.
|
||||
const IDetour* detour = elem.second;
|
||||
|
||||
detour->GetCon(); // Constants.
|
||||
detour->GetFun(); // Functions.
|
||||
detour->GetVar(); // Variables.
|
||||
|
||||
if (bLogAdr)
|
||||
{
|
||||
@ -355,7 +359,7 @@ void DetourInit() // Run the sigscan
|
||||
bInitDivider = true;
|
||||
spdlog::debug("+---------------------------------------------------------------------+\n");
|
||||
}
|
||||
pDetour->GetAdr();
|
||||
detour->GetAdr();
|
||||
spdlog::debug("+---------------------------------------------------------------------+\n");
|
||||
}
|
||||
}
|
||||
@ -372,9 +376,11 @@ void DetourInit() // Run the sigscan
|
||||
void DetourAddress() // Test the sigscan results
|
||||
{
|
||||
spdlog::debug("+---------------------------------------------------------------------+\n");
|
||||
for (const IDetour* pDetour : g_DetourVector)
|
||||
for (const auto& elem : g_DetourMap)
|
||||
{
|
||||
pDetour->GetAdr();
|
||||
const IDetour* detour = elem.second;
|
||||
|
||||
detour->GetAdr();
|
||||
spdlog::debug("+---------------------------------------------------------------------+\n");
|
||||
}
|
||||
}
|
||||
|
1
r5dev/thirdparty/detours/CMakeLists.txt
vendored
1
r5dev/thirdparty/detours/CMakeLists.txt
vendored
@ -7,6 +7,7 @@ add_sources( SOURCE_GROUP "Source"
|
||||
"src/creatwth.cpp"
|
||||
"src/detours.cpp"
|
||||
"src/disasm.cpp"
|
||||
"src/idetour.cpp"
|
||||
"src/modules.cpp"
|
||||
)
|
||||
|
||||
|
34
r5dev/thirdparty/detours/include/idetour.h
vendored
34
r5dev/thirdparty/detours/include/idetour.h
vendored
@ -1,10 +1,9 @@
|
||||
#ifndef IDETOUR_H
|
||||
#define IDETOUR_H
|
||||
|
||||
#define ADDDETOUR(x,y) static std::size_t dummy_reg_##y = AddDetour( new x() );
|
||||
#define XREGISTER(x,y) ADDDETOUR(x, y)
|
||||
#define REGISTER(x) XREGISTER(x, __COUNTER__)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interface class for context hooks
|
||||
//-----------------------------------------------------------------------------
|
||||
class IDetour
|
||||
{
|
||||
public:
|
||||
@ -18,28 +17,11 @@ public:
|
||||
virtual void Detach(void) const = 0;
|
||||
};
|
||||
|
||||
class VDetour : public IDetour
|
||||
{
|
||||
virtual void GetAdr(void) const { }
|
||||
virtual void GetFun(void) const { }
|
||||
virtual void GetVar(void) const { }
|
||||
virtual void GetCon(void) const { }
|
||||
extern std::map<const void*, const IDetour*> g_DetourMap;
|
||||
std::size_t AddDetour(IDetour* pDetour);
|
||||
|
||||
virtual void Attach(void) const { }
|
||||
virtual void Detach(void) const { }
|
||||
};
|
||||
|
||||
inline static std::vector<IDetour*> g_DetourVector;
|
||||
inline static std::unordered_set<IDetour*> g_DetourSet;
|
||||
inline std::size_t AddDetour(IDetour* pDetour)
|
||||
{
|
||||
IDetour* pVFTable = reinterpret_cast<IDetour**>(pDetour)[0];
|
||||
auto p = g_DetourSet.insert(pVFTable); // Only register if VFTable isn't already registered.
|
||||
|
||||
assert(p.second); // Code bug: duplicate registration!!! (called 'REGISTER(...)' from a header file?).
|
||||
p.second ? g_DetourVector.push_back(pDetour) : delete pDetour;
|
||||
|
||||
return g_DetourVector.size();
|
||||
}
|
||||
#define ADDDETOUR(x,y) static std::size_t dummy_reg_##y = AddDetour( new x() );
|
||||
#define XREGISTER(x,y) ADDDETOUR(x, y)
|
||||
#define REGISTER(x) XREGISTER(x, __COUNTER__)
|
||||
|
||||
#endif // IDETOUR_H
|
||||
|
30
r5dev/thirdparty/detours/src/idetour.cpp
vendored
Normal file
30
r5dev/thirdparty/detours/src/idetour.cpp
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
//===========================================================================//
|
||||
//
|
||||
// Purpose: Hook interface
|
||||
//
|
||||
//===========================================================================//
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include "../include/idetour.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Contains a VFTable pointer, and the class instance. A VFTable can only be
|
||||
// used by one class instance. This is to avoid duplicate registrations.
|
||||
//-----------------------------------------------------------------------------
|
||||
std::map<const void*, const IDetour*> g_DetourMap;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: adds a detour context to the list
|
||||
//-----------------------------------------------------------------------------
|
||||
std::size_t AddDetour(IDetour* pDetour)
|
||||
{
|
||||
const void* pVFTable = reinterpret_cast<const void**>(pDetour)[0];
|
||||
auto p = g_DetourMap.emplace(pVFTable, pDetour); // Only register if VFTable isn't already registered.
|
||||
|
||||
assert(p.second); // Code bug: duplicate registration!!! (called 'REGISTER(...)' from a header file?).
|
||||
|
||||
if (!p.second)
|
||||
delete pDetour;
|
||||
|
||||
return g_DetourMap.size();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user