added new tracker opcodes

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40135
This commit is contained in:
Borja Ferrer 2006-11-02 20:23:14 +00:00
parent a10aabaeda
commit 5b9ba35f0f
7 changed files with 168 additions and 34 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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)
/* ----- */

View File

@ -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:

View File

@ -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);