added new tracker opcodes
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40135
This commit is contained in:
parent
a10aabaeda
commit
5b9ba35f0f
@ -30,6 +30,7 @@ typedef int32_t cell_t;
|
||||
#define SP_ERROR_STACKLEAK 18 /* A native leaked an item on the stack */
|
||||
#define SP_ERROR_HEAPLEAK 19 /* A native leaked an item on the heap */
|
||||
#define SP_ERROR_ARRAY_TOO_BIG 20 /* A dynamic array is too big */
|
||||
#define SP_ERROR_TRACKER_BOUNDS 21 /* Tracker stack is out of bounds */
|
||||
|
||||
/**********************************************
|
||||
*** The following structures are reference structures.
|
||||
|
@ -983,21 +983,6 @@ inline void WriteOp_Fill(JitWriter *jit)
|
||||
IA32_Pop_Reg(jit, REG_EDI);
|
||||
}
|
||||
|
||||
inline void WriteOp_Heap_I(JitWriter *jit)
|
||||
{
|
||||
//sub [esi+hea], 4
|
||||
//mov ecx, [esi+hea]
|
||||
//mov ecx, [ebp+ecx]
|
||||
//sub [esi+hea], ecx
|
||||
IA32_Sub_Rm_Imm8_Disp8(jit, AMX_REG_INFO, 4, AMX_INFO_HEAP);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
|
||||
IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_TMP, AMX_REG_DAT, AMX_REG_TMP, NOSCALE);
|
||||
IA32_Add_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_TMP, AMX_INFO_HEAP);
|
||||
|
||||
Write_CheckHeap_Min(jit);
|
||||
Write_CheckHeap_Low(jit);
|
||||
}
|
||||
|
||||
inline void WriteOp_GenArray(JitWriter *jit, bool autozero)
|
||||
{
|
||||
cell_t val = jit->read_cell();
|
||||
@ -1064,19 +1049,6 @@ inline void WriteOp_GenArray(JitWriter *jit, bool autozero)
|
||||
}
|
||||
}
|
||||
|
||||
inline void WriteOp_Push_Heap_C(JitWriter *jit)
|
||||
{
|
||||
//mov ecx, [esi+hea]
|
||||
//mov [ebp+ecx], <val>
|
||||
//add [esi+hea], 4
|
||||
cell_t val = jit->read_cell();
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
|
||||
IA32_Mov_RmEBP_Imm32_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, val);
|
||||
IA32_Add_Rm_Imm8_Disp8(jit, AMX_REG_INFO, 4, AMX_INFO_HEAP);
|
||||
|
||||
Write_CheckHeap_Low(jit);
|
||||
}
|
||||
|
||||
inline void WriteOp_Load_Both(JitWriter *jit)
|
||||
{
|
||||
WriteOp_Load_Pri(jit);
|
||||
@ -1622,6 +1594,97 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
|
||||
}
|
||||
}
|
||||
|
||||
inline void WriteOp_Tracker_Push_C(JitWriter *jit)
|
||||
{
|
||||
CompData *data = (CompData *)jit->data;
|
||||
cell_t val = jit->read_cell();
|
||||
|
||||
/* Save registers that may be damaged by the call */
|
||||
//push eax
|
||||
//push edx
|
||||
IA32_Push_Reg(jit, AMX_REG_PRI);
|
||||
IA32_Push_Reg(jit, AMX_REG_ALT);
|
||||
|
||||
/* Get the context ptr, push it and call the check */
|
||||
//mov eax, [esi+context]
|
||||
//push eax
|
||||
//call JIT_VerifyOrAllocateTracker
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||
IA32_Push_Reg(jit, REG_EAX);
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker);
|
||||
|
||||
/* Check for errors */
|
||||
//pop eax
|
||||
//cmp [eax+err], 0
|
||||
//jnz :error
|
||||
IA32_Pop_Reg(jit, REG_EAX);
|
||||
IA32_Cmp_Rm_Disp8_Imm8(jit, REG_EAX, offsetof(sp_context_t, err), 0);
|
||||
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds);
|
||||
|
||||
/* Push the value into the stack and increment pCur */
|
||||
//mov edx, [eax+vm[]]
|
||||
//mov ecx, [edx+pcur]
|
||||
//mov [ecx], <val>
|
||||
//add [edx+pcur], 4
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER]));
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, REG_EDX, offsetof(tracker_t, pCur));
|
||||
IA32_Mov_Rm_Imm32(jit, AMX_REG_TMP, val, MOD_MEM_REG);
|
||||
IA32_Add_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur));
|
||||
|
||||
/* Restore PRI & ALT */
|
||||
//pop edx
|
||||
//pop eax
|
||||
IA32_Pop_Reg(jit, AMX_REG_ALT);
|
||||
IA32_Pop_Reg(jit, AMX_REG_PRI);
|
||||
}
|
||||
|
||||
inline void WriteOp_Tracker_Pop_SetHeap(JitWriter *jit)
|
||||
{
|
||||
CompData *data = (CompData *)jit->data;
|
||||
|
||||
/* Save registers that may be damaged by the call */
|
||||
//push eax
|
||||
//push edx
|
||||
IA32_Push_Reg(jit, AMX_REG_PRI);
|
||||
IA32_Push_Reg(jit, AMX_REG_ALT);
|
||||
|
||||
/* Get the context ptr, push it and call the check */
|
||||
//mov eax, [esi+context]
|
||||
//push eax
|
||||
//call JIT_VerifyLowBoundTracker
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||
IA32_Push_Reg(jit, REG_EAX);
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
IA32_Write_Jump32_Abs(jit, call, JIT_VerifyLowBoundTracker);
|
||||
|
||||
/* Check for errors */
|
||||
//pop eax
|
||||
//cmp [eax+err], 0
|
||||
//jnz :error
|
||||
IA32_Pop_Reg(jit, REG_EAX);
|
||||
IA32_Cmp_Rm_Disp8_Imm8(jit, REG_EAX, offsetof(sp_context_t, err), 0);
|
||||
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds);
|
||||
|
||||
/* Pop the value from the stack and decrease the heap by it*/
|
||||
//mov edx, [eax+vm[]]
|
||||
//sub [edx+pcur], 4
|
||||
//mov ecx, [edx+pcur]
|
||||
//mov ecx, [ecx]
|
||||
//sub [esi+hea], ecx
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER]));
|
||||
IA32_Sub_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur));
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, REG_EDX, offsetof(tracker_t, pCur));
|
||||
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_TMP, MOD_MEM_REG);
|
||||
IA32_Sub_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_TMP, AMX_INFO_HEAP);
|
||||
|
||||
/* Restore PRI & ALT */
|
||||
//pop edx
|
||||
//pop eax
|
||||
IA32_Pop_Reg(jit, AMX_REG_ALT);
|
||||
IA32_Pop_Reg(jit, AMX_REG_PRI);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
*************************************************
|
||||
* JIT PROPER ************************************
|
||||
@ -1732,6 +1795,9 @@ void WriteErrorRoutines(CompData *data, JitWriter *jit)
|
||||
data->jit_error_array_too_big = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERROR_ARRAY_TOO_BIG);
|
||||
|
||||
data->jit_error_tracker_bounds = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERROR_TRACKER_BOUNDS);
|
||||
|
||||
data->jit_extern_error = jit->get_outputpos();
|
||||
Write_GetError(jit);
|
||||
}
|
||||
@ -1969,6 +2035,12 @@ jit_rewind:
|
||||
}
|
||||
}
|
||||
|
||||
tracker_t *trk = new tracker_t;
|
||||
ctx->vm[JITVARS_TRACKER] = trk;
|
||||
trk->pBase = (ucell_t *)malloc(1024);
|
||||
trk->pCur = trk->pBase;
|
||||
trk->size = 1024;
|
||||
|
||||
/* clean up relocation+compilation memory */
|
||||
AbortCompilation(co);
|
||||
|
||||
@ -1999,6 +2071,8 @@ void JITX86::FreeContext(sp_context_t *ctx)
|
||||
delete [] ctx->publics;
|
||||
delete [] ctx->pubvars;
|
||||
delete [] ctx->symbols;
|
||||
free(((tracker_t *)(ctx->vm[JITVARS_TRACKER]))->pBase);
|
||||
delete ctx->vm[JITVARS_TRACKER];
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,15 @@ using namespace SourcePawn;
|
||||
#define JIT_INLINE_NATIVES (1<<1)
|
||||
#define STACK_MARGIN 64 //8 parameters of safety, I guess
|
||||
|
||||
#define JITVARS_TRACKER 0 //important: don't change this to avoid trouble
|
||||
|
||||
typedef struct tracker_s
|
||||
{
|
||||
size_t size;
|
||||
ucell_t *pBase;
|
||||
ucell_t *pCur;
|
||||
} tracker_t;
|
||||
|
||||
class CompData : public ICompilation
|
||||
{
|
||||
public:
|
||||
@ -36,6 +45,7 @@ public:
|
||||
jitoffs_t jit_error_heaplow;
|
||||
jitoffs_t jit_error_heapmin;
|
||||
jitoffs_t jit_error_array_too_big;
|
||||
jitoffs_t jit_error_tracker_bounds;
|
||||
jitoffs_t jit_extern_error; /* returning generic error */
|
||||
jitoffs_t jit_sysreq_c; /* old version! */
|
||||
uint32_t codesize; /* total codesize */
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "jit_x86.h"
|
||||
#include "opcode_helpers.h"
|
||||
#include "x86_macros.h"
|
||||
@ -687,3 +688,38 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
|
||||
IA32_Return(jit);
|
||||
}
|
||||
|
||||
void JIT_VerifyOrAllocateTracker(sp_context_t *ctx)
|
||||
{
|
||||
tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
|
||||
|
||||
if ((size_t)(trk->pCur - trk->pBase) >= trk->size)
|
||||
{
|
||||
ctx->err = SP_ERROR_TRACKER_BOUNDS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (trk->pCur+1 - (trk->pBase + trk->size) == 0)
|
||||
{
|
||||
size_t disp = trk->size - 1;
|
||||
trk->size *= 2;
|
||||
trk->pBase = (ucell_t *)realloc(trk->pBase, trk->size);
|
||||
|
||||
if (!trk->pBase)
|
||||
{
|
||||
ctx->err = SP_ERROR_TRACKER_BOUNDS;
|
||||
return;
|
||||
}
|
||||
|
||||
trk->pCur = trk->pBase + disp;
|
||||
}
|
||||
}
|
||||
|
||||
void JIT_VerifyLowBoundTracker(sp_context_t *ctx)
|
||||
{
|
||||
tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
|
||||
|
||||
if (trk->pCur <= trk->pBase)
|
||||
{
|
||||
ctx->err = SP_ERROR_TRACKER_BOUNDS;
|
||||
}
|
||||
}
|
@ -66,6 +66,12 @@ void Macro_PushN_S(JitWriter *jit, int i);
|
||||
void Macro_PushN_C(JitWriter *jit, int i);
|
||||
void Macro_PushN(JitWriter *jit, int i);
|
||||
|
||||
/**
|
||||
* Bound checking for the tracker stack,
|
||||
*/
|
||||
void JIT_VerifyLowBoundTracker(sp_context_t *ctx);
|
||||
void JIT_VerifyOrAllocateTracker(sp_context_t *ctx);
|
||||
|
||||
/**
|
||||
* Legend for Statuses:
|
||||
* ****** *** ********
|
||||
@ -245,8 +251,8 @@ typedef enum
|
||||
OP_SYSREQ_D, // !GEN UNSUPPORT
|
||||
OP_SYSREQ_ND, // !GEN UNSUPPORT
|
||||
/* ----- */
|
||||
OP_HEAP_I, //VERIFIED
|
||||
OP_PUSH_HEAP_C, //VERIFIED
|
||||
OP_TRACKER_PUSH_C, //DONE
|
||||
OP_TRACKER_POP_SETHEAP, //DONE
|
||||
OP_GENARRAY, //VERIFIED
|
||||
OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays)
|
||||
/* ----- */
|
||||
|
@ -643,14 +643,14 @@
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_PUSH_HEAP_C:
|
||||
case OP_TRACKER_PUSH_C:
|
||||
{
|
||||
WriteOp_Push_Heap_C(jit);
|
||||
WriteOp_Tracker_Push_C(jit);
|
||||
break;
|
||||
}
|
||||
case OP_HEAP_I:
|
||||
case OP_TRACKER_POP_SETHEAP:
|
||||
{
|
||||
WriteOp_Heap_I(jit);
|
||||
WriteOp_Tracker_Pop_SetHeap(jit);
|
||||
break;
|
||||
}
|
||||
case OP_GENARRAY:
|
||||
|
@ -398,6 +398,13 @@ inline void IA32_Sub_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t
|
||||
jit->write_byte(disp8);
|
||||
}
|
||||
|
||||
inline void IA32_Sub_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8)
|
||||
{
|
||||
jit->write_ubyte(IA32_SUB_RM_REG);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
|
||||
jit->write_byte(disp8);
|
||||
}
|
||||
|
||||
inline void IA32_Sub_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t val, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(IA32_SUB_RM_IMM8);
|
||||
|
Loading…
Reference in New Issue
Block a user