Fix compilation for 32bits

This commit is contained in:
Kenzzer 2024-05-16 23:45:42 +02:00 committed by Nick Hastings
parent 87fcaca024
commit ca78915d59
8 changed files with 2122 additions and 2139 deletions

View File

@ -16,11 +16,12 @@ for sdk_target in MMS.sdk_targets:
'metamod_util.cpp',
'provider/provider_base.cpp',
'sourcehook/sourcehook.cpp',
'sourcehook/sourcehook_hookmangen_test.cpp',
#'sourcehook/sourcehook_hookmangen_test.cpp',
'sourcehook/sourcehook_impl_chookidman.cpp',
'sourcehook/sourcehook_impl_chookmaninfo.cpp',
'sourcehook/sourcehook_impl_cproto.cpp',
'sourcehook/sourcehook_impl_cvfnptr.cpp',
'sourcehook/sourcehook_hookmangen.cpp',
'gamedll_bridge.cpp'
]
@ -42,7 +43,7 @@ for sdk_target in MMS.sdk_targets:
if cxx.target.arch == 'x86':
binary.sources += ['sourcehook/sourcehook_hookmangen.cpp']
elif binary.compiler.target.arch == 'x86_64':
elif binary.compiler.target.arch == 'x86_64' and binary.compiler.target.platform != 'linux':
binary.sources += ['sourcehook/sourcehook_hookmangen_x86_64.cpp']
nodes = builder.Add(binary)
MMS.binaries += [nodes]

View File

@ -34,7 +34,6 @@
#include "metamod_util.h"
#include "metamod_console.h"
#include "provider/provider_base.h"
#include "sourcehook/sourcehook_hookmangen_test.h"
#include <sys/stat.h>
#define X64_SUFFIX ".x64"
@ -85,7 +84,9 @@ static MetamodSourceConVar *mm_basedir = NULL;
static CreateInterfaceFn engine_factory = NULL;
static CreateInterfaceFn physics_factory = NULL;
static CreateInterfaceFn filesystem_factory = NULL;
#if !defined( PLATFORM_64BITS ) && !defined( _LINUX )
static CHookManagerAutoGen g_SH_HookManagerAutoGen(&g_SourceHook);
#endif
static META_RES last_meta_res;
static IServerPluginCallbacks *vsp_callbacks = NULL;
static bool were_plugins_loaded = false;
@ -221,7 +222,6 @@ mm_InitializeForLoad()
in_first_level = true;
provider->SetCallbacks(&s_ProviderCallbacks);
SourceHook::Impl::run_tests();
}
bool
@ -425,7 +425,7 @@ mm_LogMessage(const char *msg, ...)
va_start(ap, msg);
size_t len = vsnprintf(buffer, sizeof(buffer) - 2, msg, ap);
len = min(len, 2046);
len = std::min<size_t>(len, 2046);
va_end(ap);
buffer[len++] = '\n';
@ -820,6 +820,7 @@ void *MetamodSource::MetaFactory(const char *iface, int *ret, PluginId *id)
}
return static_cast<void *>(static_cast<ISmmPluginManager *>(&g_PluginMngr));
}
#if !defined( PLATFORM_64BITS ) && !defined( _LINUX )
else if (strcmp(iface, MMIFACE_SH_HOOKMANAUTOGEN) == 0)
{
if (ret)
@ -828,7 +829,7 @@ void *MetamodSource::MetaFactory(const char *iface, int *ret, PluginId *id)
}
return static_cast<void *>(static_cast<SourceHook::IHookManagerAutoGen *>(&g_SH_HookManagerAutoGen));
}
#endif
CPluginManager::CPlugin *pl;
List<IMetamodListener *>::iterator event;
IMetamodListener *api;

View File

