Imported Upstream version 4.20.9608-rtm
This commit is contained in:
404
src/See/jitter.h
Normal file
404
src/See/jitter.h
Normal file
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
* Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||
* Copyright (c) 2005 CACE Technologies, Davis (California)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/** @ingroup NPF
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup NPF_include NPF structures and definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
//
|
||||
// Registers
|
||||
//
|
||||
#define EAX 0
|
||||
#define ECX 1
|
||||
#define EDX 2
|
||||
#define EBX 3
|
||||
#define ESP 4
|
||||
#define EBP 5
|
||||
#define ESI 6
|
||||
#define EDI 7
|
||||
|
||||
#define AX 0
|
||||
#define CX 1
|
||||
#define DX 2
|
||||
#define BX 3
|
||||
#define SP 4
|
||||
#define BP 5
|
||||
#define SI 6
|
||||
#define DI 7
|
||||
|
||||
#define AL 0
|
||||
#define CL 1
|
||||
#define DL 2
|
||||
#define BL 3
|
||||
|
||||
/*! \brief A stream of X86 binary code.*/
|
||||
typedef struct binary_stream{
|
||||
INT cur_ip; ///< Current X86 instruction pointer.
|
||||
INT bpf_pc; ///< Current BPF instruction pointer, i.e. position in the BPF program reached by the jitter.
|
||||
PCHAR ibuf; ///< Instruction buffer, contains the X86 generated code.
|
||||
PUINT refs; ///< Jumps reference table.
|
||||
}binary_stream;
|
||||
|
||||
|
||||
/*! \brief Prototype of a filtering function created by the jitter.
|
||||
|
||||
The syntax and the meaning of the parameters is analogous to the one of bpf_filter(). Notice that the filter
|
||||
is not among the parameters, because it is hardwired in the function.
|
||||
*/
|
||||
typedef UINT (__cdecl *BPF_filter_function)( PVOID *, ULONG, UINT);
|
||||
|
||||
/*! \brief Prototype of the emit functions.
|
||||
|
||||
Different emit functions are used to create the reference table and to generate the actual filtering code.
|
||||
This allows to have simpler instruction macros.
|
||||
The first parameter is the stream that will receive the data. The secon one is a variable containing
|
||||
the data, the third one is the length, that can be 1,2 or 4 since it is possible to emit a byte, a short
|
||||
or a work at a time.
|
||||
*/
|
||||
typedef void (*emit_func)(binary_stream *stream, ULONG value, UINT n);
|
||||
|
||||
/*! \brief Structure describing a x86 filtering program created by the jitter.*/
|
||||
typedef struct JIT_BPF_Filter{
|
||||
BPF_filter_function Function; ///< The x86 filtering binary, in the form of a BPF_filter_function.
|
||||
PINT mem;
|
||||
}
|
||||
JIT_BPF_Filter;
|
||||
|
||||
|
||||
|
||||
|
||||
/**************************/
|
||||
/* X86 INSTRUCTION MACROS */
|
||||
/**************************/
|
||||
|
||||
/// mov r32,i32
|
||||
#define MOVid(r32, i32) \
|
||||
emitm(&stream, 11 << 4 | 1 << 3 | r32 & 0x7, 1); emitm(&stream, i32, 4);
|
||||
|
||||
/// mov dr32,sr32
|
||||
#define MOVrd(dr32, sr32) \
|
||||
emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);
|
||||
|
||||
/// mov dr32,sr32[off]
|
||||
#define MOVodd(dr32, sr32, off) \
|
||||
emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \
|
||||
emitm(&stream, 1 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);\
|
||||
emitm(&stream, off, 1);
|
||||
|
||||
/// mov dr32,sr32[or32]
|
||||
#define MOVobd(dr32, sr32, or32) \
|
||||
emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \
|
||||
emitm(&stream, (dr32 & 0x7) << 3 | 4 , 1);\
|
||||
emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1);
|
||||
|
||||
/// mov dr16,sr32[or32]
|
||||
#define MOVobw(dr32, sr32, or32) \
|
||||
emitm(&stream, 0x66, 1); \
|
||||
emitm(&stream, 8 << 4 | 3 | 1 << 3, 1); \
|
||||
emitm(&stream, (dr32 & 0x7) << 3 | 4 , 1);\
|
||||
emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1);
|
||||
|
||||
/// mov dr8,sr32[or32]
|
||||
#define MOVobb(dr8, sr32, or32) \
|
||||
emitm(&stream, 0x8a, 1); \
|
||||
emitm(&stream, (dr8 & 0x7) << 3 | 4 , 1);\
|
||||
emitm(&stream, (or32 & 0x7) << 3 | (sr32 & 0x7) , 1);
|
||||
|
||||
/// mov [dr32][or32],sr32
|
||||
#define MOVomd(dr32, or32, sr32) \
|
||||
emitm(&stream, 0x89, 1); \
|
||||
emitm(&stream, (sr32 & 0x7) << 3 | 4 , 1);\
|
||||
emitm(&stream, (or32 & 0x7) << 3 | (dr32 & 0x7) , 1);
|
||||
|
||||
/// bswap dr32
|
||||
#define BSWAP(dr32) \
|
||||
emitm(&stream, 0xf, 1); \
|
||||
emitm(&stream, 0x19 << 3 | dr32 , 1);
|
||||
|
||||
/// xchg al,ah
|
||||
#define SWAP_AX() \
|
||||
emitm(&stream, 0x86, 1); \
|
||||
emitm(&stream, 0xc4 , 1);
|
||||
|
||||
/// push r32
|
||||
#define PUSH(r32) \
|
||||
emitm(&stream, 5 << 4 | 0 << 3 | r32 & 0x7, 1);
|
||||
|
||||
/// pop r32
|
||||
#define POP(r32) \
|
||||
emitm(&stream, 5 << 4 | 1 << 3 | r32 & 0x7, 1);
|
||||
|
||||
/// ret
|
||||
#define RET() \
|
||||
emitm(&stream, 12 << 4 | 0 << 3 | 3, 1);
|
||||
|
||||
/// add dr32,sr32
|
||||
#define ADDrd(dr32, sr32) \
|
||||
emitm(&stream, 0x03, 1);\
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | (sr32 & 0x7), 1);
|
||||
|
||||
/// add eax,i32
|
||||
#define ADD_EAXi(i32) \
|
||||
emitm(&stream, 0x05, 1);\
|
||||
emitm(&stream, i32, 4);
|
||||
|
||||
/// add r32,i32
|
||||
#define ADDid(r32, i32) \
|
||||
emitm(&stream, 0x81, 1);\
|
||||
emitm(&stream, 24 << 3 | r32, 1);\
|
||||
emitm(&stream, i32, 4);
|
||||
|
||||
/// add r32,i8
|
||||
#define ADDib(r32, i8) \
|
||||
emitm(&stream, 0x83, 1);\
|
||||
emitm(&stream, 24 << 3 | r32, 1);\
|
||||
emitm(&stream, i8, 1);
|
||||
|
||||
/// sub dr32,sr32
|
||||
#define SUBrd(dr32, sr32) \
|
||||
emitm(&stream, 0x2b, 1);\
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | (sr32 & 0x7), 1);
|
||||
|
||||
/// sub eax,i32
|
||||
#define SUB_EAXi(i32) \
|
||||
emitm(&stream, 0x2d, 1);\
|
||||
emitm(&stream, i32, 4);
|
||||
|
||||
/// mul r32
|
||||
#define MULrd(r32) \
|
||||
emitm(&stream, 0xf7, 1);\
|
||||
emitm(&stream, 7 << 5 | (r32 & 0x7), 1);
|
||||
|
||||
/// div r32
|
||||
#define DIVrd(r32) \
|
||||
emitm(&stream, 0xf7, 1);\
|
||||
emitm(&stream, 15 << 4 | (r32 & 0x7), 1);
|
||||
|
||||
/// and r8,i8
|
||||
#define ANDib(r8, i8) \
|
||||
emitm(&stream, 0x80, 1);\
|
||||
emitm(&stream, 7 << 5 | r8, 1);\
|
||||
emitm(&stream, i8, 1);
|
||||
|
||||
/// and r32,i32
|
||||
#define ANDid(r32, i32) \
|
||||
if (r32 == EAX){ \
|
||||
emitm(&stream, 0x25, 1);\
|
||||
emitm(&stream, i32, 4);}\
|
||||
else{ \
|
||||
emitm(&stream, 0x81, 1);\
|
||||
emitm(&stream, 7 << 5 | r32, 1);\
|
||||
emitm(&stream, i32, 4);}
|
||||
|
||||
/// and dr32,sr32
|
||||
#define ANDrd(dr32, sr32) \
|
||||
emitm(&stream, 0x23, 1);\
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);
|
||||
|
||||
/// or dr32,sr32
|
||||
#define ORrd(dr32, sr32) \
|
||||
emitm(&stream, 0x0b, 1);\
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);
|
||||
|
||||
/// or r32,i32
|
||||
#define ORid(r32, i32) \
|
||||
if (r32 == EAX){ \
|
||||
emitm(&stream, 0x0d, 1);\
|
||||
emitm(&stream, i32, 4);}\
|
||||
else{ \
|
||||
emitm(&stream, 0x81, 1);\
|
||||
emitm(&stream, 25 << 3 | r32, 1);\
|
||||
emitm(&stream, i32, 4);}
|
||||
|
||||
/// shl r32,i8
|
||||
#define SHLib(r32, i8) \
|
||||
emitm(&stream, 0xc1, 1);\
|
||||
emitm(&stream, 7 << 5 | r32 & 0x7, 1);\
|
||||
emitm(&stream, i8, 1);
|
||||
|
||||
/// shl dr32,cl
|
||||
#define SHL_CLrb(dr32) \
|
||||
emitm(&stream, 0xd3, 1);\
|
||||
emitm(&stream, 7 << 5 | dr32 & 0x7, 1);
|
||||
|
||||
/// shr r32,i8
|
||||
#define SHRib(r32, i8) \
|
||||
emitm(&stream, 0xc1, 1);\
|
||||
emitm(&stream, 29 << 3 | r32 & 0x7, 1);\
|
||||
emitm(&stream, i8, 1);
|
||||
|
||||
/// shr dr32,cl
|
||||
#define SHR_CLrb(dr32) \
|
||||
emitm(&stream, 0xd3, 1);\
|
||||
emitm(&stream, 29 << 3 | dr32 & 0x7, 1);
|
||||
|
||||
/// neg r32
|
||||
#define NEGd(r32) \
|
||||
emitm(&stream, 0xf7, 1);\
|
||||
emitm(&stream, 27 << 3 | r32 & 0x7, 1);
|
||||
|
||||
/// cmp dr32,sr32[off]
|
||||
#define CMPodd(dr32, sr32, off) \
|
||||
emitm(&stream, 3 << 4 | 3 | 1 << 3, 1); \
|
||||
emitm(&stream, 1 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);\
|
||||
emitm(&stream, off, 1);
|
||||
|
||||
/// cmp dr32,sr32
|
||||
#define CMPrd(dr32, sr32) \
|
||||
emitm(&stream, 0x3b, 1); \
|
||||
emitm(&stream, 3 << 6 | (dr32 & 0x7) << 3 | sr32 & 0x7, 1);
|
||||
|
||||
/// cmp dr32,i32
|
||||
#define CMPid(dr32, i32) \
|
||||
if (dr32 == EAX){ \
|
||||
emitm(&stream, 0x3d, 1); \
|
||||
emitm(&stream, i32, 4);} \
|
||||
else{ \
|
||||
emitm(&stream, 0x81, 1); \
|
||||
emitm(&stream, 0x1f << 3 | (dr32 & 0x7), 1);\
|
||||
emitm(&stream, i32, 4);}
|
||||
|
||||
/// jne off32
|
||||
#define JNEb(off8) \
|
||||
emitm(&stream, 0x75, 1);\
|
||||
emitm(&stream, off8, 1);
|
||||
|
||||
/// je off32
|
||||
#define JE(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x84, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jle off32
|
||||
#define JLE(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x8e, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jle off8
|
||||
#define JLEb(off8) \
|
||||
emitm(&stream, 0x7e, 1);\
|
||||
emitm(&stream, off8, 1);
|
||||
|
||||
/// ja off32
|
||||
#define JA(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x87, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jae off32
|
||||
#define JAE(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x83, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jg off32
|
||||
#define JG(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x8f, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jge off32
|
||||
#define JGE(off32) \
|
||||
emitm(&stream, 0x0f, 1);\
|
||||
emitm(&stream, 0x8d, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/// jmp off32
|
||||
#define JMP(off32) \
|
||||
emitm(&stream, 0xe9, 1);\
|
||||
emitm(&stream, off32, 4);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**************************/
|
||||
/* Prototypes */
|
||||
/**************************/
|
||||
|
||||
/** @ingroup NPF
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup NPF_code NPF functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
\brief BPF jitter, builds an x86 function from a BPF program.
|
||||
\param fp The BPF pseudo-assembly filter that will be translated into x86 code.
|
||||
\param nins Number of instructions of the input filter.
|
||||
\return The JIT_BPF_Filter structure containing the x86 filtering binary.
|
||||
|
||||
BPF_jitter allocates the buffers for the new native filter and then translates the program pointed by fp
|
||||
calling BPFtoX86().
|
||||
*/
|
||||
JIT_BPF_Filter* BPF_jitter(struct bpf_insn *fp, INT nins);
|
||||
|
||||
/*!
|
||||
\brief Translates a set of BPF instructions in a set of x86 ones.
|
||||
\param ins Pointer to the BPF instructions that will be translated into x86 code.
|
||||
\param nins Number of instructions to translate.
|
||||
\param mem Memory used by the x86 function to emulate the RAM of the BPF pseudo processor.
|
||||
\return The x86 filtering function.
|
||||
|
||||
This function does the hard work for the JIT compilation. It takes a group of BPF pseudo instructions and
|
||||
through the instruction macros defined in jitter.h it is able to create an function directly executable
|
||||
by NPF.
|
||||
*/
|
||||
BPF_filter_function BPFtoX86(struct bpf_insn *ins, UINT nins, INT *mem);
|
||||
/*!
|
||||
\brief Deletes a filtering function that was previously created by BPF_jitter().
|
||||
\param Filter The filter to destroy.
|
||||
|
||||
This function frees the variuos buffers (code, memory, etc.) associated with a filtering function.
|
||||
*/
|
||||
void BPF_Destroy_JIT_Filter(JIT_BPF_Filter *Filter);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
Reference in New Issue
Block a user