sketched out break opcode
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4091
This commit is contained in:
parent
9ba07e4b28
commit
1bf17b05bb
@ -175,10 +175,20 @@ typedef struct sp_debug_symbol_s
|
||||
sp_fdbg_symbol_t *sym; /* pointer to original symbol */
|
||||
} sp_debug_symbol_t;
|
||||
|
||||
namespace SourcePawn
|
||||
{
|
||||
class IPluginContext;
|
||||
class IVirtualMachine;
|
||||
};
|
||||
|
||||
/**
|
||||
* Breaks into a debugger
|
||||
* Params:
|
||||
* [0] - plugin context
|
||||
* [1] - frm
|
||||
* [2] - cip
|
||||
*/
|
||||
typedef int (*SPVM_DEBUGBREAK)(struct sp_context_s *);
|
||||
typedef int (*SPVM_DEBUGBREAK)(SourcePawn::IPluginContext *, uint32_t, uint32_t);
|
||||
|
||||
#define SPFLAG_PLUGIN_DEBUG (1<<0) /* plugin is in debug mode */
|
||||
|
||||
@ -193,8 +203,8 @@ typedef struct sp_context_s
|
||||
/* general/parent information */
|
||||
void *base; /* base of generated code and memory */
|
||||
sp_plugin_t *plugin; /* pointer back to parent information */
|
||||
void *context; /* pointer to IPluginContext */
|
||||
void *vmbase; /* pointer to IVirtualMachine */
|
||||
SourcePawn::IPluginContext *context; /* pointer to IPluginContext */
|
||||
SourcePawn::IVirtualMachine *vmbase; /* pointer to IVirtualMachine */
|
||||
void *user[4]; /* user specific pointers */
|
||||
void *vm[4]; /* VM specific pointers */
|
||||
uint32_t flags; /* compilation flags */
|
||||
|
@ -1382,6 +1382,23 @@ inline void WriteOp_Halt(JitWriter *jit)
|
||||
IA32_Write_Jump32(jit, reloc, data->jit_return);
|
||||
}
|
||||
|
||||
inline void WriteOp_Break(JitWriter *jit)
|
||||
{
|
||||
CompData *data = (CompData *)jit->data;
|
||||
if (data->debug)
|
||||
{
|
||||
//mov ecx, <cip>
|
||||
jitoffs_t wr = IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, 0);
|
||||
jitoffs_t save = jit->jit_curpos();
|
||||
jit->setpos(wr);
|
||||
jit->write_uint32((uint32_t)(jit->outbase + wr));
|
||||
jit->setpos(save);
|
||||
|
||||
wr = IA32_Call_Imm32(jit, 0);
|
||||
IA32_Write_Jump32(jit, wr, data->jit_break);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
*************************************************
|
||||
@ -1476,6 +1493,8 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
|
||||
data->jit_return = Write_Execute_Function(jit);
|
||||
|
||||
/* Write error checking routines in case they are needed */
|
||||
if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
|
||||
{
|
||||
jitpos = jit->jit_curpos();
|
||||
Write_Check_VerifyAddr(jit, REG_EAX, true);
|
||||
data->jit_verify_addr_eax = jitpos;
|
||||
@ -1491,6 +1510,7 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
|
||||
jitpos = jit->jit_curpos();
|
||||
Write_BoundsCheck(jit);
|
||||
data->jit_bounds = jitpos;
|
||||
}
|
||||
|
||||
/* Begin opcode browsing */
|
||||
for (; writer.inptr <= endptr;)
|
||||
@ -2153,6 +2173,11 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
|
||||
WriteOp_Halt(jit);
|
||||
break;
|
||||
}
|
||||
case OP_BREAK:
|
||||
{
|
||||
WriteOp_Break(jit);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
AbortCompilation(co);
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
jitoffs_t jit_verify_addr_edx;
|
||||
jitoffs_t jit_chkmargin_heap;
|
||||
jitoffs_t jit_bounds;
|
||||
jitoffs_t jit_break;
|
||||
int inline_level;
|
||||
bool checks;
|
||||
bool debug;
|
||||
@ -53,6 +54,7 @@ public:
|
||||
#define AMX_REG_FRM REG_EBX
|
||||
|
||||
#define AMX_INFO_FRM AMX_REG_INFO //not relocated
|
||||
#define AMX_INFO_FRAME 0 //(same thing as above)
|
||||
#define AMX_INFO_HEAP 4 //not relocated
|
||||
#define AMX_INFO_RETVAL 8 //physical
|
||||
#define AMX_INFO_CONTEXT 12 //physical
|
||||
|
@ -85,7 +85,7 @@ jitoffs_t Write_Execute_Function(JitWriter *jit, bool never_inline)
|
||||
|
||||
/* by now, everything is set up, so we can call into the plugin */
|
||||
//call ecx
|
||||
IA32_Call_Rm(jit, REG_ECX);
|
||||
IA32_Call_Reg(jit, REG_ECX);
|
||||
|
||||
/* if the code flow gets to here, there was a normal return */
|
||||
//mov ebp, [esi+8] - get retval pointer
|
||||
@ -133,6 +133,39 @@ jitoffs_t Write_Execute_Function(JitWriter *jit, bool never_inline)
|
||||
return offs_return;
|
||||
}
|
||||
|
||||
void Write_BreakDebug(JitWriter *jit)
|
||||
{
|
||||
//push ecx
|
||||
//mov ecx, [esi+ctx]
|
||||
//cmp [ecx+dbreak], 0
|
||||
//jnz :nocall
|
||||
IA32_Push_Reg(jit, AMX_REG_TMP);
|
||||
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, dbreak), 0);
|
||||
jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_NZ, 0);
|
||||
|
||||
//pushad
|
||||
IA32_Pushad(jit);
|
||||
|
||||
//push [esi+frm]
|
||||
//push [ecx+context]
|
||||
//mov ecx, [ecx+dbreak]
|
||||
//call ecx
|
||||
//add esp, 8
|
||||
//popad
|
||||
IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_FRAME);
|
||||
IA32_Push_Rm_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, context));
|
||||
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_Add_Rm_Imm8(jit, REG_ESP, 4*2, MOD_REG);
|
||||
IA32_Popad(jit);
|
||||
|
||||
//:nocall
|
||||
IA32_Send_Jump8_Here(jit, jmp);
|
||||
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*1, MOD_REG);
|
||||
IA32_Return(jit);
|
||||
}
|
||||
|
||||
void Write_Error(JitWriter *jit, int error)
|
||||
{
|
||||
CompData *data = (CompData *)jit->data;
|
||||
|
@ -43,6 +43,11 @@ void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg);
|
||||
*/
|
||||
void Write_BoundsCheck(JitWriter *jit);
|
||||
|
||||
/**
|
||||
* Writes the break debug function.
|
||||
*/
|
||||
void Write_BreakDebug(JitWriter *jit);
|
||||
|
||||
/**
|
||||
* These are for writing the PushN opcodes.
|
||||
*/
|
||||
@ -190,7 +195,7 @@ typedef enum
|
||||
OP_NOP, //DONE
|
||||
OP_SYSREQ_N,
|
||||
OP_SYMTAG, //DEPRECATED
|
||||
OP_BREAK,
|
||||
OP_BREAK, //DONE
|
||||
OP_PUSH2_C, //DONE
|
||||
OP_PUSH2, //DONE
|
||||
OP_PUSH2_S, //DONE
|
||||
|
@ -114,11 +114,14 @@
|
||||
#define IA32_LEA_REG_MEM 0x8D // encoding is /r
|
||||
#define IA32_POP_REG 0x58 // encoding is +r
|
||||
#define IA32_PUSH_REG 0x50 // encoding is +r
|
||||
#define IA32_PUSH_RM 0xFF // encoding is /6
|
||||
#define IA32_REP 0xF3 // no extra encoding
|
||||
#define IA32_MOVSD 0xA5 // no extra encoding
|
||||
#define IA32_MOVSB 0xA4 // no extra encoding
|
||||
#define IA32_STOSD 0xAB // no extra encoding
|
||||
#define IA32_CLD 0xFC // no extra encoding
|
||||
#define IA32_PUSHAD 0x60 // no extra encoding
|
||||
#define IA32_POPAD 0x61 // no extra encoding
|
||||
|
||||
inline jit_uint8_t ia32_modrm(jit_uint8_t mode, jit_uint8_t reg, jit_uint8_t rm)
|
||||
{
|
||||
@ -568,6 +571,23 @@ inline void IA32_Push_Reg(JitWriter *jit, jit_uint8_t reg)
|
||||
jit->write_ubyte(IA32_PUSH_REG+reg);
|
||||
}
|
||||
|
||||
inline void IA32_Pushad(JitWriter *jit)
|
||||
{
|
||||
jit->write_ubyte(IA32_PUSHAD);
|
||||
}
|
||||
|
||||
inline void IA32_Popad(JitWriter *jit)
|
||||
{
|
||||
jit->write_ubyte(IA32_POPAD);
|
||||
}
|
||||
|
||||
inline void IA32_Push_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t disp8)
|
||||
{
|
||||
jit->write_ubyte(IA32_PUSH_RM);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, reg));
|
||||
jit->write_ubyte(disp8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moving from REGISTER/MEMORY to REGISTER
|
||||
*/
|
||||
@ -771,7 +791,7 @@ inline jitoffs_t IA32_Call_Imm32(JitWriter *jit, jit_int32_t disp)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline void IA32_Call_Rm(JitWriter *jit, jit_uint8_t reg)
|
||||
inline void IA32_Call_Reg(JitWriter *jit, jit_uint8_t reg)
|
||||
{
|
||||
jit->write_ubyte(IA32_CALL_RM);
|
||||
jit->write_ubyte(ia32_modrm(MOD_REG, 2, reg));
|
||||
@ -853,6 +873,14 @@ inline void IA32_Cmp_Rm_Imm32(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm,
|
||||
jit->write_int32(imm32);
|
||||
}
|
||||
|
||||
inline void IA32_Cmp_Rm_Imm32_Disp8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t disp8, jit_int32_t imm32)
|
||||
{
|
||||
jit->write_ubyte(IA32_CMP_RM_IMM32);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg));
|
||||
jit->write_ubyte(disp8);
|
||||
jit->write_int32(imm32);
|
||||
}
|
||||
|
||||
inline void IA32_Cmp_Rm_Disp8_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp, jit_int8_t imm8)
|
||||
{
|
||||
jit->write_ubyte(IA32_CMP_RM_IMM8);
|
||||
|
Loading…
Reference in New Issue
Block a user