@ -115,11 +115,11 @@ namespace SourceHook
constexpr operator x8664Reg() const { return rm; }
protected:
x86_64_RegRm::x86_64_RegRm(x8664Reg reg, std::int32_t disp) : rm(reg), disp(disp) {
x86_64_RegRm(x8664Reg reg, std::int32_t disp) : rm(reg), disp(disp) {
Setup();
}
x86_64_RegRm::x86_64_RegRm(x8664Reg reg) : rm(reg), disp(0) {
x86_64_RegRm(x8664Reg reg) : rm(reg), disp(0) {
Setup();
}
@ -155,8 +155,8 @@ namespace SourceHook
static const x86_64_Reg rsi = { x8664Reg::RSI };
static const x86_64_Reg rdi = { x8664Reg::RDI };
static const x86_64_Reg r8 = { x8664Reg::R8 };
static const x86_64_Reg r9 = { x8664Reg::R9 };
static const x86_64_Reg r8 = { x8664Reg::R8 };
static const x86_64_Reg r9 = { x8664Reg::R9 };
static const x86_64_Reg r10 = { x8664Reg::R10 };
static const x86_64_Reg r11 = { x8664Reg::R11 };
static const x86_64_Reg r12 = { x8664Reg::R12 };

File diff suppressed because it is too large Load Diff

View File

@ -52,122 +52,6 @@ namespace SourceHook
virtual HookManagerPubFunc GetPubFunc() = 0;
};
class GenContext : public IGenContext
{
const static int SIZE_MWORD = 4;
const static int SIZE_PTR = sizeof(void*);
const static int PassFlag_ForcedByRef = (1<<30); // ByVal in source, but actually passed by reference (GCC) -> private pass, destruct
HookManagerPubFunc m_GeneratedPubFunc;
CProto m_OrigProto; // original passed-in prototype
CProto m_Proto;
int m_VtblOffs;
int m_VtblIdx;
ISourceHook *m_SHPtr;
Asm::GenBuffer m_HookFunc;
Asm::GenBuffer m_PubFunc;
ProtoInfo *m_BuiltPI;
PassInfo *m_BuiltPI_Params;
PassInfo::V2Info *m_BuiltPI_Params2;
// For hookfunc
void **m_pHI;
void **m_HookfuncVfnptr;
// Level 3 - Helpers
int m_RegCounter;
jit_int8_t NextRegEBX_ECX_EDX();
int m_BytesPushedAfterInitialAlignment;
enum AlignStackFlags
{
AlignStack_GCC_ThisOnStack = 1,
AlignStack_MSVC_ThisOnStack = 2,
AlignStack_MemRet = 4
};
jit_int32_t AlignStackBeforeCall(int paramsize, int flags);
void AlignStackAfterCall(jit_int32_t numofbytes);
void CheckAlignmentBeforeCall();
// size info
jit_int32_t GetRealSize(const IntPassInfo &info); // checks for reference
jit_int32_t AlignSize(jit_int32_t x, jit_int32_t boundary); // align a size
jit_int32_t GetParamStackSize(const IntPassInfo &info); // get the size of a param in the param stack
short GetParamsTotalStackSize(); // sum(GetParamStackSize(param[i]), 0 <= i < numOfParams)
// Helpers
void BitwiseCopy_Setup();
void BitwiseCopy_Do(size_t size);
// HookFunc frame
jit_int32_t m_HookFunc_FrameOffset;
jit_int32_t m_HookFunc_FrameVarsSize;
void ResetFrame(jit_int32_t startOffset);
jit_int32_t AddVarToFrame(jit_int32_t size);
jit_int32_t ComputeVarsSize();
// Param push
short GetForcedByRefParamsSize(); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < numOfParams)
short GetForcedByRefParamOffset(int p); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < p)
jit_int32_t PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to,
jit_int32_t v_place_for_memret, jit_int32_t v_place_fbrr_base); // save_ret_to and v_place_for_memret only used for memory returns
jit_int32_t PushRef(jit_int32_t param_offset, const IntPassInfo &pi);
jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi);
jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi);
jit_int32_t PushObject(jit_int32_t param_offset, const IntPassInfo &pi, jit_int32_t v_place_fbrr);
jit_int32_t PushMemRetPtr(jit_int32_t save_ret_to, jit_int32_t v_place_for_memret);
void DestroyParams(jit_int32_t fbrr_base);
// Ret val processing
void SaveRetVal(jit_int32_t v_where, jit_int32_t v_place_for_memret);
void ProcessPluginRetVal(jit_int32_t v_cur_res, jit_int32_t v_pContext, jit_int32_t v_plugin_ret);
void PrepareReturn(jit_int32_t v_status, jit_int32_t v_pContext, jit_int32_t v_retptr);
void DoReturn(jit_int32_t v_retptr, jit_int32_t v_memret_outaddr);
bool MemRetWithTempObj(); // do we do a memory return AND need a temporary place for it?
// Call hooks
void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter,
int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf);
// Call orig
void GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this,
int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf);
// Hook loop
void CallSetupHookLoop(int v_orig_ret, int v_override_ret,
int v_cur_res, int v_prev_res, int v_status, int v_vnfptr_origentry,
int v_this, int v_pContext);
void CallEndContext(int v_pContext);
// Level 2 -> called from Generate()
void AutoDetectRetType();
void AutoDetectParamFlags();
bool PassInfoSupported(const IntPassInfo &pi, bool is_ret);
void Clear();
void BuildProtoInfo();
void *GenerateHookFunc();
void *GeneratePubFunc();
HookManagerPubFunc Generate();
public:
// Level 1 -> Public interface
GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr);
virtual ~GenContext();
virtual bool Equal(const CProto &proto, int vtbl_offs, int vtbl_idx) override;
virtual bool Equal(HookManagerPubFunc other) override;
virtual HookManagerPubFunc GetPubFunc() override;
};
class CHookManagerAutoGen : public IHookManagerAutoGen
{
struct StoredContext

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,8 @@
#include <limits.h>
#include "sh_asm.h"
#undef REG_EAX
#undef REG_ECX
#undef REG_EDX
@ -194,7 +196,7 @@ namespace SourceHook
{
namespace Impl
{
typedef GenBuffer JitWriter;
typedef Asm::GenBuffer JitWriter;
inline jit_uint8_t ia32_modrm(jit_uint8_t mode, jit_uint8_t reg, jit_uint8_t rm)
{
@ -1605,6 +1607,121 @@ namespace SourceHook
jit->write_ubyte(IA32_CLD);
}
class GenContext : public IGenContext
{
const static int SIZE_MWORD = 4;
const static int SIZE_PTR = sizeof(void*);
const static int PassFlag_ForcedByRef = (1<<30); // ByVal in source, but actually passed by reference (GCC) -> private pass, destruct
HookManagerPubFunc m_GeneratedPubFunc;
CProto m_OrigProto; // original passed-in prototype
CProto m_Proto;
int m_VtblOffs;
int m_VtblIdx;
ISourceHook *m_SHPtr;
Asm::GenBuffer m_HookFunc;
Asm::GenBuffer m_PubFunc;
ProtoInfo *m_BuiltPI;
PassInfo *m_BuiltPI_Params;
PassInfo::V2Info *m_BuiltPI_Params2;
// For hookfunc
void **m_pHI;
void **m_HookfuncVfnptr;
// Level 3 - Helpers
int m_RegCounter;
jit_int8_t NextRegEBX_ECX_EDX();
int m_BytesPushedAfterInitialAlignment;
enum AlignStackFlags
{
AlignStack_GCC_ThisOnStack = 1,
AlignStack_MSVC_ThisOnStack = 2,
AlignStack_MemRet = 4
};
jit_int32_t AlignStackBeforeCall(int paramsize, int flags);
void AlignStackAfterCall(jit_int32_t numofbytes);
void CheckAlignmentBeforeCall();
// size info
jit_int32_t GetRealSize(const IntPassInfo &info); // checks for reference
jit_int32_t AlignSize(jit_int32_t x, jit_int32_t boundary); // align a size
jit_int32_t GetParamStackSize(const IntPassInfo &info); // get the size of a param in the param stack
short GetParamsTotalStackSize(); // sum(GetParamStackSize(param[i]), 0 <= i < numOfParams)
// Helpers
void BitwiseCopy_Setup();
void BitwiseCopy_Do(size_t size);
// HookFunc frame
jit_int32_t m_HookFunc_FrameOffset;
jit_int32_t m_HookFunc_FrameVarsSize;
void ResetFrame(jit_int32_t startOffset);
jit_int32_t AddVarToFrame(jit_int32_t size);
jit_int32_t ComputeVarsSize();
// Param push
short GetForcedByRefParamsSize(); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < numOfParams)
short GetForcedByRefParamOffset(int p); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < p)
jit_int32_t PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to,
jit_int32_t v_place_for_memret, jit_int32_t v_place_fbrr_base); // save_ret_to and v_place_for_memret only used for memory returns
jit_int32_t PushRef(jit_int32_t param_offset, const IntPassInfo &pi);
jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi);
jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi);
jit_int32_t PushObject(jit_int32_t param_offset, const IntPassInfo &pi, jit_int32_t v_place_fbrr);
jit_int32_t PushMemRetPtr(jit_int32_t save_ret_to, jit_int32_t v_place_for_memret);
void DestroyParams(jit_int32_t fbrr_base);
// Ret val processing
void SaveRetVal(jit_int32_t v_where, jit_int32_t v_place_for_memret);
void ProcessPluginRetVal(jit_int32_t v_cur_res, jit_int32_t v_pContext, jit_int32_t v_plugin_ret);
void PrepareReturn(jit_int32_t v_status, jit_int32_t v_pContext, jit_int32_t v_retptr);
void DoReturn(jit_int32_t v_retptr, jit_int32_t v_memret_outaddr);
bool MemRetWithTempObj(); // do we do a memory return AND need a temporary place for it?
// Call hooks
void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter,
int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf);
// Call orig
void GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this,
int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf);
// Hook loop
void CallSetupHookLoop(int v_orig_ret, int v_override_ret,
int v_cur_res, int v_prev_res, int v_status, int v_vnfptr_origentry,
int v_this, int v_pContext);
void CallEndContext(int v_pContext);
// Level 2 -> called from Generate()
void AutoDetectRetType();
void AutoDetectParamFlags();
bool PassInfoSupported(const IntPassInfo &pi, bool is_ret);
void Clear();
void BuildProtoInfo();
void *GenerateHookFunc();
void *GeneratePubFunc();
HookManagerPubFunc Generate();
public:
// Level 1 -> Public interface
GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr);
virtual ~GenContext();
virtual bool Equal(const CProto &proto, int vtbl_offs, int vtbl_idx) override;
virtual bool Equal(HookManagerPubFunc other) override;
virtual HookManagerPubFunc GetPubFunc() override;
};
}
}

