[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86_emulate: Emulate ENTER and LEAVE instructions.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1196253859 0 # Node ID cca2f2fb857d5dce7c435e92b8fc105d388f4f5d # Parent 3fdbdd131fc7c64cacf99e2dd9eda40ca3ed40bb x86_emulate: Emulate ENTER and LEAVE instructions. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/x86_emulate.c | 59 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 58 insertions(+), 1 deletion(-) diff -r 3fdbdd131fc7 -r cca2f2fb857d xen/arch/x86/x86_emulate.c --- a/xen/arch/x86/x86_emulate.c Wed Nov 28 12:42:17 2007 +0000 +++ b/xen/arch/x86/x86_emulate.c Wed Nov 28 12:44:19 2007 +0000 @@ -152,7 +152,7 @@ static uint8_t opcode_table[256] = { DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov, /* 0xC8 - 0xCF */ - 0, 0, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0xD0 - 0xD7 */ ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, @@ -2263,6 +2263,63 @@ x86_emulate( break; } + case 0xc8: /* enter imm16,imm8 */ { + uint16_t size = insn_fetch_type(uint16_t); + uint8_t depth = insn_fetch_type(uint8_t) & 31; + int i; + + dst.type = OP_REG; + dst.bytes = (mode_64bit() && (op_bytes == 4)) ? 8 : op_bytes; + dst.reg = (unsigned long *)&_regs.ebp; + if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes), + _regs.ebp, dst.bytes, ctxt)) ) + goto done; + dst.val = _regs.esp; + + if ( depth > 0 ) + { + for ( i = 1; i < depth; i++ ) + { + unsigned long ebp, temp_data; + ebp = _truncate_ea(_regs.ebp - i*dst.bytes, ctxt->sp_size/8); + if ( (rc = ops->read(x86_seg_ss, ebp, + &temp_data, dst.bytes, ctxt)) || + (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes), + temp_data, dst.bytes, ctxt)) ) + goto done; + } + if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes), + dst.val, dst.bytes, ctxt)) ) + goto done; + } + + sp_pre_dec(size); + break; + } + + case 0xc9: /* leave */ + /* First writeback, to %%esp. */ + dst.type = OP_REG; + dst.bytes = (mode_64bit() && (op_bytes == 4)) ? 8 : op_bytes; + dst.reg = (unsigned long *)&_regs.esp; + dst.val = _regs.ebp; + + /* Flush first writeback, since there is a second. */ + switch ( dst.bytes ) + { + case 1: *(uint8_t *)dst.reg = (uint8_t)dst.val; break; + case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break; + case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */ + case 8: *dst.reg = dst.val; break; + } + + /* Second writeback, to %%ebp. */ + dst.reg = (unsigned long *)&_regs.ebp; + if ( (rc = ops->read(x86_seg_ss, sp_post_inc(dst.bytes), + &dst.val, dst.bytes, ctxt)) ) + goto done; + break; + case 0xca: /* ret imm16 (far) */ case 0xcb: /* ret (far) */ { int offset = (b == 0xca) ? insn_fetch_type(uint16_t) : 0; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |