changed error defines to have "ERROR" instead of "ERR"
added and verified sysreq.c which is generated on -O0 --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40118
This commit is contained in:
@@ -1407,6 +1407,26 @@ inline void WriteOp_Casetbl(JitWriter *jit)
|
||||
jit->inptr += num_cases;
|
||||
}
|
||||
|
||||
inline void WriteOp_Sysreq_C(JitWriter *jit)
|
||||
{
|
||||
/* store the number of parameters on the stack,
|
||||
* and store the native index as well.
|
||||
*/
|
||||
cell_t native_index = jit->read_cell();
|
||||
|
||||
if ((uint32_t)native_index >= ((CompData*)jit->data)->plugin->info.natives_num)
|
||||
{
|
||||
((CompData *)jit->data)->error_set = SP_ERROR_INSTRUCTION_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
//mov ecx, <native_index>
|
||||
IA32_Mov_Rm_Imm32(jit, REG_ECX, native_index, MOD_REG);
|
||||
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_sysreq_c);
|
||||
}
|
||||
|
||||
inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
|
||||
{
|
||||
/* store the number of parameters on the stack,
|
||||
@@ -1417,7 +1437,7 @@ inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
|
||||
|
||||
if ((uint32_t)native_index >= ((CompData*)jit->data)->plugin->info.natives_num)
|
||||
{
|
||||
((CompData *)jit->data)->error_set = SP_ERR_INSTRUCTION_PARAM;
|
||||
((CompData *)jit->data)->error_set = SP_ERROR_INSTRUCTION_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1439,7 +1459,7 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
|
||||
|
||||
if ((uint32_t)native_index >= data->plugin->info.natives_num)
|
||||
{
|
||||
data->error_set = SP_ERR_INSTRUCTION_PARAM;
|
||||
data->error_set = SP_ERROR_INSTRUCTION_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1481,8 +1501,13 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
|
||||
//call NativeCallback
|
||||
IA32_Push_Reg(jit, REG_EAX);
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback);
|
||||
|
||||
if (!data->debug)
|
||||
{
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback);
|
||||
} else {
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
|
||||
}
|
||||
|
||||
/* check for errors */
|
||||
//mov ecx, [esi+context]
|
||||
//cmp [ecx+err], 0
|
||||
@@ -1528,13 +1553,55 @@ cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
||||
/* Technically both aren't needed, I guess */
|
||||
if (native->status == SP_NATIVE_NONE)
|
||||
{
|
||||
ctx->err = SP_ERR_NATIVE_PENDING;
|
||||
ctx->err = SP_ERROR_NATIVE_PENDING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return native->pfn(ctx, params);
|
||||
}
|
||||
|
||||
cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
||||
{
|
||||
cell_t save_sp = ctx->sp;
|
||||
cell_t save_hp = ctx->hp;
|
||||
|
||||
if (ctx->hp < ctx->heapbase)
|
||||
{
|
||||
ctx->err = SP_ERROR_HEAPMIN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->hp + STACK_MARGIN > ctx->sp)
|
||||
{
|
||||
ctx->err = SP_ERROR_STACKLOW;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((uint32_t)ctx->sp >= ctx->memory)
|
||||
{
|
||||
ctx->err = SP_ERROR_STACKMIN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t result = NativeCallback(ctx, native_idx, params);
|
||||
|
||||
if (ctx->err != SP_ERROR_NONE)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (save_sp != ctx->sp)
|
||||
{
|
||||
ctx->err = SP_ERROR_STACKLEAK;
|
||||
return result;
|
||||
} else if (save_hp != ctx->hp) {
|
||||
ctx->err = SP_ERROR_HEAPLEAK;
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
|
||||
{
|
||||
if (jit->outptr)
|
||||
@@ -1559,25 +1626,25 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
|
||||
void WriteErrorRoutines(CompData *data, JitWriter *jit)
|
||||
{
|
||||
data->jit_error_divzero = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_DIVIDE_BY_ZERO);
|
||||
Write_SetError(jit, SP_ERROR_DIVIDE_BY_ZERO);
|
||||
|
||||
data->jit_error_stacklow = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_STACKLOW);
|
||||
Write_SetError(jit, SP_ERROR_STACKLOW);
|
||||
|
||||
data->jit_error_stackmin = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_STACKMIN);
|
||||
Write_SetError(jit, SP_ERROR_STACKMIN);
|
||||
|
||||
data->jit_error_bounds = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_ARRAY_BOUNDS);
|
||||
Write_SetError(jit, SP_ERROR_ARRAY_BOUNDS);
|
||||
|
||||
data->jit_error_memaccess = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_MEMACCESS);
|
||||
Write_SetError(jit, SP_ERROR_MEMACCESS);
|
||||
|
||||
data->jit_error_heaplow = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_HEAPLOW);
|
||||
Write_SetError(jit, SP_ERROR_HEAPLOW);
|
||||
|
||||
data->jit_error_heapmin = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_HEAPMIN);
|
||||
Write_SetError(jit, SP_ERROR_HEAPMIN);
|
||||
|
||||
data->jit_extern_error = jit->get_outputpos();
|
||||
Write_GetError(jit);
|
||||
@@ -1629,6 +1696,10 @@ jit_rewind:
|
||||
WriteOp_Sysreq_N_Function(jit);
|
||||
}
|
||||
|
||||
/* Plugins compiled with -O0 will need this! */
|
||||
data->jit_sysreq_c = jit->get_outputpos();
|
||||
WriteOp_Sysreq_C_Function(jit);
|
||||
|
||||
/* Write error checking routines that are called to */
|
||||
if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
|
||||
{
|
||||
@@ -1663,7 +1734,7 @@ jit_rewind:
|
||||
#include "opcode_switch.inc"
|
||||
}
|
||||
/* Check for errors. This should only happen in the first pass. */
|
||||
if (data->error_set != SP_ERR_NONE)
|
||||
if (data->error_set != SP_ERROR_NONE)
|
||||
{
|
||||
*err = data->error_set;
|
||||
AbortCompilation(co);
|
||||
@@ -1812,7 +1883,7 @@ jit_rewind:
|
||||
/* clean up relocation+compilation memory */
|
||||
AbortCompilation(co);
|
||||
|
||||
*err = SP_ERR_NONE;
|
||||
*err = SP_ERROR_NONE;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
@@ -1848,7 +1919,7 @@ ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
|
||||
|
||||
data->plugin = plugin;
|
||||
data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
|
||||
data->error_set = SP_ERR_NONE;
|
||||
data->error_set = SP_ERROR_NONE;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -15,17 +15,18 @@ class CompData : public ICompilation
|
||||
{
|
||||
public:
|
||||
CompData() : plugin(NULL),
|
||||
debug(false), inline_level(0), rebase(NULL)
|
||||
debug(false), inline_level(0), rebase(NULL),
|
||||
error_set(SP_ERROR_NONE)
|
||||
{
|
||||
};
|
||||
public:
|
||||
sp_plugin_t *plugin;
|
||||
jitcode_t rebase;
|
||||
jitoffs_t jit_return;
|
||||
sp_plugin_t *plugin; /* plugin handle */
|
||||
jitcode_t rebase; /* relocation map */
|
||||
jitoffs_t jit_return; /* point in main call to return to */
|
||||
jitoffs_t jit_verify_addr_eax;
|
||||
jitoffs_t jit_verify_addr_edx;
|
||||
jitoffs_t jit_break;
|
||||
jitoffs_t jit_sysreq_n;
|
||||
jitoffs_t jit_break; /* call to op.break */
|
||||
jitoffs_t jit_sysreq_n; /* call version of op.sysreq.n */
|
||||
jitoffs_t jit_error_bounds;
|
||||
jitoffs_t jit_error_divzero;
|
||||
jitoffs_t jit_error_stacklow;
|
||||
@@ -33,11 +34,12 @@ public:
|
||||
jitoffs_t jit_error_memaccess;
|
||||
jitoffs_t jit_error_heaplow;
|
||||
jitoffs_t jit_error_heapmin;
|
||||
jitoffs_t jit_extern_error;
|
||||
uint32_t codesize;
|
||||
int inline_level;
|
||||
int error_set;
|
||||
bool debug;
|
||||
jitoffs_t jit_extern_error; /* returning generic error */
|
||||
jitoffs_t jit_sysreq_c; /* old version! */
|
||||
uint32_t codesize; /* total codesize */
|
||||
int inline_level; /* inline optimization level */
|
||||
int error_set; /* error code to halt process */
|
||||
bool debug; /* whether to compile debug mode */
|
||||
};
|
||||
|
||||
class JITX86 : public IVirtualMachine
|
||||
@@ -53,6 +55,7 @@ public:
|
||||
};
|
||||
|
||||
cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
|
||||
cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
|
||||
jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
|
||||
|
||||
#define AMX_REG_PRI REG_EAX
|
||||
@@ -69,8 +72,7 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
|
||||
#define AMX_INFO_RETVAL 8 //physical
|
||||
#define AMX_INFO_CONTEXT 12 //physical
|
||||
#define AMX_INFO_STACKTOP 16 //relocated
|
||||
#define AMX_INFO_HEAPLOW 20 //not relocated. currently unused
|
||||
#define AMX_INFO_STACKTOP_U 24 //not relocated
|
||||
#define AMX_INFO_STACKTOP_U 20 //not relocated
|
||||
|
||||
extern ISourcePawnEngine *engine;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "opcode_helpers.h"
|
||||
#include "x86_macros.h"
|
||||
|
||||
#define NUM_INFO_PARAMS 7
|
||||
#define NUM_INFO_PARAMS 6
|
||||
|
||||
jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||
{
|
||||
@@ -66,14 +66,10 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||
//mov [esi+x], ecx - store unrelocated
|
||||
//add ecx, ebp - relocate
|
||||
//mov [esi+x], ecx - store relocated
|
||||
//mov ecx, [eax+<offs>] - get heap low
|
||||
//mov [esi+20], ecx - store heap low into info pointer
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, memory));
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP_U);
|
||||
IA32_Add_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, heapbase));
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_HEAPLOW);
|
||||
|
||||
/* Remaining needed vars */
|
||||
//mov ecx, [esp+(4*(NUM_INFO_PARAMS+3))+12] - get code index (normally esp+12, but we have another array on the stack)
|
||||
@@ -88,10 +84,10 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||
/* if the code flow gets to here, there was a normal return */
|
||||
//mov ecx, [esi+8] - get retval pointer
|
||||
//mov [ecx], eax - store retval from PRI
|
||||
//mov eax, SP_ERR_NONE - set no error
|
||||
//mov eax, SP_ERROR_NONE - set no error
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, AMX_REG_INFO, AMX_INFO_RETVAL);
|
||||
IA32_Mov_Rm_Reg(jit, REG_ECX, AMX_REG_PRI, MOD_MEM_REG);
|
||||
IA32_Mov_Reg_Imm32(jit, REG_EAX, SP_ERR_NONE);
|
||||
IA32_Mov_Reg_Imm32(jit, REG_EAX, SP_ERROR_NONE);
|
||||
|
||||
/* save where error checking/halting functions should go to */
|
||||
jitoffs_t offs_return = jit->get_outputpos();
|
||||
@@ -390,6 +386,71 @@ void Macro_PushN(JitWriter *jit, int i)
|
||||
IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
|
||||
}
|
||||
|
||||
void WriteOp_Sysreq_C_Function(JitWriter *jit)
|
||||
{
|
||||
/* The small daddy of the big daddy of opcodes.
|
||||
* ecx - native index
|
||||
*/
|
||||
CompData *data = (CompData *)jit->data;
|
||||
|
||||
/* save registers we will need */
|
||||
//push edx
|
||||
IA32_Push_Reg(jit, AMX_REG_ALT);
|
||||
|
||||
/* push some callback stuff */
|
||||
//push edi ; stack
|
||||
//push ecx ; native index
|
||||
IA32_Push_Reg(jit, AMX_REG_STK);
|
||||
IA32_Push_Reg(jit, REG_ECX);
|
||||
|
||||
/* Relocate stack, heap, frm information, then store back */
|
||||
//sub edi, ebp
|
||||
//mov ecx, [esi+hea]
|
||||
//mov eax, [esi+context]
|
||||
//mov [eax+hp], ecx
|
||||
//mov [eax+sp], edi
|
||||
//mov ecx, [esi+frm]
|
||||
//mov [eax+frm], ecx
|
||||
IA32_Sub_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
|
||||
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_REG);
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
|
||||
|
||||
/* finally, push the last parameter and make the call */
|
||||
//push eax ; context
|
||||
//call NativeCallback
|
||||
IA32_Push_Reg(jit, REG_EAX);
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
if (!data->debug)
|
||||
{
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback);
|
||||
} else {
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
|
||||
}
|
||||
|
||||
/* Test for error */
|
||||
//mov ecx, [esi+context]
|
||||
//cmp [ecx+err], 0
|
||||
//jnz :error
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||
IA32_Cmp_Rm_Imm32_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
|
||||
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
|
||||
|
||||
/* restore what we damaged */
|
||||
//add esp, 4*3
|
||||
//add edi, ebp
|
||||
//pop edx
|
||||
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
|
||||
IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
|
||||
IA32_Pop_Reg(jit, AMX_REG_ALT);
|
||||
|
||||
//ret
|
||||
IA32_Return(jit);
|
||||
}
|
||||
|
||||
void WriteOp_Sysreq_N_Function(JitWriter *jit)
|
||||
{
|
||||
/* The big daddy of opcodes.
|
||||
@@ -437,7 +498,12 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
|
||||
//call NativeCallback
|
||||
IA32_Push_Reg(jit, REG_EAX);
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
IA32_Write_Jump32_Abs(jit, call, (void *)&NativeCallback);
|
||||
if (!data->debug)
|
||||
{
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback);
|
||||
} else {
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
|
||||
}
|
||||
|
||||
/* Test for error */
|
||||
//mov ecx, [esi+context]
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
jitoffs_t Write_Execute_Function(JitWriter *jit);
|
||||
|
||||
/**
|
||||
* Writes the Sysreq.n opcode as a function call.
|
||||
* Writes the Sysreq.* opcodes as a function call.
|
||||
*/
|
||||
void WriteOp_Sysreq_N_Function(JitWriter *jit);
|
||||
void WriteOp_Sysreq_C_Function(JitWriter *jit);
|
||||
|
||||
/**
|
||||
* Generates code to set an error state in the VM and return.
|
||||
@@ -200,7 +201,7 @@ typedef enum
|
||||
OP_HALT, //DONE
|
||||
OP_BOUNDS, //VERIFIED
|
||||
OP_SYSREQ_PRI, // !GEN
|
||||
OP_SYSREQ_C, // !GEN DEPRECATED
|
||||
OP_SYSREQ_C, //VERIFIED
|
||||
OP_FILE, // !GEN DEPRECATED
|
||||
OP_LINE, // !GEN DEPRECATED
|
||||
OP_SYMBOL, // !GEN DEPRECATED
|
||||
|
||||
@@ -643,6 +643,11 @@
|
||||
WriteOp_Call(jit);
|
||||
break;
|
||||
}
|
||||
case OP_SYSREQ_C:
|
||||
{
|
||||
WriteOp_Sysreq_C(jit);
|
||||
break;
|
||||
}
|
||||
case OP_SYSREQ_N:
|
||||
{
|
||||
if (data->inline_level & JIT_INLINE_NATIVES)
|
||||
@@ -658,7 +663,7 @@
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
data->error_set = SP_ERR_INVALID_INSTRUCTION;
|
||||
data->error_set = SP_ERROR_INVALID_INSTRUCTION;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user