mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-12-09 19:38:29 +00:00
The pain begins
This commit is contained in:
parent
dc41559c79
commit
57929cabcf
@ -41,7 +41,7 @@ for sdk_target in MMS.sdk_targets:
|
|||||||
|
|
||||||
if cxx.target.arch == 'x86':
|
if cxx.target.arch == 'x86':
|
||||||
binary.sources += ['sourcehook/sourcehook_hookmangen_x86.cpp']
|
binary.sources += ['sourcehook/sourcehook_hookmangen_x86.cpp']
|
||||||
elif binary.compiler.target.arch == 'x86_64' and binary.compiler.target.platform != 'linux':
|
elif binary.compiler.target.arch == 'x86_64':
|
||||||
binary.sources += ['sourcehook/sourcehook_hookmangen_x86_64.cpp']
|
binary.sources += ['sourcehook/sourcehook_hookmangen_x86_64.cpp']
|
||||||
nodes = builder.Add(binary)
|
nodes = builder.Add(binary)
|
||||||
MMS.binaries += [nodes]
|
MMS.binaries += [nodes]
|
||||||
|
|||||||
@ -84,9 +84,7 @@ static MetamodSourceConVar *mm_basedir = NULL;
|
|||||||
static CreateInterfaceFn engine_factory = NULL;
|
static CreateInterfaceFn engine_factory = NULL;
|
||||||
static CreateInterfaceFn physics_factory = NULL;
|
static CreateInterfaceFn physics_factory = NULL;
|
||||||
static CreateInterfaceFn filesystem_factory = NULL;
|
static CreateInterfaceFn filesystem_factory = NULL;
|
||||||
#if !defined( __amd64__ )
|
|
||||||
static CHookManagerAutoGen g_SH_HookManagerAutoGen(&g_SourceHook);
|
static CHookManagerAutoGen g_SH_HookManagerAutoGen(&g_SourceHook);
|
||||||
#endif
|
|
||||||
static META_RES last_meta_res;
|
static META_RES last_meta_res;
|
||||||
static IServerPluginCallbacks *vsp_callbacks = NULL;
|
static IServerPluginCallbacks *vsp_callbacks = NULL;
|
||||||
static bool were_plugins_loaded = false;
|
static bool were_plugins_loaded = false;
|
||||||
@ -846,7 +844,6 @@ void *MetamodSource::MetaFactory(const char *iface, int *ret, PluginId *id)
|
|||||||
}
|
}
|
||||||
return static_cast<void *>(static_cast<ISmmPluginManager *>(&g_PluginMngr));
|
return static_cast<void *>(static_cast<ISmmPluginManager *>(&g_PluginMngr));
|
||||||
}
|
}
|
||||||
#if !defined( __amd64__ )
|
|
||||||
else if (strcmp(iface, MMIFACE_SH_HOOKMANAUTOGEN) == 0)
|
else if (strcmp(iface, MMIFACE_SH_HOOKMANAUTOGEN) == 0)
|
||||||
{
|
{
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -855,7 +852,7 @@ void *MetamodSource::MetaFactory(const char *iface, int *ret, PluginId *id)
|
|||||||
}
|
}
|
||||||
return static_cast<void *>(static_cast<SourceHook::IHookManagerAutoGen *>(&g_SH_HookManagerAutoGen));
|
return static_cast<void *>(static_cast<SourceHook::IHookManagerAutoGen *>(&g_SH_HookManagerAutoGen));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
CPluginManager::CPlugin *pl;
|
CPluginManager::CPlugin *pl;
|
||||||
List<IMetamodListener *>::iterator event;
|
List<IMetamodListener *>::iterator event;
|
||||||
IMetamodListener *api;
|
IMetamodListener *api;
|
||||||
|
|||||||
@ -464,7 +464,8 @@ namespace SourceHook
|
|||||||
this->write_int32(imm);
|
this->write_int32(imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xor(x86_64_Reg dst, x86_64_Reg src) {
|
// can't name it `xor` because that's a C++ keyword (it works in VS tho but not clang)
|
||||||
|
void xor_reg(x86_64_Reg dst, x86_64_Reg src) {
|
||||||
this->write_ubyte(w_rex(src, dst));
|
this->write_ubyte(w_rex(src, dst));
|
||||||
this->write_ubyte(0x31);
|
this->write_ubyte(0x31);
|
||||||
this->write_ubyte(modrm(src, dst));
|
this->write_ubyte(modrm(src, dst));
|
||||||
|
|||||||
@ -238,7 +238,10 @@ namespace SourceHook
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Detect the pass flags (if they're missing) for return and parameters type
|
// Detect the pass flags (if they're missing) for return and parameters type
|
||||||
AutoDetectRetType();
|
if (!AutoDetectRetType())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
AutoDetectParamFlags();
|
AutoDetectParamFlags();
|
||||||
|
|
||||||
// Calling conventions are gone on x86_64, there's only one to call all functions
|
// Calling conventions are gone on x86_64, there's only one to call all functions
|
||||||
@ -596,7 +599,7 @@ static_assert(false, "Missing parameters destruction for linux");
|
|||||||
if (m_Proto.GetRet().size == 0) // void return function
|
if (m_Proto.GetRet().size == 0) // void return function
|
||||||
{
|
{
|
||||||
// nullptr
|
// nullptr
|
||||||
m_HookFunc.xor(rax, rax);
|
m_HookFunc.xor_reg(rax, rax);
|
||||||
// 9th argument - const void* origRetPtr
|
// 9th argument - const void* origRetPtr
|
||||||
MSVC_ONLY(m_HookFunc.mov(rsp(0x40), rax));
|
MSVC_ONLY(m_HookFunc.mov(rsp(0x40), rax));
|
||||||
// 10th argument - void* overrideRetPtr
|
// 10th argument - void* overrideRetPtr
|
||||||
@ -1112,7 +1115,7 @@ static_assert(false, "Missing registers saving for linux");
|
|||||||
m_HookFunc.mov(rax, rax(getOrigRetPtrMfi.vtblindex * SIZE_PTR));
|
m_HookFunc.mov(rax, rax(getOrigRetPtrMfi.vtblindex * SIZE_PTR));
|
||||||
m_HookFunc.mov(r8, r8(getOverrideRetPtrMfi.vtblindex * SIZE_PTR));
|
m_HookFunc.mov(r8, r8(getOverrideRetPtrMfi.vtblindex * SIZE_PTR));
|
||||||
|
|
||||||
m_HookFunc.xor(r9, r9);
|
m_HookFunc.xor_reg(r9, r9);
|
||||||
m_HookFunc.mov(r9, rbp(v_status));
|
m_HookFunc.mov(r9, rbp(v_status));
|
||||||
m_HookFunc.cmp(r9, MRES_OVERRIDE);
|
m_HookFunc.cmp(r9, MRES_OVERRIDE);
|
||||||
|
|
||||||
@ -1236,11 +1239,11 @@ static_assert(false, "Missing registers saving for linux");
|
|||||||
&& (retInfo.flags & (PassInfo::PassFlag_ODtor | PassInfo::PassFlag_AssignOp)));
|
&& (retInfo.flags & (PassInfo::PassFlag_ODtor | PassInfo::PassFlag_AssignOp)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void x64GenContext::AutoDetectRetType() {
|
bool x64GenContext::AutoDetectRetType() {
|
||||||
auto& pi = m_Proto.GetRet();
|
auto& pi = m_Proto.GetRet();
|
||||||
// Void return, ignore
|
// Void return, ignore
|
||||||
if (pi.size == 0) {
|
if (pi.size == 0) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only relevant for byval types
|
// Only relevant for byval types
|
||||||
@ -1283,7 +1286,24 @@ static_assert(false, "Missing registers saving for linux");
|
|||||||
pi.flags |= PassInfo::PassFlag_RetReg;
|
pi.flags |= PassInfo::PassFlag_RetReg;
|
||||||
}
|
}
|
||||||
#elif SH_COMP == SH_COMP_GCC
|
#elif SH_COMP == SH_COMP_GCC
|
||||||
static_assert(false, "Missing auto-detect type for linux!");
|
// It depends on the object layout.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// typedef struct __attribute__((packed)) { char a; int b; } thing;
|
||||||
|
// = memory (5 bytes)
|
||||||
|
//
|
||||||
|
// typedef struct __attribute__((packed)) { int a; char b; } thing;
|
||||||
|
// = register (5 bytes)
|
||||||
|
//
|
||||||
|
// typedef struct __attribute__((packed)) { char a; short b; char c; } thing;
|
||||||
|
// = memory (6 bytes)
|
||||||
|
//
|
||||||
|
// typedef struct __attribute__((packed)) { char a; short b; int c; char d; } thing;
|
||||||
|
// = memory (8 bytes)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Result: we cannot detect if it should be register or memory without knowing the layout of the object.
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1294,6 +1314,7 @@ static_assert(false, "Missing auto-detect type for linux!");
|
|||||||
pi.flags &= ~PassInfo::PassFlag_RetMem;
|
pi.flags &= ~PassInfo::PassFlag_RetMem;
|
||||||
pi.flags |= PassInfo::PassFlag_RetReg;
|
pi.flags |= PassInfo::PassFlag_RetReg;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void x64GenContext::AutoDetectParamFlags()
|
void x64GenContext::AutoDetectParamFlags()
|
||||||
@ -1402,7 +1423,7 @@ static_assert(false, "Missing auto-detect type for linux!");
|
|||||||
GCC_ONLY(m_PubFunc.pop(rbp));
|
GCC_ONLY(m_PubFunc.pop(rbp));
|
||||||
|
|
||||||
// Return 0
|
// Return 0
|
||||||
m_PubFunc.xor(rax, rax);
|
m_PubFunc.xor_reg(rax, rax);
|
||||||
|
|
||||||
m_PubFunc.retn();
|
m_PubFunc.retn();
|
||||||
|
|
||||||
|
|||||||
@ -38,12 +38,12 @@ namespace SourceHook
|
|||||||
|
|
||||||
std::int32_t AddVarToFrame(std::int32_t size);
|
std::int32_t AddVarToFrame(std::int32_t size);
|
||||||
std::int32_t ComputeVarsSize();
|
std::int32_t ComputeVarsSize();
|
||||||
std::int32_t x64GenContext::GetRealSize(const IntPassInfo& info);
|
std::int32_t GetRealSize(const IntPassInfo& info);
|
||||||
std::int32_t AlignSize(std::int32_t x, std::int32_t boundary);
|
std::int32_t AlignSize(std::int32_t x, std::int32_t boundary);
|
||||||
std::int32_t GetParamStackSize(const IntPassInfo &info);
|
std::int32_t GetParamStackSize(const IntPassInfo &info);
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void AutoDetectRetType();
|
bool AutoDetectRetType();
|
||||||
void AutoDetectParamFlags();
|
void AutoDetectParamFlags();
|
||||||
bool PassInfoSupported(const IntPassInfo& pi, bool is_ret);
|
bool PassInfoSupported(const IntPassInfo& pi, bool is_ret);
|
||||||
void BuildProtoInfo();
|
void BuildProtoInfo();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user