1.1 --- a/extensions/bintools/CallMaker.cpp Wed Jan 07 22:55:40 2009 -0500
1.2 +++ b/extensions/bintools/CallMaker.cpp Thu Jan 08 18:17:17 2009 +1300
1.3 @@ -29,9 +29,54 @@
1.4 * Version: $Id$
1.5 */
1.6
1.7 +#include <stdio.h>
1.8 #include "CallMaker.h"
1.9 -#include "CallWrapper.h"
1.10 -#include "jit_call.h"
1.11 +#include "jit_compile.h"
1.12 +#include "extension.h"
1.13 +
1.14 +/* SourceMod <==> SourceHook type conversion functions */
1.15 +
1.16 +SourceHook::ProtoInfo::CallConvention GetSHCallConvention(SourceMod::CallConvention cv)
1.17 +{
1.18 + if (cv < SourceMod::CallConv_ThisCall || cv > SourceMod::CallConv_Cdecl)
1.19 + {
1.20 + return SourceHook::ProtoInfo::CallConv_Unknown;
1.21 + }
1.22 +
1.23 + return (SourceHook::ProtoInfo::CallConvention)(cv + 1);
1.24 +}
1.25 +
1.26 +SourceMod::CallConvention GetSMCallConvention(SourceHook::ProtoInfo::CallConvention cv)
1.27 +{
1.28 + assert(cv >= SourceHook::ProtoInfo::CallConv_ThisCall || cv <= SourceHook::ProtoInfo::CallConv_Cdecl);
1.29 +
1.30 + return (SourceMod::CallConvention)(cv - 1);
1.31 +}
1.32 +
1.33 +SourceHook::PassInfo::PassType GetSHPassType(SourceMod::PassType type)
1.34 +{
1.35 + if (type < SourceMod::PassType_Basic || type > SourceMod::PassType_Object)
1.36 + {
1.37 + return SourceHook::PassInfo::PassType_Unknown;
1.38 + }
1.39 +
1.40 + return (SourceHook::PassInfo::PassType)(type + 1);
1.41 +}
1.42 +
1.43 +SourceMod::PassType GetSMPassType(int type)
1.44 +{
1.45 + /* SourceMod doesn't provide an Unknown type so we it must be an error */
1.46 + assert(type >= SourceHook::PassInfo::PassType_Basic && type <= SourceHook::PassInfo::PassType_Object);
1.47 +
1.48 + return (SourceMod::PassType)(type - 1);
1.49 +}
1.50 +
1.51 +void GetSMPassInfo(SourceMod::PassInfo *out, const SourceHook::PassInfo *in)
1.52 +{
1.53 + out->size = in->size;
1.54 + out->flags = in->flags;
1.55 + out->type = GetSMPassType(in->type);
1.56 +}
1.57
1.58 ICallWrapper *CallMaker::CreateCall(void *address,
1.59 CallConvention cv,
1.60 @@ -39,12 +84,26 @@
1.61 const PassInfo paramInfo[],
1.62 unsigned int numParams)
1.63 {
1.64 - CallWrapper *pWrapper = new CallWrapper(cv, paramInfo, retInfo, numParams);
1.65 - pWrapper->m_Addrs[ADDR_CALLEE] = address;
1.66 + SourceHook::CProtoInfoBuilder protoInfo(GetSHCallConvention(cv));
1.67 +
1.68 + for (unsigned int i=0; i<numParams; i++)
1.69 + {
1.70 + protoInfo.AddParam(paramInfo[i].size, GetSHPassType(paramInfo[i].type), paramInfo[i].flags,
1.71 + NULL, NULL, NULL, NULL);
1.72 + }
1.73
1.74 - JIT_Compile(pWrapper, FuncAddr_Direct);
1.75 + if (retInfo)
1.76 + {
1.77 + protoInfo.SetReturnType(retInfo->size, GetSHPassType(retInfo->type), retInfo->flags,
1.78 + NULL, NULL, NULL, NULL);
1.79 + }
1.80 + else
1.81 + {
1.82 + protoInfo.SetReturnType(0, SourceHook::PassInfo::PassType_Unknown, 0,
1.83 + NULL, NULL, NULL, NULL);
1.84 + }
1.85
1.86 - return pWrapper;
1.87 + return g_CallMaker2.CreateCall(address, &(*protoInfo));
1.88 }
1.89
1.90 ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
1.91 @@ -54,12 +113,73 @@
1.92 const PassInfo paramInfo[],
1.93 unsigned int numParams)
1.94 {
1.95 - CallWrapper *pWrapper = new CallWrapper(CallConv_ThisCall, paramInfo, retInfo, numParams);
1.96 - pWrapper->m_VtInfo.thisOffs = thisOffs;
1.97 - pWrapper->m_VtInfo.vtblIdx = vtblIdx;
1.98 - pWrapper->m_VtInfo.vtblOffs = vtblOffs;
1.99 + SourceHook::MemFuncInfo info;
1.100 + info.isVirtual = true;
1.101 + info.vtblindex = vtblIdx;
1.102 + info.vtbloffs = vtblOffs;
1.103 + info.thisptroffs = thisOffs;
1.104 +
1.105 + SourceHook::CProtoInfoBuilder protoInfo(SourceHook::ProtoInfo::CallConv_ThisCall);
1.106 +
1.107 + for (unsigned int i=0; i<numParams; i++)
1.108 + {
1.109 + protoInfo.AddParam(paramInfo[i].size, GetSHPassType(paramInfo[i].type), paramInfo[i].flags,
1.110 + NULL, NULL, NULL, NULL);
1.111 + }
1.112
1.113 - JIT_Compile(pWrapper, FuncAddr_VTable);
1.114 + if (retInfo)
1.115 + {
1.116 + protoInfo.SetReturnType(retInfo->size, GetSHPassType(retInfo->type), retInfo->flags,
1.117 + NULL, NULL, NULL, NULL);
1.118 + }
1.119 + else
1.120 + {
1.121 + protoInfo.SetReturnType(0, SourceHook::PassInfo::PassType_Unknown, 0,
1.122 + NULL, NULL, NULL, NULL);
1.123 + }
1.124 +
1.125 +
1.126 + return g_CallMaker2.CreateVirtualCall(&(*protoInfo), &info);
1.127 +}
1.128 +
1.129 +ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo)
1.130 +{
1.131 + CallWrapper *pWrapper = new CallWrapper(protoInfo);
1.132 + pWrapper->SetCalleeAddr(address);
1.133 +
1.134 + void *addr = JIT_CallCompile(pWrapper, FuncAddr_Direct);
1.135 + pWrapper->SetCodeBaseAddr(addr);
1.136
1.137 return pWrapper;
1.138 }
1.139 +
1.140 +ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
1.141 + const SourceHook::MemFuncInfo *info)
1.142 +{
1.143 + CallWrapper *pWrapper = new CallWrapper(protoInfo);
1.144 + pWrapper->SetMemFuncInfo(info);
1.145 +
1.146 + void *addr = JIT_CallCompile(pWrapper, FuncAddr_VTable);
1.147 + pWrapper->SetCodeBaseAddr(addr);
1.148 +
1.149 + return pWrapper;
1.150 +}
1.151 +
1.152 +#if defined HOOKING_ENABLED
1.153 +IHookWrapper *CallMaker2::CreateVirtualHook(SourceHook::ISourceHook *pSH,
1.154 + const SourceHook::ProtoInfo *protoInfo,
1.155 + const SourceHook::MemFuncInfo *info,
1.156 + VIRTUAL_HOOK_PROTO f)
1.157 +{
1.158 + HookWrapper *pWrapper = new HookWrapper(pSH, protoInfo, const_cast<SourceHook::MemFuncInfo *>(info), (void *)f);
1.159 +
1.160 + void *addr = JIT_HookCompile(pWrapper);
1.161 + pWrapper->SetHookWrpAddr(addr);
1.162 +
1.163 + ICallWrapper *callWrap = CreateVirtualCall(protoInfo, info);
1.164 + pWrapper->SetCallWrapperAddr(callWrap);
1.165 +
1.166 + return pWrapper;
1.167 +}
1.168 +#endif
1.169 +