extensions/bintools/CallMaker.cpp
changeset 2504 74fea7db93e4
parent 2289 44045ead61cd
     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 +