View File

@ -44,8 +44,6 @@ using namespace SourceHook::Asm;
namespace SourceHook
{
CPageAlloc Asm::GenBuffer::ms_Allocator(16);
namespace Impl
{
void PrintDebug(x64JitWriter& jit, const char* message) {
@ -1431,60 +1429,5 @@ static_assert(false, "Missing auto-detect type for linux!");
{
return m_GeneratedPubFunc == other;
}
CHookManagerAutoGen::CHookManagerAutoGen(ISourceHook *pSHPtr) : m_pSHPtr(pSHPtr) { }
CHookManagerAutoGen::~CHookManagerAutoGen() { }
int CHookManagerAutoGen::GetIfaceVersion()
{
return SH_HOOKMANAUTOGEN_IFACE_VERSION;
}
int CHookManagerAutoGen::GetImplVersion()
{
return SH_HOOKMANAUTOGEN_IMPL_VERSION;
}
HookManagerPubFunc CHookManagerAutoGen::MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx)
{
CProto mproto(proto);
for (auto iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter)
{
if (iter->m_GenContext->Equal(mproto, vtbl_offs, vtbl_idx))
{
iter->m_RefCnt++;
return iter->m_GenContext->GetPubFunc();
}
}
// Not found yet -> new one
StoredContext sctx;
sctx.m_RefCnt = 1;
sctx.m_GenContext = std::make_unique<x64GenContext>(proto, vtbl_offs, vtbl_idx, m_pSHPtr);
auto pubFunc = sctx.m_GenContext->GetPubFunc();
if (pubFunc != nullptr)
{
m_Contexts.emplace_back(std::move(sctx));
}
return pubFunc;
}
void CHookManagerAutoGen::ReleaseHookMan(HookManagerPubFunc pubFunc)
{
for (auto iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter)
{
if (iter->m_GenContext->Equal(pubFunc))
{
iter->m_RefCnt--;
if (iter->m_RefCnt == 0)
{
iter = m_Contexts.erase(iter);
}
break;
}
}
}
}
}