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

Fixed problems with object params on gcc when object has a destructor (forcedbyref)

--HG--
branch : hookman_autogen
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/branches/hookman_autogen%40571
This commit is contained in:
Pavol Marko 2007-11-23 15:09:36 +00:00
parent 07d38f007b
commit a0cbabed06
2 changed files with 28 additions and 23 deletions

View File

@ -126,21 +126,25 @@ namespace SourceHook
jit_int32_t GenContext::GetRealSize(const IntPassInfo &info)
{
if (info.flags & PassInfo::PassFlag_ByRef)
if (info.flags & (PassInfo::PassFlag_ByRef | PassFlag_ForcedByRef))
{
return SIZE_PTR;
}
return static_cast<jit_int32_t>(info.size);
}
jit_int32_t GenContext::AlignSize(jit_int32_t x, jit_int32_t boundary)
{
if (x % boundary != 0)
x = (x & ~(boundary-1)) + boundary;
return x;
}
// Computes size on the stack
jit_int32_t GenContext::GetStackSize(const IntPassInfo &info)
jit_int32_t GenContext::GetParamStackSize(const IntPassInfo &info)
{
// Align up to 4 byte boundaries
jit_int32_t rs = GetRealSize(info);
if (rs % 4 != 0)
rs = (rs & ~(3)) + 4;
return rs;
return AlignSize(GetRealSize(info), 4);
}
jit_int8_t GenContext::NextRegEBX_ECX_EDX()
@ -199,12 +203,12 @@ namespace SourceHook
IA32_Pop_Reg(&m_HookFunc, REG_EDI);
}
short GenContext::GetParamsStackSize()
short GenContext::GetParamsTotalStackSize()
{
short acc = 0;
for (int i = 0; i < m_Proto.GetNumOfParams(); ++i)
{
acc += GetStackSize(m_Proto.GetParam(i));
acc += GetParamStackSize(m_Proto.GetParam(i));
}
return acc;
@ -216,7 +220,7 @@ namespace SourceHook
for (int i = 0; i < p; ++i)
{
if (m_Proto.GetParam(i).flags & PassFlag_ForcedByRef)
off += GetStackSize(m_Proto.GetParam(i));
off += AlignSize(m_Proto.GetParam(i).size, 4);
}
return off;
}
@ -318,7 +322,7 @@ namespace SourceHook
{
// make room on the stack
// sub esp, <size>
IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, GetStackSize(pi), MOD_REG);
IA32_Sub_Rm_ImmAuto(&m_HookFunc, REG_ESP, GetParamStackSize(pi), MOD_REG);
}
// if there is a copy constructor..
@ -404,14 +408,14 @@ namespace SourceHook
jit_int32_t cur_offset = param_base_offset;
for (int i = 0; i < m_Proto.GetNumOfParams(); ++i)
{
cur_offset += GetStackSize(m_Proto.GetParam(i));
cur_offset += GetParamStackSize(m_Proto.GetParam(i));
}
// push parameters in reverse order
for (int i = m_Proto.GetNumOfParams() - 1; i >= 0; --i)
{
const IntPassInfo &pi = m_Proto.GetParam(i);
cur_offset -= GetStackSize(pi);
cur_offset -= GetParamStackSize(pi);
if (pi.flags & PassInfo::PassFlag_ByVal)
{
switch (pi.type)
@ -1351,15 +1355,15 @@ namespace SourceHook
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()));
v_orig_ret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet()));
v_override_ret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet()));
v_plugin_ret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet()));
}
jit_int32_t v_place_for_memret = 0;
if (MemRetWithTempObj())
{
v_place_for_memret = AddVarToFrame(GetStackSize(m_Proto.GetRet()));
v_place_for_memret = AddVarToFrame(GetParamStackSize(m_Proto.GetRet()));
}
jit_int32_t v_place_fbrr_base = 0;
@ -1393,7 +1397,7 @@ namespace SourceHook
// lea eax, [ebp + param_base_offs + paramssize]
// mov argptr, eax
IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_base_offs + GetParamsStackSize() + SIZE_PTR); // +SIZE_PTR: last const char * is not in protoinfo
IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_EAX, REG_EBP, param_base_offs + GetParamsTotalStackSize() + SIZE_PTR); // +SIZE_PTR: last const char * is not in protoinfo
IA32_Mov_Rm_Reg_DispAuto(&m_HookFunc, REG_EBP, REG_EAX, v_va_argptr);
}
if (m_Proto.GetConvention() & ProtoInfo::CallConv_HasVafmt)
@ -1402,7 +1406,7 @@ namespace SourceHook
// push valist, fmt param, maxsize, buffer
IA32_Push_Reg(&m_HookFunc, REG_EAX);
IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, param_base_offs + GetParamsStackSize()); // last given param (+4-4, see above)
IA32_Push_Rm_DispAuto(&m_HookFunc, REG_EBP, param_base_offs + GetParamsTotalStackSize()); // last given param (+4-4, see above)
IA32_Push_Imm32(&m_HookFunc, SourceHook::STRBUF_LEN - 1);
IA32_Lea_DispRegImmAuto(&m_HookFunc, REG_ECX, REG_EBP, v_va_buf);
IA32_Push_Reg(&m_HookFunc, REG_ECX);
@ -1482,7 +1486,7 @@ namespace SourceHook
IA32_Mov_Reg_Imm32(&m_HookFunc, REG_EAX, DownCastPtr(pi.pDtor));
IA32_Call_Reg(&m_HookFunc, REG_EAX);
}
cur_param_pos += GetStackSize(pi);
cur_param_pos += GetParamStackSize(pi);
}
DoReturn(v_ret_ptr, v_memret_addr);
@ -1527,7 +1531,7 @@ namespace SourceHook
// msvc without varargs:
// callee cleans the stack
short cleansize = GetParamsStackSize();
short cleansize = GetParamsTotalStackSize();
// Memory return: address is first param
if (m_Proto.GetRet().flags & PassInfo::PassFlag_RetMem)
cleansize += SIZE_PTR;

View File

@ -181,9 +181,10 @@ namespace SourceHook
jit_int8_t NextRegEBX_ECX_EDX();
// size info
jit_int32_t GetRealSize(const IntPassInfo &info);
jit_int32_t GetStackSize(const IntPassInfo &info);
short GetParamsStackSize(); // sum(GetStackSize(param[i]), 0 <= i < numOfParams)
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();