added new function calling module, wow
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40745
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* ===============================================================
|
||||
* SourceMod, Copyright (C) 2004-2007 AlliedModders LLC.
|
||||
* All rights reserved.
|
||||
* ===============================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK. This file may only be
|
||||
* used or modified under the Terms and Conditions of its License Agreement,
|
||||
* which is found in public/licenses/LICENSE.txt. As of this notice, derivative
|
||||
* works must be licensed under the GNU General Public License (version 2 or
|
||||
* greater). A copy of the GPL is included under public/licenses/GPL.txt.
|
||||
*
|
||||
* To view the latest information, see: http://www.sourcemod.net/license.php
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SMEXT_BINTOOLS_H_
|
||||
#define _INCLUDE_SMEXT_BINTOOLS_H_
|
||||
|
||||
#include <IShareSys.h>
|
||||
|
||||
#define SMINTERFACE_BINTOOLS_NAME "IBinTools"
|
||||
#define SMINTERFACE_BINTOOLS_VERSION 1
|
||||
|
||||
/**
|
||||
* @brief Function calling encoding utilities
|
||||
* @file IBinTools.h
|
||||
*/
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
/**
|
||||
* @brief Supported calling conventions
|
||||
*/
|
||||
enum CallConvention
|
||||
{
|
||||
CallConv_ThisCall, /**< This call (object pointer required) */
|
||||
CallConv_Cdecl, /**< Standard C call */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Describes how a parameter should be passed
|
||||
*/
|
||||
enum PassType
|
||||
{
|
||||
PassType_Basic, /**< Plain old register data (pointers, integers) */
|
||||
PassType_Float, /**< Floating point data */
|
||||
PassType_Object, /**< Object or structure */
|
||||
};
|
||||
|
||||
#define PASSFLAG_BYVAL (1<<0) /**< Passing by value */
|
||||
#define PASSFLAG_BYREF (1<<1) /**< Passing by reference */
|
||||
#define PASSFLAG_ODTOR (1<<2) /**< Object has a destructor */
|
||||
#define PASSFLAG_OCTOR (1<<3) /**< Object has a constructor */
|
||||
#define PASSFLAG_OASSIGNOP (1<<4) /**< Object has an assignment operator */
|
||||
|
||||
/**
|
||||
* @brief Parameter passing information
|
||||
*/
|
||||
struct PassInfo
|
||||
{
|
||||
PassType type; /**< PassType value */
|
||||
unsigned int flags; /**< Pass/return flags */
|
||||
size_t size; /**< Size of the data being passed */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parameter encoding information
|
||||
*/
|
||||
struct PassEncode
|
||||
{
|
||||
PassInfo info; /**< Parameter information */
|
||||
size_t offset; /**< Offset into the virtual stack */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Wraps a C/C++ call.
|
||||
*/
|
||||
class ICallWrapper
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Returns the calling convention.
|
||||
*
|
||||
* @return CallConvention value.
|
||||
*/
|
||||
virtual CallConvention GetCallConvention() =0;
|
||||
|
||||
/**
|
||||
* @brief Returns parameter info.
|
||||
*
|
||||
* @param num Parameter number to get (starting from 0).
|
||||
* @return A PassInfo pointer.
|
||||
*/
|
||||
virtual const PassEncode *GetParamInfo(unsigned int num) =0;
|
||||
|
||||
/**
|
||||
* @brief Returns return type info.
|
||||
*
|
||||
* @return A PassInfo pointer.
|
||||
*/
|
||||
virtual const PassInfo *GetReturnInfo() =0;
|
||||
|
||||
/**
|
||||
* @brief Returns the number of parameters.
|
||||
*/
|
||||
virtual unsigned int GetParamCount() =0;
|
||||
|
||||
/**
|
||||
* @brief Execute the contained function.
|
||||
*/
|
||||
virtual void Execute(void *vParamStack, void *retBuffer) =0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Binary tools interface.
|
||||
*/
|
||||
class IBinTools : public SMInterface
|
||||
{
|
||||
public:
|
||||
virtual const char *GetInterfaceName()
|
||||
{
|
||||
return SMINTERFACE_BINTOOLS_NAME;
|
||||
}
|
||||
virtual unsigned int GetInterfaceVersion()
|
||||
{
|
||||
return SMINTERFACE_BINTOOLS_VERSION;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* @brief Creates a call decoder.
|
||||
*
|
||||
* Note: CallConv_ThisCall requires an implicit first parameter
|
||||
* of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However,
|
||||
* this should only be given to the Execute() function, and never
|
||||
* listed in the paramInfo array.
|
||||
*
|
||||
* @param address Address to use as a call.
|
||||
* @param cv Calling convention.
|
||||
* @param retInfo Return type information, or NULL for void.
|
||||
* @param paramInfo Array of parameters.
|
||||
* @param numParams Number of parameters in the array.
|
||||
* @return A new ICallWrapper function.
|
||||
*/
|
||||
virtual ICallWrapper *CreateCall(void *address,
|
||||
CallConvention cv,
|
||||
const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[],
|
||||
unsigned int numParams) =0;
|
||||
|
||||
/**
|
||||
* @brief Creates a vtable call decoder.
|
||||
*
|
||||
* Note: CallConv_ThisCall requires an implicit first parameter
|
||||
* of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However,
|
||||
* this should only be given to the Execute() function, and never
|
||||
* listed in the paramInfo array.
|
||||
*
|
||||
* @param vtblIdx Index into the virtual table.
|
||||
* @param vtblOffs Offset of the virtual table.
|
||||
* @param thisOffs Offset of the this pointer of the virtual table.
|
||||
* @param retInfo Return type information, or NULL for void.
|
||||
* @param paramInfo Array of parameters.
|
||||
* @param numParams Number of parameters in the array.
|
||||
* @return A new ICallWrapper function.
|
||||
*/
|
||||
virtual ICallWrapper *CreateVCall(unsigned int vtblIdx,
|
||||
unsigned int vtblOffs,
|
||||
unsigned int thisOffs,
|
||||
const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[],
|
||||
unsigned int numParams) =0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //_INCLUDE_SMEXT_BINTOOLS_H_
|
||||
@@ -92,6 +92,8 @@
|
||||
#define IA32_MOV_RM8_REG 0x88 // encoding is /r
|
||||
#define IA32_MOV_RM_REG 0x89 // encoding is /r
|
||||
#define IA32_MOV_REG_MEM 0x8B // encoding is /r
|
||||
#define IA32_MOV_REG8_RM8 0x8A // encoding is /r
|
||||
#define IA32_MOV_RM8_REG8 0x88 // encoding is /r
|
||||
#define IA32_MOV_RM_IMM32 0xC7 // encoding is /0
|
||||
#define IA32_CMP_RM_IMM32 0x81 // encoding is /7 <imm32>
|
||||
#define IA32_CMP_RM_IMM8 0x83 // encoding is /7 <imm8>
|
||||
@@ -149,6 +151,10 @@
|
||||
#define IA32_POPAD 0x61 // no extra encoding
|
||||
#define IA32_NOP 0x90 // no extra encoding
|
||||
#define IA32_INT3 0xCC // no extra encoding
|
||||
#define IA32_FSTP_MEM32 0xD9 // encoding is /3
|
||||
#define IA32_FSTP_MEM64 0xDD // encoding is /3
|
||||
#define IA32_FLD_MEM32 0xD9 // encoding is /0
|
||||
#define IA32_FLD_MEM64 0xDD // encoding is /0
|
||||
|
||||
inline jit_uint8_t ia32_modrm(jit_uint8_t mode, jit_uint8_t reg, jit_uint8_t rm)
|
||||
{
|
||||
@@ -629,6 +635,19 @@ inline void IA32_Lea_Reg_DispRegMultImm8(JitWriter *jit,
|
||||
jit->write_byte(val);
|
||||
}
|
||||
|
||||
inline void IA32_Lea_Reg_DispRegMultImm32(JitWriter *jit,
|
||||
jit_uint8_t dest,
|
||||
jit_uint8_t src_base,
|
||||
jit_uint8_t src_index,
|
||||
jit_uint8_t scale,
|
||||
jit_int32_t val)
|
||||
{
|
||||
jit->write_ubyte(IA32_LEA_REG_MEM);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, REG_SIB));
|
||||
jit->write_ubyte(ia32_sib(scale, src_index, src_base));
|
||||
jit->write_int32(val);
|
||||
}
|
||||
|
||||
inline void IA32_Lea_Reg_RegMultImm32(JitWriter *jit,
|
||||
jit_uint8_t dest,
|
||||
jit_uint8_t src_index,
|
||||
@@ -716,6 +735,12 @@ inline void IA32_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, j
|
||||
jit->write_ubyte(ia32_modrm(mode, dest, src));
|
||||
}
|
||||
|
||||
inline void IA32_Mov_Reg8_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(IA32_MOV_REG8_RM8);
|
||||
jit->write_ubyte(ia32_modrm(mode, dest, src));
|
||||
}
|
||||
|
||||
inline void IA32_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(IA32_MOV_REG_MEM);
|
||||
@@ -723,6 +748,13 @@ inline void IA32_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void IA32_Mov_Reg8_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(IA32_MOV_REG8_RM8);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void IA32_Mov_Reg_Esp_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(IA32_MOV_REG_MEM);
|
||||
@@ -738,6 +770,13 @@ inline void IA32_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t
|
||||
jit->write_int32(disp);
|
||||
}
|
||||
|
||||
inline void IA32_Mov_Reg8_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
jit->write_ubyte(IA32_MOV_REG8_RM8);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src));
|
||||
jit->write_int32(disp);
|
||||
}
|
||||
|
||||
inline void IA32_Mov_Reg_Rm_Disp_Reg(JitWriter *jit,
|
||||
jit_uint8_t dest,
|
||||
jit_uint8_t src_base,
|
||||
@@ -784,6 +823,12 @@ inline void IA32_Mov_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, j
|
||||
jit->write_ubyte(ia32_modrm(mode, src, dest));
|
||||
}
|
||||
|
||||
inline void IA32_Mov_Rm8_Reg8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(IA32_MOV_RM8_REG8);
|
||||
jit->write_ubyte(ia32_modrm(mode, src, dest));
|
||||
}
|
||||
|
||||
inline void IA32_Mov_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(IA32_MOV_RM_REG);
|
||||
@@ -890,6 +935,52 @@ inline void IA32_Mov_RmEBP_Imm32_Disp_Reg(JitWriter *jit,
|
||||
jit->write_int32(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Floating Point Instructions
|
||||
*/
|
||||
|
||||
inline void IA32_Fstp_Mem32(JitWriter *jit, jit_uint8_t dest_base, jit_uint8_t dest_index, jit_uint8_t dest_scale)
|
||||
{
|
||||
jit->write_ubyte(IA32_FSTP_MEM32);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB));
|
||||
jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
|
||||
}
|
||||
|
||||
inline void IA32_Fstp_Mem64(JitWriter *jit, jit_uint8_t dest_base, jit_uint8_t dest_index, jit_uint8_t dest_scale)
|
||||
{
|
||||
jit->write_ubyte(IA32_FSTP_MEM64);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 3, REG_SIB));
|
||||
jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
|
||||
}
|
||||
|
||||
inline void IA32_Fld_Mem32_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t val)
|
||||
{
|
||||
jit->write_ubyte(IA32_FLD_MEM32);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
|
||||
jit->write_byte(val);
|
||||
}
|
||||
|
||||
inline void IA32_Fld_Mem64_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t val)
|
||||
{
|
||||
jit->write_ubyte(IA32_FLD_MEM64);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
|
||||
jit->write_byte(val);
|
||||
}
|
||||
|
||||
inline void IA32_Fld_Mem32_Disp32(JitWriter *jit, jit_uint8_t dest, jit_int32_t val)
|
||||
{
|
||||
jit->write_ubyte(IA32_FLD_MEM32);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest));
|
||||
jit->write_int32(val);
|
||||
}
|
||||
|
||||
inline void IA32_Fld_Mem64_Disp32(JitWriter *jit, jit_uint8_t dest, jit_int32_t val)
|
||||
{
|
||||
jit->write_ubyte(IA32_FLD_MEM64);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest));
|
||||
jit->write_int32(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Branching/Jumping
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user