1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2025-02-20 13:54:14 +01:00

New hookfunc local vars code; first step to vafmt support

--HG--
branch : hookman_autogen
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40562
This commit is contained in:
Pavol Marko 2007-11-17 09:53:58 +00:00
parent a81e661fa2
commit 784d474507
3 changed files with 90 additions and 36 deletions

View File

@ -19,6 +19,7 @@
#include "sourcehook_hookmangen.h"
#include "sourcehook_hookmangen_x86.h"
#include "sh_memory.h"
#include <stdarg.h> // we might need the address of vsnprintf
#if SH_COMP == SH_COMP_MSVC
# define GCC_ONLY(x)
@ -988,7 +989,7 @@ namespace SourceHook
// ECX = pContext
// gcc: push ecx
// eax = [ecx]
// eax = [eax + 3*PTR_SIZE]
// eax = [eax + 3*SIZE_PTR]
// call eax
// gcc: clean up
IA32_Mov_Reg_Rm_DispAuto(&m_HookFunc, REG_ECX, REG_EBP, v_pContext);
@ -1193,6 +1194,24 @@ namespace SourceHook
GCC_ONLY(IA32_Add_Rm_Imm8(&m_HookFunc, REG_ESP, 2*SIZE_PTR, MOD_REG));
}
void GenContext::ResetFrame(jit_int32_t startOffset)
{
m_HookFunc_FrameOffset = startOffset;
m_HookFunc_FrameVarsSize = 0;
}
jit_int32_t GenContext::AddVarToFrame(jit_int32_t size)
{
m_HookFunc_FrameOffset -= size;
m_HookFunc_FrameVarsSize += size;
return m_HookFunc_FrameOffset;
}
jit_int32_t GenContext::ComputeVarsSize()
{
return m_HookFunc_FrameVarsSize;
}
void * GenContext::GenerateHookFunc()
{
// prologue
@ -1200,19 +1219,21 @@ namespace SourceHook
IA32_Push_Reg(&m_HookFunc, REG_EBX);
IA32_Mov_Reg_Rm(&m_HookFunc, REG_EBP, REG_ESP, MOD_REG);
// on msvc, save thisptr
#if SH_COMP == SH_COMP_MSVC
jit_int8_t v_this = -4;
const int addstackoffset = -4;
jit_int32_t v_this = -4;
IA32_Push_Reg(&m_HookFunc, REG_ECX);
#elif SH_COMP == SH_COMP_GCC
jit_int8_t v_this = 12; // first param
const int addstackoffset = 0;
jit_int32_t v_this = 12; // first param
#endif
ResetFrame(
(SH_COMP==SH_COMP_MSVC) ? -4 : 0
); // on msvc, start on offset -4 because there already is the thisptr variable
// ********************** stack frame **********************
// MSVC
// MSVC
// second param (gcc: first real param) ebp + 16
// first param (gcc: thisptr) ebp + 12
// ret address: ebp + 8
@ -1227,26 +1248,33 @@ namespace SourceHook
// IHookContext *pContext ebp - 24 -4
// == 3 ptrs + 3 enums = 24 bytes
//
// varargs:
// va_list argptr ebp - 28 -4
//
// non-void: add:
// my_rettype *ret_ptr ebp - 28 -4
// my_rettype orig_ret ebp - 28 - sizeof(my_rettype) -4
// my_rettype override_ret ebp - 28 - sizeof(my_rettype)*2 -4
// my_rettype plugin_ret ebp - 28 - sizeof(my_rettype)*3 -4
// my_rettype *ret_ptr ebp - 28 (va: -4) -4
// my_rettype orig_ret ebp - 28 (va: -4) - sizeof(my_rettype) -4
// my_rettype override_ret ebp - 28 (va: -4) - sizeof(my_rettype)*2 -4
// my_rettype plugin_ret ebp - 28 (va: -4) - sizeof(my_rettype)*3 -4
// == + 3 * sizeof(my_rettype) bytes
// if required:
// my_rettype place_for_memret ebp - 28 - sizeof(my_rettype)*4 -4
// my_rettype place_for_memret ebp - 28 (va: -4) - sizeof(my_rettype)*4 -4
// gcc only: if required:
// place forced byref params ebp - 28 - sizeof(my_rettype)*{4 or 5}
// place forced byref params ebp - 28 (va: -4) - sizeof(my_rettype)*{4 or 5}
const jit_int8_t v_vfnptr_origentry = -4 + addstackoffset;
const jit_int8_t v_status = -8 + addstackoffset;
const jit_int8_t v_prev_res = -12 + addstackoffset;
const jit_int8_t v_cur_res = -16 + addstackoffset;
const jit_int8_t v_iter = -20 + addstackoffset;
const jit_int8_t v_pContext = -24 + addstackoffset;
const jit_int8_t v_vfnptr_origentry = AddVarToFrame(SIZE_PTR);
const jit_int8_t v_status = AddVarToFrame(sizeof(META_RES));
const jit_int8_t v_prev_res = AddVarToFrame(sizeof(META_RES));
const jit_int8_t v_cur_res = AddVarToFrame(sizeof(META_RES));
const jit_int8_t v_iter = AddVarToFrame(SIZE_PTR);
const jit_int8_t v_pContext = AddVarToFrame(SIZE_PTR);
// Only exists for varargs functions
const jit_int8_t v_va_argptr = (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs) ?
AddVarToFrame(sizeof(va_list)) :
0;
#if SH_COMP == SH_COMP_GCC
jit_int32_t param_base_offs = 16;
@ -1271,34 +1299,51 @@ namespace SourceHook
#endif
}
jit_int32_t v_ret_ptr = -28 + addstackoffset;
jit_int32_t v_orig_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 1;
jit_int32_t v_override_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 2;
jit_int32_t v_plugin_ret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 3;
jit_int32_t v_ret_ptr = 0;
jit_int32_t v_orig_ret = 0;
jit_int32_t v_override_ret = 0;
jit_int32_t v_plugin_ret = 0;
if (m_Proto.GetRet().size != 0)
{
v_ret_ptr = AddVarToFrame(SIZE_PTR);
v_orig_ret = AddVarToFrame(GetStackSize(m_Proto.GetRet()));
v_override_ret = AddVarToFrame(GetStackSize(m_Proto.GetRet()));
v_plugin_ret = AddVarToFrame(GetStackSize(m_Proto.GetRet()));
}
jit_int32_t v_place_for_memret = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * 4;
jit_int32_t v_place_for_memret = 0;
if (MemRetWithTempObj())
{
v_place_for_memret = AddVarToFrame(GetStackSize(m_Proto.GetRet()));
}
jit_int32_t v_place_fbrr_base = -28 + addstackoffset - GetStackSize(m_Proto.GetRet()) * (MemRetWithTempObj() ? 5 : 4);
jit_int32_t v_place_fbrr_base = 0;
if (GetForcedByRefParamsSize())
{
v_place_fbrr_base = AddVarToFrame(GetForcedByRefParamsSize());
}
// Hash for temporary storage for byval params with copy constructors
// (param, offset into stack)
short usedStackBytes = 3*SIZE_MWORD + 3*SIZE_PTR // vfnptr_origentry, status, prev_res, cur_res, iter, pContext
+ 3 * GetStackSize(m_Proto.GetRet()) + (m_Proto.GetRet().size == 0 ? 0 : SIZE_PTR) // ret_ptr, orig_ret, override_ret, plugin_ret
+ (MemRetWithTempObj() ? GetStackSize(m_Proto.GetRet()) : 0)
+ GetForcedByRefParamsSize()
- addstackoffset; // msvc: current thisptr
IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, usedStackBytes, MOD_REG);
IA32_Sub_Rm_Imm32(&m_HookFunc, REG_ESP, ComputeVarsSize(), MOD_REG);
// init status localvar
IA32_Mov_Rm_Imm32_Disp8(&m_HookFunc, REG_EBP, MRES_IGNORED, v_status);
// VarArgs: init argptr
if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVarArgs)
{
// argptr = first vararg param
// lea eax, [esp + param_base_offs + paramssize]
// mov argptr, eax
IA32_Lea_Reg_DispRegMultImm32(&m_HookFunc, REG_EAX, REG_NOIDX, REG_ESP, NOSCALE, param_base_offs + GetParamsStackSize());
IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, v_va_argptr, REG_EAX);
}
// Call constructors for ret vars if required
if((m_Proto.GetRet().flags & PassInfo::PassFlag_ByVal) &&
m_Proto.GetRet().pNormalCtor)
{
// :TODO: Gcc version
// orig_reg
IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_orig_ret);
GCC_ONLY(IA32_Push_Reg(&m_HookFunc, REG_ECX));

View File

@ -189,6 +189,15 @@ namespace SourceHook
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)

View File

@ -20,7 +20,7 @@ else
CFLAGS = $(OPT_FLAGS)
endif
CFLAGS += -Wall
CFLAGS += -Wall -Wno-non-virtual-dtor
# Also, enable SH_ASSERT
CFLAGS += -DSH_DEBUG