debug break now uses context struct instead of context interface
err is renamed to 'n_err' 'n_err' is now a 'native only' member, for native errors only --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40242
This commit is contained in:
parent
cf15783eb0
commit
a7fe408995
@ -314,6 +314,67 @@ namespace SourcePawn
|
|||||||
virtual int Execute(uint32_t funcid, cell_t *result) =0;
|
virtual int Execute(uint32_t funcid, cell_t *result) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ErrorTraceInfo
|
||||||
|
{
|
||||||
|
const char *filename;
|
||||||
|
unsigned int line;
|
||||||
|
const char *function;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IContextErrorInfo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Returns the integer error code.
|
||||||
|
*
|
||||||
|
* @return Integer error code.
|
||||||
|
*/
|
||||||
|
virtual int GetErrorCode() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a string describing the error.
|
||||||
|
*
|
||||||
|
* @return Error string.
|
||||||
|
*/
|
||||||
|
virtual const char *GetErrorString() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns whether debug info is available.
|
||||||
|
*
|
||||||
|
* @return True if debug info is available, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool DebugInfoAvailable() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a custom error message.
|
||||||
|
*
|
||||||
|
* @return A pointer to a custom error message, or NULL otherwise.
|
||||||
|
*/
|
||||||
|
virtual const char *GetCustomErrorString() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the number of calls in the call backtrace.
|
||||||
|
* NOTE: Tracers are ordered from 0 to N-1, where 0 is the top of the trace.
|
||||||
|
*
|
||||||
|
* @return Number of calls in the trace.
|
||||||
|
*/
|
||||||
|
virtual unsigned int TraceCallCount() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns trace info for a specific point in the backtrace.
|
||||||
|
*
|
||||||
|
* @param call The call trace index (from 0 to N-1).
|
||||||
|
* @param trace An ErrorTraceInfo buffer to store information.
|
||||||
|
* @return True if successful, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool GetTraceInfo(unsigned int call, ErrorTraceInfo *trace) =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IDebugListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void OnContextExecuteError(IPluginContext *ctx, IContextErrorInfo *error) =0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Contains helper functions used by VMs and the host app
|
* @brief Contains helper functions used by VMs and the host app
|
||||||
*/
|
*/
|
||||||
@ -321,8 +382,8 @@ namespace SourcePawn
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Loads a named file from a file pointer.
|
* @brief Loads a named file from a file pointer.
|
||||||
* Using this means base memory will be allocated by the VM.
|
* Note: Using this means the memory will be allocated by the VM.
|
||||||
*
|
*
|
||||||
* @param fp File pointer. May be at any offset. Not closed on return.
|
* @param fp File pointer. May be at any offset. Not closed on return.
|
||||||
* @param err Optional error code pointer.
|
* @param err Optional error code pointer.
|
||||||
@ -331,7 +392,7 @@ namespace SourcePawn
|
|||||||
virtual sp_plugin_t *LoadFromFilePointer(FILE *fp, int *err) =0;
|
virtual sp_plugin_t *LoadFromFilePointer(FILE *fp, int *err) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a file from a base memory address.
|
* @brief Loads a file from a base memory address.
|
||||||
*
|
*
|
||||||
* @param base Base address of the plugin's memory region.
|
* @param base Base address of the plugin's memory region.
|
||||||
* @param plugin If NULL, a new plugin pointer is returned.
|
* @param plugin If NULL, a new plugin pointer is returned.
|
||||||
@ -349,7 +410,7 @@ namespace SourcePawn
|
|||||||
virtual int FreeFromMemory(sp_plugin_t *plugin) =0;
|
virtual int FreeFromMemory(sp_plugin_t *plugin) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new IContext from a context handle.
|
* @brief Creates a new IContext from a context handle.
|
||||||
*
|
*
|
||||||
* @param ctx Context to use as a basis for the IPluginContext.
|
* @param ctx Context to use as a basis for the IPluginContext.
|
||||||
* @return New IPluginContext handle.
|
* @return New IPluginContext handle.
|
||||||
@ -357,14 +418,14 @@ namespace SourcePawn
|
|||||||
virtual IPluginContext *CreateBaseContext(sp_context_t *ctx) =0;
|
virtual IPluginContext *CreateBaseContext(sp_context_t *ctx) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees a base context. Does not free the sp_context_t it holds.
|
* @brief Frees a base context. Does not free the sp_context_t it holds.
|
||||||
*
|
*
|
||||||
* @param ctx Context pointer to free.
|
* @param ctx Context pointer to free.
|
||||||
*/
|
*/
|
||||||
virtual void FreeBaseContext(IPluginContext *ctx) =0;
|
virtual void FreeBaseContext(IPluginContext *ctx) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates large blocks of temporary memory.
|
* @brief Allocates large blocks of temporary memory.
|
||||||
*
|
*
|
||||||
* @param size Size of memory to allocate.
|
* @param size Size of memory to allocate.
|
||||||
* @return Pointer to memory, NULL if allocation failed.
|
* @return Pointer to memory, NULL if allocation failed.
|
||||||
@ -372,14 +433,14 @@ namespace SourcePawn
|
|||||||
virtual void *BaseAlloc(size_t size) =0;
|
virtual void *BaseAlloc(size_t size) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees memory allocated with BaseAlloc.
|
* @brief Frees memory allocated with BaseAlloc.
|
||||||
*
|
*
|
||||||
* @param memory Memory address to free.
|
* @param memory Memory address to free.
|
||||||
*/
|
*/
|
||||||
virtual void BaseFree(void *memory) =0;
|
virtual void BaseFree(void *memory) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates executable memory.
|
* @brief Allocates executable memory.
|
||||||
*
|
*
|
||||||
* @param size Size of memory to allocate.
|
* @param size Size of memory to allocate.
|
||||||
* @return Pointer to memory, NULL if allocation failed.
|
* @return Pointer to memory, NULL if allocation failed.
|
||||||
@ -387,13 +448,50 @@ namespace SourcePawn
|
|||||||
virtual void *ExecAlloc(size_t size) =0;
|
virtual void *ExecAlloc(size_t size) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees executable memory.
|
* @brief Frees executable memory.
|
||||||
*
|
*
|
||||||
* @param address Address to free.
|
* @param address Address to free.
|
||||||
*/
|
*/
|
||||||
virtual void ExecFree(void *address) =0;
|
virtual void ExecFree(void *address) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the debug listener.
|
||||||
|
*
|
||||||
|
* @param listener Pointer to an IDebugListener.
|
||||||
|
* @return Old IDebugListener, or NULL if none.
|
||||||
|
*/
|
||||||
|
virtual IDebugListener *SetDebugListener(IDebugListener *pListener) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the number of plugins on the call stack.
|
||||||
|
*
|
||||||
|
* @return Number of contexts in the call stack.
|
||||||
|
*/
|
||||||
|
virtual unsigned int GetContextCallCount() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Throws an error and halts any current execution.
|
||||||
|
*
|
||||||
|
* @param error The error number to set.
|
||||||
|
* @param msg Custom error message format. NULL to use default.
|
||||||
|
* @param ... Message format arguments, if any.
|
||||||
|
*/
|
||||||
|
virtual void ThrowNativeErrorEx(int error, const char *msg, ...) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Throws a native error and halts any current execution.
|
||||||
|
* NOTE: This is a wrapper around ThrowError() for convenience.
|
||||||
|
*
|
||||||
|
* @param msg Custom error message format. NULL to set no message.
|
||||||
|
* @param ... Message format arguments, if any.
|
||||||
|
* @return 0 for convenience.
|
||||||
|
*/
|
||||||
|
virtual void ThrowNativeError(const char *msg, ...) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dummy class for encapsulating private compilation data.
|
||||||
|
*/
|
||||||
class ICompilation
|
class ICompilation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <sp_vm_api.h>
|
#include <sp_vm_api.h>
|
||||||
|
|
||||||
|
/* :TODO: rename this to sp_vm_linkage.h */
|
||||||
|
|
||||||
#if defined WIN32
|
#if defined WIN32
|
||||||
#define EXPORT_LINK extern "C" __declspec(dllexport)
|
#define EXPORT_LINK extern "C" __declspec(dllexport)
|
||||||
#else if defined __GNUC__
|
#else if defined __GNUC__
|
||||||
|
@ -37,6 +37,7 @@ typedef uint32_t funcid_t;
|
|||||||
#define SP_ERROR_TRACKER_BOUNDS 20 /* Tracker stack is out of bounds */
|
#define SP_ERROR_TRACKER_BOUNDS 20 /* Tracker stack is out of bounds */
|
||||||
#define SP_ERROR_INVALID_NATIVE 21 /* Native was pending or invalid */
|
#define SP_ERROR_INVALID_NATIVE 21 /* Native was pending or invalid */
|
||||||
#define SP_ERROR_PARAMS_MAX 22 /* Maximum number of parameters reached */
|
#define SP_ERROR_PARAMS_MAX 22 /* Maximum number of parameters reached */
|
||||||
|
#define SP_ERROR_NATIVE 23 /* Error originates from a native */
|
||||||
|
|
||||||
/**********************************************
|
/**********************************************
|
||||||
*** The following structures are reference structures.
|
*** The following structures are reference structures.
|
||||||
@ -204,7 +205,7 @@ typedef struct sp_debug_symbol_s
|
|||||||
* [1] - frm
|
* [1] - frm
|
||||||
* [2] - cip
|
* [2] - cip
|
||||||
*/
|
*/
|
||||||
typedef int (*SPVM_DEBUGBREAK)(SourcePawn::IPluginContext *, uint32_t, uint32_t);
|
typedef int (*SPVM_DEBUGBREAK)(struct sp_context_s *, uint32_t, uint32_t);
|
||||||
|
|
||||||
#define SPFLAG_PLUGIN_DEBUG (1<<0) /* plugin is in debug mode */
|
#define SPFLAG_PLUGIN_DEBUG (1<<0) /* plugin is in debug mode */
|
||||||
|
|
||||||
@ -234,8 +235,9 @@ typedef struct sp_context_s
|
|||||||
cell_t hp; /* heap pointer */
|
cell_t hp; /* heap pointer */
|
||||||
cell_t sp; /* stack pointer */
|
cell_t sp; /* stack pointer */
|
||||||
cell_t frm; /* frame pointer */
|
cell_t frm; /* frame pointer */
|
||||||
int32_t err; /* error code */
|
|
||||||
uint32_t pushcount; /* push count */
|
uint32_t pushcount; /* push count */
|
||||||
|
int32_t n_err; /* error code set by a native */
|
||||||
|
uint32_t n_idx; /* current native index being executed */
|
||||||
/* context rebased database */
|
/* context rebased database */
|
||||||
sp_public_t *publics; /* public functions table */
|
sp_public_t *publics; /* public functions table */
|
||||||
sp_pubvar_t *pubvars; /* public variables table */
|
sp_pubvar_t *pubvars; /* public variables table */
|
||||||
|
@ -1631,7 +1631,7 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
|
|||||||
//cmp [ecx+err], 0
|
//cmp [ecx+err], 0
|
||||||
//jnz :error
|
//jnz :error
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||||
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
|
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, n_err), 0);
|
||||||
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
|
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
|
||||||
|
|
||||||
/* restore what we damaged */
|
/* restore what we damaged */
|
||||||
@ -1678,12 +1678,14 @@ inline void WriteOp_Tracker_Push_C(JitWriter *jit)
|
|||||||
IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker);
|
IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker);
|
||||||
|
|
||||||
/* Check for errors */
|
/* Check for errors */
|
||||||
//pop eax
|
//cmp eax, 0
|
||||||
//cmp [eax+err], 0
|
|
||||||
//jnz :error
|
//jnz :error
|
||||||
|
IA32_Cmp_Rm_Imm32(jit, MOD_REG, REG_EAX, 0);
|
||||||
|
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_return);
|
||||||
|
|
||||||
|
/* Restore */
|
||||||
|
//pop eax
|
||||||
IA32_Pop_Reg(jit, REG_EAX);
|
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 */
|
/* Push the value into the stack and increment pCur */
|
||||||
//mov edx, [eax+vm[]]
|
//mov edx, [eax+vm[]]
|
||||||
@ -1722,12 +1724,14 @@ inline void WriteOp_Tracker_Pop_SetHeap(JitWriter *jit)
|
|||||||
IA32_Write_Jump32_Abs(jit, call, JIT_VerifyLowBoundTracker);
|
IA32_Write_Jump32_Abs(jit, call, JIT_VerifyLowBoundTracker);
|
||||||
|
|
||||||
/* Check for errors */
|
/* Check for errors */
|
||||||
//pop eax
|
//cmp eax, 0
|
||||||
//cmp [eax+err], 0
|
|
||||||
//jnz :error
|
//jnz :error
|
||||||
|
IA32_Cmp_Rm_Imm32(jit, MOD_REG, REG_EAX, 0);
|
||||||
|
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_return);
|
||||||
|
|
||||||
|
/* Restore */
|
||||||
|
//pop eax
|
||||||
IA32_Pop_Reg(jit, REG_EAX);
|
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*/
|
/* Pop the value from the stack and decrease the heap by it*/
|
||||||
//mov edx, [eax+vm[]]
|
//mov edx, [eax+vm[]]
|
||||||
@ -1769,10 +1773,12 @@ cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
|||||||
{
|
{
|
||||||
sp_native_t *native = &ctx->natives[native_idx];
|
sp_native_t *native = &ctx->natives[native_idx];
|
||||||
|
|
||||||
|
ctx->n_idx = native_idx;
|
||||||
|
|
||||||
/* Technically both aren't needed, I guess */
|
/* Technically both aren't needed, I guess */
|
||||||
if (native->status == SP_NATIVE_UNBOUND)
|
if (native->status == SP_NATIVE_UNBOUND)
|
||||||
{
|
{
|
||||||
ctx->err = SP_ERROR_INVALID_NATIVE;
|
ctx->n_err = SP_ERROR_INVALID_NATIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1782,7 +1788,7 @@ cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
|||||||
static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params)
|
static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params)
|
||||||
{
|
{
|
||||||
sp_context_t *ctx = pCtx->GetContext();
|
sp_context_t *ctx = pCtx->GetContext();
|
||||||
ctx->err = SP_ERROR_INVALID_NATIVE;
|
ctx->n_err = SP_ERROR_INVALID_NATIVE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1792,37 +1798,39 @@ cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *param
|
|||||||
cell_t save_sp = ctx->sp;
|
cell_t save_sp = ctx->sp;
|
||||||
cell_t save_hp = ctx->hp;
|
cell_t save_hp = ctx->hp;
|
||||||
|
|
||||||
|
ctx->n_idx = native_idx;
|
||||||
|
|
||||||
if (ctx->hp < ctx->heap_base)
|
if (ctx->hp < ctx->heap_base)
|
||||||
{
|
{
|
||||||
ctx->err = SP_ERROR_HEAPMIN;
|
ctx->n_err = SP_ERROR_HEAPMIN;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->hp + STACK_MARGIN > ctx->sp)
|
if (ctx->hp + STACK_MARGIN > ctx->sp)
|
||||||
{
|
{
|
||||||
ctx->err = SP_ERROR_STACKLOW;
|
ctx->n_err = SP_ERROR_STACKLOW;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uint32_t)ctx->sp >= ctx->mem_size)
|
if ((uint32_t)ctx->sp >= ctx->mem_size)
|
||||||
{
|
{
|
||||||
ctx->err = SP_ERROR_STACKMIN;
|
ctx->n_err = SP_ERROR_STACKMIN;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell_t result = NativeCallback(ctx, native_idx, params);
|
cell_t result = NativeCallback(ctx, native_idx, params);
|
||||||
|
|
||||||
if (ctx->err != SP_ERROR_NONE)
|
if (ctx->n_err != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (save_sp != ctx->sp)
|
if (save_sp != ctx->sp)
|
||||||
{
|
{
|
||||||
ctx->err = SP_ERROR_STACKLEAK;
|
ctx->n_err = SP_ERROR_STACKLEAK;
|
||||||
return result;
|
return result;
|
||||||
} else if (save_hp != ctx->hp) {
|
} else if (save_hp != ctx->hp) {
|
||||||
ctx->err = SP_ERROR_HEAPLEAK;
|
ctx->n_err = SP_ERROR_HEAPLEAK;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ void Write_BreakDebug(JitWriter *jit)
|
|||||||
//add esp, 8
|
//add esp, 8
|
||||||
//popad
|
//popad
|
||||||
IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_FRAME); //:TODO: move to regs and push? and dont disp for 0
|
IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_FRAME); //:TODO: move to regs and push? and dont disp for 0
|
||||||
IA32_Push_Rm_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, context));
|
IA32_Push_Reg(jit, AMX_REG_TMP);
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_TMP, offsetof(sp_context_t, dbreak));
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_TMP, offsetof(sp_context_t, dbreak));
|
||||||
IA32_Call_Reg(jit, AMX_REG_TMP);
|
IA32_Call_Reg(jit, AMX_REG_TMP);
|
||||||
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*2, MOD_REG);
|
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*2, MOD_REG);
|
||||||
@ -166,7 +166,7 @@ void Write_GetError(JitWriter *jit)
|
|||||||
//mov eax, [eax+ctx.error]
|
//mov eax, [eax+ctx.error]
|
||||||
//jmp [jit_return]
|
//jmp [jit_return]
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EAX, offsetof(sp_context_t, err));
|
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EAX, offsetof(sp_context_t, n_err));
|
||||||
IA32_Jump_Imm32_Abs(jit, data->jit_return);
|
IA32_Jump_Imm32_Abs(jit, data->jit_return);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,7 +435,7 @@ void WriteOp_Sysreq_C_Function(JitWriter *jit)
|
|||||||
//cmp [ecx+err], 0
|
//cmp [ecx+err], 0
|
||||||
//jnz :error
|
//jnz :error
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||||
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
|
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, n_err), 0);
|
||||||
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
|
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
|
||||||
|
|
||||||
/* restore what we damaged */
|
/* restore what we damaged */
|
||||||
@ -662,7 +662,7 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
|
|||||||
//cmp [ecx+err], 0
|
//cmp [ecx+err], 0
|
||||||
//jnz :error
|
//jnz :error
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||||
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
|
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, n_err), 0);
|
||||||
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
|
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
|
||||||
|
|
||||||
/* restore what we damaged */
|
/* restore what we damaged */
|
||||||
@ -713,13 +713,15 @@ void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg)
|
|||||||
IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker);
|
IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker);
|
||||||
|
|
||||||
/* Check for errors */
|
/* Check for errors */
|
||||||
//pop eax
|
//cmp eax, 0
|
||||||
//cmp [eax+err], 0
|
|
||||||
//jnz :error
|
//jnz :error
|
||||||
IA32_Pop_Reg(jit, REG_EAX);
|
IA32_Cmp_Rm_Imm32(jit, MOD_REG, REG_EAX, 0);
|
||||||
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);
|
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds);
|
||||||
|
|
||||||
|
/* Restore */
|
||||||
|
//pop eax
|
||||||
|
IA32_Pop_Reg(jit, REG_EAX);
|
||||||
|
|
||||||
/* Push the register into the stack and increment pCur */
|
/* Push the register into the stack and increment pCur */
|
||||||
//mov edx, [eax+vm[]]
|
//mov edx, [eax+vm[]]
|
||||||
//mov eax, [edx+pcur]
|
//mov eax, [edx+pcur]
|
||||||
@ -742,14 +744,13 @@ void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg)
|
|||||||
IA32_Pop_Reg(jit, AMX_REG_PRI);
|
IA32_Pop_Reg(jit, AMX_REG_PRI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT_VerifyOrAllocateTracker(sp_context_t *ctx)
|
int JIT_VerifyOrAllocateTracker(sp_context_t *ctx)
|
||||||
{
|
{
|
||||||
tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
|
tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
|
||||||
|
|
||||||
if ((size_t)(trk->pCur - trk->pBase) >= trk->size)
|
if ((size_t)(trk->pCur - trk->pBase) >= trk->size)
|
||||||
{
|
{
|
||||||
ctx->err = SP_ERROR_TRACKER_BOUNDS;
|
return SP_ERROR_TRACKER_BOUNDS;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trk->pCur+1 - (trk->pBase + trk->size) == 0)
|
if (trk->pCur+1 - (trk->pBase + trk->size) == 0)
|
||||||
@ -760,20 +761,23 @@ void JIT_VerifyOrAllocateTracker(sp_context_t *ctx)
|
|||||||
|
|
||||||
if (!trk->pBase)
|
if (!trk->pBase)
|
||||||
{
|
{
|
||||||
ctx->err = SP_ERROR_TRACKER_BOUNDS;
|
return SP_ERROR_TRACKER_BOUNDS;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trk->pCur = trk->pBase + disp;
|
trk->pCur = trk->pBase + disp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SP_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT_VerifyLowBoundTracker(sp_context_t *ctx)
|
int JIT_VerifyLowBoundTracker(sp_context_t *ctx)
|
||||||
{
|
{
|
||||||
tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
|
tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
|
||||||
|
|
||||||
if (trk->pCur <= trk->pBase)
|
if (trk->pCur <= trk->pBase)
|
||||||
{
|
{
|
||||||
ctx->err = SP_ERROR_TRACKER_BOUNDS;
|
return SP_ERROR_TRACKER_BOUNDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SP_ERROR_NONE;
|
||||||
}
|
}
|
@ -69,8 +69,8 @@ void Macro_PushN(JitWriter *jit, int i);
|
|||||||
/**
|
/**
|
||||||
* Bound checking for the tracker stack,
|
* Bound checking for the tracker stack,
|
||||||
*/
|
*/
|
||||||
void JIT_VerifyLowBoundTracker(sp_context_t *ctx);
|
int JIT_VerifyLowBoundTracker(sp_context_t *ctx);
|
||||||
void JIT_VerifyOrAllocateTracker(sp_context_t *ctx);
|
int JIT_VerifyOrAllocateTracker(sp_context_t *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the push into tracker function.
|
* Writes the push into tracker function.
|
||||||
|
Loading…
Reference in New Issue
Block a user