[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86_emulate: Emulate far call/jmp. This completes emulation of Grp5.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1195994593 0 # Node ID d40788f07a4f40ac95c1f297f808c63b85baa3ff # Parent a194083696d5dbd9b7509d35924e48aa05678607 x86_emulate: Emulate far call/jmp. This completes emulation of Grp5. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/x86_emulate.c | 54 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 53 insertions(+), 1 deletion(-) diff -r a194083696d5 -r d40788f07a4f xen/arch/x86/x86_emulate.c --- a/xen/arch/x86/x86_emulate.c Sun Nov 25 11:45:02 2007 +0000 +++ b/xen/arch/x86/x86_emulate.c Sun Nov 25 12:43:13 2007 +0000 @@ -126,7 +126,8 @@ static uint8_t opcode_table[256] = { ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0x98 - 0x9F */ - ImplicitOps, ImplicitOps, 0, 0, 0, 0, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, 0, + 0, 0, ImplicitOps, ImplicitOps, /* 0xA0 - 0xA7 */ ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, @@ -1687,6 +1688,33 @@ x86_emulate( if ( (modrm_reg & 7) == 2 ) goto push; /* call */ break; + case 3: /* call (far, absolute indirect) */ + case 5: /* jmp (far, absolute indirect) */ { + unsigned long sel, eip = dst.val; + + if ( (rc = ops->read(dst.mem.seg, dst.mem.off+dst.bytes, + &sel, 2, ctxt)) ) + goto done; + + if ( (modrm_reg & 7) == 3 ) /* call */ + { + struct segment_register reg; + fail_if(ops->read_segment == NULL); + if ( (rc = ops->read_segment(x86_seg_cs, ®, ctxt)) || + (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), + reg.sel, op_bytes, ctxt)) || + (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), + _regs.eip, op_bytes, ctxt)) ) + goto done; + } + + if ( (rc = load_seg(x86_seg_cs, sel, ctxt, ops)) != 0 ) + goto done; + _regs.eip = eip; + + dst.type = OP_NONE; + break; + } case 6: /* push */ /* 64-bit mode: PUSH defaults to a 64-bit operand. */ if ( mode_64bit() && (dst.bytes == 4) ) @@ -2023,6 +2051,30 @@ x86_emulate( break; } break; + + case 0x9a: /* call (far, absolute) */ { + struct segment_register reg; + uint16_t sel; + uint32_t eip; + + fail_if(ops->read_segment == NULL); + generate_exception_if(mode_64bit(), EXC_UD); + + eip = insn_fetch_bytes(op_bytes); + sel = insn_fetch_type(uint16_t); + + if ( (rc = ops->read_segment(x86_seg_cs, ®, ctxt)) || + (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), + reg.sel, op_bytes, ctxt)) || + (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), + _regs.eip, op_bytes, ctxt)) ) + goto done; + + if ( (rc = load_seg(x86_seg_cs, sel, ctxt, ops)) != 0 ) + goto done; + _regs.eip = eip; + break; + } case 0x9e: /* sahf */ *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |