sketched out break opcode

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4091
This commit is contained in:
David Anderson 2006-09-21 05:04:51 +00:00
parent 9ba07e4b28
commit 1bf17b05bb
6 changed files with 122 additions and 19 deletions

View File

@ -175,10 +175,20 @@ typedef struct sp_debug_symbol_s
sp_fdbg_symbol_t *sym; /* pointer to original symbol */ sp_fdbg_symbol_t *sym; /* pointer to original symbol */
} sp_debug_symbol_t; } sp_debug_symbol_t;
namespace SourcePawn
{
class IPluginContext;
class IVirtualMachine;
};
/** /**
* Breaks into a debugger * 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 */ #define SPFLAG_PLUGIN_DEBUG (1<<0) /* plugin is in debug mode */
@ -193,8 +203,8 @@ typedef struct sp_context_s
/* general/parent information */ /* general/parent information */
void *base; /* base of generated code and memory */ void *base; /* base of generated code and memory */
sp_plugin_t *plugin; /* pointer back to parent information */ sp_plugin_t *plugin; /* pointer back to parent information */
void *context; /* pointer to IPluginContext */ SourcePawn::IPluginContext *context; /* pointer to IPluginContext */
void *vmbase; /* pointer to IVirtualMachine */ SourcePawn::IVirtualMachine *vmbase; /* pointer to IVirtualMachine */
void *user[4]; /* user specific pointers */ void *user[4]; /* user specific pointers */
void *vm[4]; /* VM specific pointers */ void *vm[4]; /* VM specific pointers */
uint32_t flags; /* compilation flags */ uint32_t flags; /* compilation flags */

View File

@ -1382,6 +1382,23 @@ inline void WriteOp_Halt(JitWriter *jit)
IA32_Write_Jump32(jit, reloc, data->jit_return); 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); data->jit_return = Write_Execute_Function(jit);
/* Write error checking routines in case they are needed */ /* Write error checking routines in case they are needed */
if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
{
jitpos = jit->jit_curpos(); jitpos = jit->jit_curpos();
Write_Check_VerifyAddr(jit, REG_EAX, true); Write_Check_VerifyAddr(jit, REG_EAX, true);
data->jit_verify_addr_eax = jitpos; data->jit_verify_addr_eax = jitpos;
@ -1491,6 +1510,7 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
jitpos = jit->jit_curpos(); jitpos = jit->jit_curpos();
Write_BoundsCheck(jit); Write_BoundsCheck(jit);
data->jit_bounds = jitpos; data->jit_bounds = jitpos;
}
/* Begin opcode browsing */ /* Begin opcode browsing */
for (; writer.inptr <= endptr;) for (; writer.inptr <= endptr;)
@ -2153,6 +2173,11 @@ IPluginContext *JITX86::CompileToContext(ICompilation *co, int *err)
WriteOp_Halt(jit); WriteOp_Halt(jit);
break; break;
} }
case OP_BREAK:
{
WriteOp_Break(jit);
break;
}
default: default:
{ {
AbortCompilation(co); AbortCompilation(co);

View File

@ -25,6 +25,7 @@ public:
jitoffs_t jit_verify_addr_edx; jitoffs_t jit_verify_addr_edx;
jitoffs_t jit_chkmargin_heap; jitoffs_t jit_chkmargin_heap;
jitoffs_t jit_bounds; jitoffs_t jit_bounds;
jitoffs_t jit_break;
int inline_level; int inline_level;
bool checks; bool checks;
bool debug; bool debug;
@ -53,6 +54,7 @@ public:
#define AMX_REG_FRM REG_EBX #define AMX_REG_FRM REG_EBX
#define AMX_INFO_FRM AMX_REG_INFO //not relocated #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_HEAP 4 //not relocated
#define AMX_INFO_RETVAL 8 //physical #define AMX_INFO_RETVAL 8 //physical
#define AMX_INFO_CONTEXT 12 //physical #define AMX_INFO_CONTEXT 12 //physical

View File

@ -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 */ /* by now, everything is set up, so we can call into the plugin */
//call ecx //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 */ /* if the code flow gets to here, there was a normal return */
//mov ebp, [esi+8] - get retval pointer //mov ebp, [esi+8] - get retval pointer
@ -133,6 +133,39 @@ jitoffs_t Write_Execute_Function(JitWriter *jit, bool never_inline)
return offs_return; 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) void Write_Error(JitWriter *jit, int error)
{ {
CompData *data = (CompData *)jit->data; CompData *data = (CompData *)jit->data;

View File

@ -43,6 +43,11 @@ void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg);
*/ */
void Write_BoundsCheck(JitWriter *jit); void Write_BoundsCheck(JitWriter *jit);
/**
* Writes the break debug function.
*/
void Write_BreakDebug(JitWriter *jit);
/** /**
* These are for writing the PushN opcodes. * These are for writing the PushN opcodes.
*/ */
@ -190,7 +195,7 @@ typedef enum
OP_NOP, //DONE OP_NOP, //DONE
OP_SYSREQ_N, OP_SYSREQ_N,
OP_SYMTAG, //DEPRECATED OP_SYMTAG, //DEPRECATED
OP_BREAK, OP_BREAK, //DONE
OP_PUSH2_C, //DONE OP_PUSH2_C, //DONE
OP_PUSH2, //DONE OP_PUSH2, //DONE
OP_PUSH2_S, //DONE OP_PUSH2_S, //DONE

View File

@ -114,11 +114,14 @@
#define IA32_LEA_REG_MEM 0x8D // encoding is /r #define IA32_LEA_REG_MEM 0x8D // encoding is /r
#define IA32_POP_REG 0x58 // encoding is +r #define IA32_POP_REG 0x58 // encoding is +r
#define IA32_PUSH_REG 0x50 // 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_REP 0xF3 // no extra encoding
#define IA32_MOVSD 0xA5 // no extra encoding #define IA32_MOVSD 0xA5 // no extra encoding
#define IA32_MOVSB 0xA4 // no extra encoding #define IA32_MOVSB 0xA4 // no extra encoding
#define IA32_STOSD 0xAB // no extra encoding #define IA32_STOSD 0xAB // no extra encoding
#define IA32_CLD 0xFC // 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) 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); 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 * Moving from REGISTER/MEMORY to REGISTER
*/ */
@ -771,7 +791,7 @@ inline jitoffs_t IA32_Call_Imm32(JitWriter *jit, jit_int32_t disp)
return ptr; 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_CALL_RM);
jit->write_ubyte(ia32_modrm(MOD_REG, 2, reg)); 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); 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) 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); jit->write_ubyte(IA32_CMP_RM_IMM8);