Restore #gp when accessing null segment, only non-jit (fixes Windows 95 and 98)
This commit is contained in:
parent
107c6fef36
commit
1ea2209499
|
@ -421,7 +421,7 @@ pub unsafe fn iret(is_16: bool) {
|
|||
}
|
||||
|
||||
switch_cs_real_mode(new_cs);
|
||||
*instruction_pointer = get_seg(CS) + new_eip;
|
||||
*instruction_pointer = get_seg_cs() + new_eip;
|
||||
|
||||
if is_16 {
|
||||
update_eflags(new_flags | *flags & !0xFFFF);
|
||||
|
@ -474,7 +474,7 @@ pub unsafe fn iret(is_16: bool) {
|
|||
*flags |= FLAG_VM;
|
||||
|
||||
switch_cs_real_mode(new_cs);
|
||||
*instruction_pointer = get_seg(CS) + (new_eip & 0xFFFF);
|
||||
*instruction_pointer = get_seg_cs() + (new_eip & 0xFFFF);
|
||||
|
||||
if !switch_seg(ES, new_es)
|
||||
|| !switch_seg(DS, new_ds)
|
||||
|
@ -654,7 +654,7 @@ pub unsafe fn iret(is_16: bool) {
|
|||
*segment_limits.offset(CS as isize) = cs_descriptor.effective_limit();
|
||||
*segment_offsets.offset(CS as isize) = cs_descriptor.base();
|
||||
|
||||
*instruction_pointer = new_eip + get_seg(CS);
|
||||
*instruction_pointer = new_eip + get_seg_cs();
|
||||
|
||||
// iret end
|
||||
|
||||
|
@ -941,7 +941,7 @@ pub unsafe fn call_interrupt_vector(
|
|||
*segment_limits.offset(CS as isize) = cs_segment_descriptor.effective_limit();
|
||||
*segment_offsets.offset(CS as isize) = cs_segment_descriptor.base();
|
||||
|
||||
*instruction_pointer = get_seg(CS) + offset;
|
||||
*instruction_pointer = get_seg_cs() + offset;
|
||||
|
||||
*flags &= !FLAG_NT & !FLAG_VM & !FLAG_RF & !FLAG_TRAP;
|
||||
|
||||
|
@ -977,7 +977,7 @@ pub unsafe fn call_interrupt_vector(
|
|||
*flags &= !FLAG_INTERRUPT & !FLAG_AC & !FLAG_TRAP;
|
||||
|
||||
switch_cs_real_mode(new_cs);
|
||||
*instruction_pointer = get_seg(CS) + new_ip;
|
||||
*instruction_pointer = get_seg_cs() + new_ip;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1663,15 +1663,17 @@ pub unsafe fn assert_seg_non_null(segment: i32) {
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_seg(segment: i32) -> i32 {
|
||||
pub unsafe fn get_seg(segment: i32) -> OrPageFault<i32> {
|
||||
dbg_assert!(segment >= 0 && segment < 8);
|
||||
if *segment_is_null.offset(segment as isize) {
|
||||
dbg_assert!(segment != CS && segment != SS);
|
||||
dbg_log!("#gp: Access null segment");
|
||||
assert!(false);
|
||||
//trigger_gp(0); // TODO
|
||||
dbg_trace();
|
||||
dbg_assert!(!in_jit, "TODO");
|
||||
trigger_gp(0);
|
||||
return Err(());
|
||||
}
|
||||
return *segment_offsets.offset(segment as isize);
|
||||
return Ok(*segment_offsets.offset(segment as isize));
|
||||
}
|
||||
|
||||
pub unsafe fn set_cr0(cr0: i32) {
|
||||
|
@ -1783,12 +1785,12 @@ pub unsafe fn get_seg_cs() -> i32 { return *segment_offsets.offset(CS as isize);
|
|||
#[no_mangle]
|
||||
pub unsafe fn get_seg_ss() -> i32 { return *segment_offsets.offset(SS as isize); }
|
||||
|
||||
pub unsafe fn get_seg_prefix(default_segment: i32) -> i32 {
|
||||
pub unsafe fn get_seg_prefix(default_segment: i32) -> OrPageFault<i32> {
|
||||
dbg_assert!(!in_jit);
|
||||
let prefix = *prefixes as i32 & PREFIX_MASK_SEGMENT;
|
||||
if 0 != prefix {
|
||||
if prefix == SEG_PREFIX_ZERO {
|
||||
return 0;
|
||||
return Ok(0);
|
||||
}
|
||||
else {
|
||||
return get_seg(prefix - 1);
|
||||
|
@ -1799,9 +1801,13 @@ pub unsafe fn get_seg_prefix(default_segment: i32) -> i32 {
|
|||
};
|
||||
}
|
||||
|
||||
pub unsafe fn get_seg_prefix_ds(offset: i32) -> i32 { return get_seg_prefix(DS) + offset; }
|
||||
pub unsafe fn get_seg_prefix_ds(offset: i32) -> OrPageFault<i32> {
|
||||
Ok(get_seg_prefix(DS)? + offset)
|
||||
}
|
||||
|
||||
pub unsafe fn get_seg_prefix_ss(offset: i32) -> i32 { return get_seg_prefix(SS) + offset; }
|
||||
pub unsafe fn get_seg_prefix_ss(offset: i32) -> OrPageFault<i32> {
|
||||
Ok(get_seg_prefix(SS)? + offset)
|
||||
}
|
||||
|
||||
pub unsafe fn modrm_resolve(modrm_byte: i32) -> OrPageFault<i32> {
|
||||
if is_asize_32() { resolve_modrm32(modrm_byte) } else { resolve_modrm16(modrm_byte) }
|
||||
|
|
|
@ -928,11 +928,15 @@ pub unsafe fn instr16_6D() { insw_no_rep(is_asize_32()); }
|
|||
#[no_mangle]
|
||||
pub unsafe fn instr32_6D() { insd_no_rep(is_asize_32()); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_6E() { outsb_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_6E() { outsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_6F() { outsw_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_6F() {
|
||||
outsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_6F() { outsd_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_6F() {
|
||||
outsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_80_0_mem(addr: i32, imm: i32) {
|
||||
SAFE_READ_WRITE8!(___, addr, add8(___, imm));
|
||||
|
@ -1575,25 +1579,25 @@ pub unsafe fn instr_9F() {
|
|||
#[no_mangle]
|
||||
pub unsafe fn instr_A0(moffs: i32) {
|
||||
// mov
|
||||
let data = return_on_pagefault!(safe_read8(get_seg_prefix_ds(moffs)));
|
||||
let data = return_on_pagefault!(safe_read8(return_on_pagefault!(get_seg_prefix_ds(moffs))));
|
||||
*reg8.offset(AL as isize) = data as u8;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_A1(moffs: i32) {
|
||||
// mov
|
||||
let data = return_on_pagefault!(safe_read16(get_seg_prefix_ds(moffs)));
|
||||
let data = return_on_pagefault!(safe_read16(return_on_pagefault!(get_seg_prefix_ds(moffs))));
|
||||
*reg16.offset(AX as isize) = data as u16;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_A1(moffs: i32) {
|
||||
let data = return_on_pagefault!(safe_read32s(get_seg_prefix_ds(moffs)));
|
||||
let data = return_on_pagefault!(safe_read32s(return_on_pagefault!(get_seg_prefix_ds(moffs))));
|
||||
*reg32.offset(EAX as isize) = data;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_A2(moffs: i32) {
|
||||
// mov
|
||||
return_on_pagefault!(safe_write8(
|
||||
get_seg_prefix_ds(moffs),
|
||||
return_on_pagefault!(get_seg_prefix_ds(moffs)),
|
||||
*reg8.offset(AL as isize) as i32
|
||||
));
|
||||
}
|
||||
|
@ -1601,29 +1605,37 @@ pub unsafe fn instr_A2(moffs: i32) {
|
|||
pub unsafe fn instr16_A3(moffs: i32) {
|
||||
// mov
|
||||
return_on_pagefault!(safe_write16(
|
||||
get_seg_prefix_ds(moffs),
|
||||
return_on_pagefault!(get_seg_prefix_ds(moffs)),
|
||||
*reg16.offset(AX as isize) as i32
|
||||
));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_A3(moffs: i32) {
|
||||
return_on_pagefault!(safe_write32(
|
||||
get_seg_prefix_ds(moffs),
|
||||
return_on_pagefault!(get_seg_prefix_ds(moffs)),
|
||||
*reg32.offset(EAX as isize)
|
||||
));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_A4() { movsb_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_A4() { movsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_A5() { movsw_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_A5() {
|
||||
movsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_A5() { movsd_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_A5() {
|
||||
movsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_A6() { cmpsb_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_A6() { cmpsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_A7() { cmpsw_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_A7() {
|
||||
cmpsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_A7() { cmpsd_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_A7() {
|
||||
cmpsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_A8(imm8: i32) { test8(*reg8.offset(AL as isize) as i32, imm8); }
|
||||
#[no_mangle]
|
||||
|
@ -1637,11 +1649,15 @@ pub unsafe fn instr16_AB() { stosw_no_rep(is_asize_32()); }
|
|||
#[no_mangle]
|
||||
pub unsafe fn instr32_AB() { stosd_no_rep(is_asize_32()); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_AC() { lodsb_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_AC() { lodsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_AD() { lodsw_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_AD() {
|
||||
lodsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_AD() { lodsd_no_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_AD() {
|
||||
lodsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_AE() { scasb_no_rep(is_asize_32()); }
|
||||
#[no_mangle]
|
||||
|
@ -2426,12 +2442,14 @@ pub unsafe fn instr_D7() {
|
|||
dbg_assert!(!in_jit, "TODO");
|
||||
if is_asize_32() {
|
||||
*reg8.offset(AL as isize) = return_on_pagefault!(safe_read8(
|
||||
get_seg_prefix(DS) + *reg32.offset(EBX as isize) + *reg8.offset(AL as isize) as i32,
|
||||
return_on_pagefault!(get_seg_prefix(DS))
|
||||
+ *reg32.offset(EBX as isize)
|
||||
+ *reg8.offset(AL as isize) as i32,
|
||||
)) as u8
|
||||
}
|
||||
else {
|
||||
*reg8.offset(AL as isize) = return_on_pagefault!(safe_read8(
|
||||
get_seg_prefix(DS)
|
||||
return_on_pagefault!(get_seg_prefix(DS))
|
||||
+ (*reg16.offset(BX as isize) as i32 + *reg8.offset(AL as isize) as i32 & 0xFFFF),
|
||||
)) as u8
|
||||
};
|
||||
|
@ -3031,17 +3049,17 @@ pub unsafe fn instr32_F26D() { insd_rep(is_asize_32()); }
|
|||
#[no_mangle]
|
||||
pub unsafe fn instr32_F36D() { insd_rep(is_asize_32()); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F26E() { outsb_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_F26E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F36E() { outsb_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_F36E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_F26F() { outsw_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_F26F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_F36F() { outsw_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_F36F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_F26F() { outsd_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_F26F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_F36F() { outsd_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_F36F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_70(imm8: i32) { jmpcc16(test_o(), imm8); }
|
||||
#[no_mangle]
|
||||
|
@ -3107,29 +3125,65 @@ pub unsafe fn instr32_7E(imm8: i32) { jmpcc32(test_le(), imm8); }
|
|||
#[no_mangle]
|
||||
pub unsafe fn instr32_7F(imm8: i32) { jmpcc32(!test_le(), imm8); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F2A4() { movsb_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_F2A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F3A4() { movsb_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_F3A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_F2A5() { movsw_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_F2A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_F3A5() { movsw_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_F3A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_F2A5() { movsd_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_F2A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_F3A5() { movsd_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_F3A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F2A6() { cmpsb_rep(PREFIX_F2, is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_F2A6() {
|
||||
cmpsb_rep(
|
||||
PREFIX_F2,
|
||||
is_asize_32(),
|
||||
return_on_pagefault!(get_seg_prefix(DS)),
|
||||
);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F3A6() { cmpsb_rep(PREFIX_F3, is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_F3A6() {
|
||||
cmpsb_rep(
|
||||
PREFIX_F3,
|
||||
is_asize_32(),
|
||||
return_on_pagefault!(get_seg_prefix(DS)),
|
||||
);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_F2A7() { cmpsw_rep(PREFIX_F2, is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_F2A7() {
|
||||
cmpsw_rep(
|
||||
PREFIX_F2,
|
||||
is_asize_32(),
|
||||
return_on_pagefault!(get_seg_prefix(DS)),
|
||||
);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_F3A7() { cmpsw_rep(PREFIX_F3, is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_F3A7() {
|
||||
cmpsw_rep(
|
||||
PREFIX_F3,
|
||||
is_asize_32(),
|
||||
return_on_pagefault!(get_seg_prefix(DS)),
|
||||
);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_F2A7() { cmpsd_rep(PREFIX_F2, is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_F2A7() {
|
||||
cmpsd_rep(
|
||||
PREFIX_F2,
|
||||
is_asize_32(),
|
||||
return_on_pagefault!(get_seg_prefix(DS)),
|
||||
);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_F3A7() { cmpsd_rep(PREFIX_F3, is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_F3A7() {
|
||||
cmpsd_rep(
|
||||
PREFIX_F3,
|
||||
is_asize_32(),
|
||||
return_on_pagefault!(get_seg_prefix(DS)),
|
||||
);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F2AA() { stosb_rep(is_asize_32()); }
|
||||
#[no_mangle]
|
||||
|
@ -3143,17 +3197,17 @@ pub unsafe fn instr32_F2AB() { stosd_rep(is_asize_32()); }
|
|||
#[no_mangle]
|
||||
pub unsafe fn instr32_F3AB() { stosd_rep(is_asize_32()); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F2AC() { lodsb_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_F2AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F3AC() { lodsb_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr_F3AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_F2AD() { lodsw_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_F2AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_F3AD() { lodsw_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr16_F3AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_F2AD() { lodsd_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_F2AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr32_F3AD() { lodsd_rep(is_asize_32(), get_seg_prefix(DS)); }
|
||||
pub unsafe fn instr32_F3AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_F2AE() { scasb_rep(PREFIX_F2, is_asize_32()); }
|
||||
#[no_mangle]
|
||||
|
|
|
@ -4967,7 +4967,11 @@ pub unsafe fn maskmovq(r1: i32, r2: i32, addr: i32) {
|
|||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0FF7_reg(r1: i32, r2: i32) {
|
||||
maskmovq(r1, r2, get_seg_prefix(DS) + get_reg_asize(EDI))
|
||||
maskmovq(
|
||||
r1,
|
||||
r2,
|
||||
return_on_pagefault!(get_seg_prefix_ds(get_reg_asize(EDI))),
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -4996,7 +5000,11 @@ pub unsafe fn maskmovdqu(r1: i32, r2: i32, addr: i32) {
|
|||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_660FF7_reg(r1: i32, r2: i32) {
|
||||
maskmovdqu(r1, r2, get_seg_prefix(DS) + get_reg_asize(EDI))
|
||||
maskmovdqu(
|
||||
r1,
|
||||
r2,
|
||||
return_on_pagefault!(get_seg_prefix_ds(get_reg_asize(EDI))),
|
||||
)
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_0FF8(source: reg64, r: i32) {
|
||||
|
|
|
@ -6,81 +6,81 @@ pub unsafe fn resolve_modrm16(modrm_byte: i32) -> OrPageFault<i32> {
|
|||
Ok(match modrm_byte {
|
||||
0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 => get_seg_prefix_ds(
|
||||
*reg16.offset(BX as isize) as i32 + *reg16.offset(SI as isize) as i32 & 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
64 | 72 | 80 | 88 | 96 | 104 | 112 | 120 => get_seg_prefix_ds(
|
||||
*reg16.offset(BX as isize) as i32 + *reg16.offset(SI as isize) as i32 + read_imm8s()?
|
||||
& 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
128 | 136 | 144 | 152 | 160 | 168 | 176 | 184 => get_seg_prefix_ds(
|
||||
*reg16.offset(BX as isize) as i32 + *reg16.offset(SI as isize) as i32 + read_imm16()?
|
||||
& 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 => get_seg_prefix_ds(
|
||||
*reg16.offset(BX as isize) as i32 + *reg16.offset(DI as isize) as i32 & 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
65 | 73 | 81 | 89 | 97 | 105 | 113 | 121 => get_seg_prefix_ds(
|
||||
*reg16.offset(BX as isize) as i32 + *reg16.offset(DI as isize) as i32 + read_imm8s()?
|
||||
& 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
129 | 137 | 145 | 153 | 161 | 169 | 177 | 185 => get_seg_prefix_ds(
|
||||
*reg16.offset(BX as isize) as i32 + *reg16.offset(DI as isize) as i32 + read_imm16()?
|
||||
& 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 => get_seg_prefix_ss(
|
||||
*reg16.offset(BP as isize) as i32 + *reg16.offset(SI as isize) as i32 & 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
66 | 74 | 82 | 90 | 98 | 106 | 114 | 122 => get_seg_prefix_ss(
|
||||
*reg16.offset(BP as isize) as i32 + *reg16.offset(SI as isize) as i32 + read_imm8s()?
|
||||
& 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
130 | 138 | 146 | 154 | 162 | 170 | 178 | 186 => get_seg_prefix_ss(
|
||||
*reg16.offset(BP as isize) as i32 + *reg16.offset(SI as isize) as i32 + read_imm16()?
|
||||
& 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 => get_seg_prefix_ss(
|
||||
*reg16.offset(BP as isize) as i32 + *reg16.offset(DI as isize) as i32 & 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
67 | 75 | 83 | 91 | 99 | 107 | 115 | 123 => get_seg_prefix_ss(
|
||||
*reg16.offset(BP as isize) as i32 + *reg16.offset(DI as isize) as i32 + read_imm8s()?
|
||||
& 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
131 | 139 | 147 | 155 | 163 | 171 | 179 | 187 => get_seg_prefix_ss(
|
||||
*reg16.offset(BP as isize) as i32 + *reg16.offset(DI as isize) as i32 + read_imm16()?
|
||||
& 0xFFFF,
|
||||
),
|
||||
)?,
|
||||
4 | 12 | 20 | 28 | 36 | 44 | 52 | 60 => {
|
||||
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 & 0xFFFF)
|
||||
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 & 0xFFFF)?
|
||||
},
|
||||
68 | 76 | 84 | 92 | 100 | 108 | 116 | 124 => {
|
||||
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 + read_imm8s()? & 0xFFFF)
|
||||
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 + read_imm8s()? & 0xFFFF)?
|
||||
},
|
||||
132 | 140 | 148 | 156 | 164 | 172 | 180 | 188 => {
|
||||
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 + read_imm16()? & 0xFFFF)
|
||||
get_seg_prefix_ds(*reg16.offset(SI as isize) as i32 + read_imm16()? & 0xFFFF)?
|
||||
},
|
||||
5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 => {
|
||||
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 & 0xFFFF)
|
||||
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 & 0xFFFF)?
|
||||
},
|
||||
69 | 77 | 85 | 93 | 101 | 109 | 117 | 125 => {
|
||||
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 + read_imm8s()? & 0xFFFF)
|
||||
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 + read_imm8s()? & 0xFFFF)?
|
||||
},
|
||||
133 | 141 | 149 | 157 | 165 | 173 | 181 | 189 => {
|
||||
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 + read_imm16()? & 0xFFFF)
|
||||
get_seg_prefix_ds(*reg16.offset(DI as isize) as i32 + read_imm16()? & 0xFFFF)?
|
||||
},
|
||||
6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(read_imm16()?),
|
||||
6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(read_imm16()?)?,
|
||||
70 | 78 | 86 | 94 | 102 | 110 | 118 | 126 => {
|
||||
get_seg_prefix_ss(*reg16.offset(BP as isize) as i32 + read_imm8s()? & 0xFFFF)
|
||||
get_seg_prefix_ss(*reg16.offset(BP as isize) as i32 + read_imm8s()? & 0xFFFF)?
|
||||
},
|
||||
134 | 142 | 150 | 158 | 166 | 174 | 182 | 190 => {
|
||||
get_seg_prefix_ss(*reg16.offset(BP as isize) as i32 + read_imm16()? & 0xFFFF)
|
||||
get_seg_prefix_ss(*reg16.offset(BP as isize) as i32 + read_imm16()? & 0xFFFF)?
|
||||
},
|
||||
7 | 15 | 23 | 31 | 39 | 47 | 55 | 63 => {
|
||||
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 & 0xFFFF)
|
||||
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 & 0xFFFF)?
|
||||
},
|
||||
71 | 79 | 87 | 95 | 103 | 111 | 119 | 127 => {
|
||||
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 + read_imm8s()? & 0xFFFF)
|
||||
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 + read_imm8s()? & 0xFFFF)?
|
||||
},
|
||||
135 | 143 | 151 | 159 | 167 | 175 | 183 | 191 => {
|
||||
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 + read_imm16()? & 0xFFFF)
|
||||
get_seg_prefix_ds(*reg16.offset(BX as isize) as i32 + read_imm16()? & 0xFFFF)?
|
||||
},
|
||||
_ => {
|
||||
dbg_assert!(false);
|
||||
|
@ -102,23 +102,23 @@ pub unsafe fn resolve_modrm32_(modrm_byte: i32) -> OrPageFault<i32> {
|
|||
}
|
||||
else if r as i32 == 5 {
|
||||
if modrm_byte < 64 {
|
||||
get_seg_prefix_ds(read_imm32s()?)
|
||||
get_seg_prefix_ds(read_imm32s()?)?
|
||||
}
|
||||
else {
|
||||
get_seg_prefix_ss(
|
||||
*reg32.offset(EBP as isize)
|
||||
+ if modrm_byte < 128 { read_imm8s()? } else { read_imm32s()? },
|
||||
)
|
||||
)?
|
||||
}
|
||||
}
|
||||
else if modrm_byte < 64 {
|
||||
get_seg_prefix_ds(*reg32.offset(r as isize))
|
||||
get_seg_prefix_ds(*reg32.offset(r as isize))?
|
||||
}
|
||||
else {
|
||||
get_seg_prefix_ds(
|
||||
*reg32.offset(r as isize)
|
||||
+ if modrm_byte < 128 { read_imm8s()? } else { read_imm32s()? },
|
||||
)
|
||||
)?
|
||||
})
|
||||
}
|
||||
unsafe fn resolve_sib(mod_0: bool) -> OrPageFault<i32> {
|
||||
|
@ -154,62 +154,62 @@ unsafe fn resolve_sib(mod_0: bool) -> OrPageFault<i32> {
|
|||
s = (sib_byte as i32 >> 6 & 3) as u8;
|
||||
offset = *reg32.offset(m as isize) << s as i32
|
||||
}
|
||||
Ok(get_seg_prefix(seg) + base + offset)
|
||||
Ok(get_seg_prefix(seg)? + base + offset)
|
||||
}
|
||||
|
||||
pub unsafe fn resolve_modrm32(modrm_byte: i32) -> OrPageFault<i32> {
|
||||
Ok(match modrm_byte {
|
||||
0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 => get_seg_prefix_ds(*reg32.offset(EAX as isize)),
|
||||
0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 => get_seg_prefix_ds(*reg32.offset(EAX as isize))?,
|
||||
64 | 72 | 80 | 88 | 96 | 104 | 112 | 120 => {
|
||||
get_seg_prefix_ds(*reg32.offset(EAX as isize) + read_imm8s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(EAX as isize) + read_imm8s()?)?
|
||||
},
|
||||
128 | 136 | 144 | 152 | 160 | 168 | 176 | 184 => {
|
||||
get_seg_prefix_ds(*reg32.offset(EAX as isize) + read_imm32s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(EAX as isize) + read_imm32s()?)?
|
||||
},
|
||||
1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 => get_seg_prefix_ds(*reg32.offset(ECX as isize)),
|
||||
1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 => get_seg_prefix_ds(*reg32.offset(ECX as isize))?,
|
||||
65 | 73 | 81 | 89 | 97 | 105 | 113 | 121 => {
|
||||
get_seg_prefix_ds(*reg32.offset(ECX as isize) + read_imm8s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(ECX as isize) + read_imm8s()?)?
|
||||
},
|
||||
129 | 137 | 145 | 153 | 161 | 169 | 177 | 185 => {
|
||||
get_seg_prefix_ds(*reg32.offset(ECX as isize) + read_imm32s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(ECX as isize) + read_imm32s()?)?
|
||||
},
|
||||
2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 => get_seg_prefix_ds(*reg32.offset(EDX as isize)),
|
||||
2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 => get_seg_prefix_ds(*reg32.offset(EDX as isize))?,
|
||||
66 | 74 | 82 | 90 | 98 | 106 | 114 | 122 => {
|
||||
get_seg_prefix_ds(*reg32.offset(EDX as isize) + read_imm8s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(EDX as isize) + read_imm8s()?)?
|
||||
},
|
||||
130 | 138 | 146 | 154 | 162 | 170 | 178 | 186 => {
|
||||
get_seg_prefix_ds(*reg32.offset(EDX as isize) + read_imm32s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(EDX as isize) + read_imm32s()?)?
|
||||
},
|
||||
3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 => get_seg_prefix_ds(*reg32.offset(EBX as isize)),
|
||||
3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 => get_seg_prefix_ds(*reg32.offset(EBX as isize))?,
|
||||
67 | 75 | 83 | 91 | 99 | 107 | 115 | 123 => {
|
||||
get_seg_prefix_ds(*reg32.offset(EBX as isize) + read_imm8s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(EBX as isize) + read_imm8s()?)?
|
||||
},
|
||||
131 | 139 | 147 | 155 | 163 | 171 | 179 | 187 => {
|
||||
get_seg_prefix_ds(*reg32.offset(EBX as isize) + read_imm32s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(EBX as isize) + read_imm32s()?)?
|
||||
},
|
||||
4 | 12 | 20 | 28 | 36 | 44 | 52 | 60 => resolve_sib(false)?,
|
||||
68 | 76 | 84 | 92 | 100 | 108 | 116 | 124 => resolve_sib(true)? + read_imm8s()?,
|
||||
132 | 140 | 148 | 156 | 164 | 172 | 180 | 188 => resolve_sib(true)? + read_imm32s()?,
|
||||
5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 => get_seg_prefix_ds(read_imm32s()?),
|
||||
5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 => get_seg_prefix_ds(read_imm32s()?)?,
|
||||
69 | 77 | 85 | 93 | 101 | 109 | 117 | 125 => {
|
||||
get_seg_prefix_ss(*reg32.offset(EBP as isize) + read_imm8s()?)
|
||||
get_seg_prefix_ss(*reg32.offset(EBP as isize) + read_imm8s()?)?
|
||||
},
|
||||
133 | 141 | 149 | 157 | 165 | 173 | 181 | 189 => {
|
||||
get_seg_prefix_ss(*reg32.offset(EBP as isize) + read_imm32s()?)
|
||||
get_seg_prefix_ss(*reg32.offset(EBP as isize) + read_imm32s()?)?
|
||||
},
|
||||
6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(*reg32.offset(ESI as isize)),
|
||||
6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(*reg32.offset(ESI as isize))?,
|
||||
70 | 78 | 86 | 94 | 102 | 110 | 118 | 126 => {
|
||||
get_seg_prefix_ds(*reg32.offset(ESI as isize) + read_imm8s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(ESI as isize) + read_imm8s()?)?
|
||||
},
|
||||
134 | 142 | 150 | 158 | 166 | 174 | 182 | 190 => {
|
||||
get_seg_prefix_ds(*reg32.offset(ESI as isize) + read_imm32s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(ESI as isize) + read_imm32s()?)?
|
||||
},
|
||||
7 | 15 | 23 | 31 | 39 | 47 | 55 | 63 => get_seg_prefix_ds(*reg32.offset(EDI as isize)),
|
||||
7 | 15 | 23 | 31 | 39 | 47 | 55 | 63 => get_seg_prefix_ds(*reg32.offset(EDI as isize))?,
|
||||
71 | 79 | 87 | 95 | 103 | 111 | 119 | 127 => {
|
||||
get_seg_prefix_ds(*reg32.offset(EDI as isize) + read_imm8s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(EDI as isize) + read_imm8s()?)?
|
||||
},
|
||||
135 | 143 | 151 | 159 | 167 | 175 | 183 | 191 => {
|
||||
get_seg_prefix_ds(*reg32.offset(EDI as isize) + read_imm32s()?)
|
||||
get_seg_prefix_ds(*reg32.offset(EDI as isize) + read_imm32s()?)?
|
||||
},
|
||||
_ => {
|
||||
dbg_assert!(false);
|
||||
|
|
|
@ -50,7 +50,8 @@ pub unsafe fn string_get_cycle_count2(size: i32, addr1: i32, addr2: i32) -> i32
|
|||
#[no_mangle]
|
||||
pub unsafe fn movsb_rep(is_asize_32: bool, ds: i32) {
|
||||
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
|
||||
if count == 0 {
|
||||
|
@ -108,7 +109,8 @@ pub unsafe fn movsb_rep(is_asize_32: bool, ds: i32) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn movsb_no_rep(is_asize_32: bool, ds: i32) {
|
||||
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
return_on_pagefault!(safe_write8(dest, return_on_pagefault!(safe_read8(src))));
|
||||
add_reg_asize(is_asize_32, EDI, size);
|
||||
|
@ -118,7 +120,8 @@ pub unsafe fn movsb_no_rep(is_asize_32: bool, ds: i32) {
|
|||
pub unsafe fn movsw_rep(is_asize_32: bool, ds: i32) {
|
||||
let diff;
|
||||
let mut src: i32 = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
|
||||
if count == 0 {
|
||||
|
@ -179,7 +182,8 @@ pub unsafe fn movsw_rep(is_asize_32: bool, ds: i32) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn movsw_no_rep(is_asize_32: bool, ds: i32) {
|
||||
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
return_on_pagefault!(safe_write16(dest, return_on_pagefault!(safe_read16(src))));
|
||||
add_reg_asize(is_asize_32, EDI, size);
|
||||
|
@ -189,7 +193,8 @@ pub unsafe fn movsw_no_rep(is_asize_32: bool, ds: i32) {
|
|||
pub unsafe fn movsd_rep(is_asize_32: bool, ds: i32) {
|
||||
let diff;
|
||||
let mut src: i32 = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
|
||||
if count == 0 {
|
||||
|
@ -271,7 +276,8 @@ pub unsafe fn movsd_rep(is_asize_32: bool, ds: i32) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn movsd_no_rep(is_asize_32: bool, ds: i32) {
|
||||
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
return_on_pagefault!(safe_write32(dest, return_on_pagefault!(safe_read32s(src))));
|
||||
add_reg_asize(is_asize_32, EDI, size);
|
||||
|
@ -280,7 +286,8 @@ pub unsafe fn movsd_no_rep(is_asize_32: bool, ds: i32) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn cmpsb_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
|
||||
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut data_src;
|
||||
let mut data_dest;
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
|
@ -325,7 +332,8 @@ pub unsafe fn cmpsb_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn cmpsb_no_rep(is_asize_32: bool, ds: i32) {
|
||||
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let data_src;
|
||||
let data_dest;
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
|
@ -339,7 +347,8 @@ pub unsafe fn cmpsb_no_rep(is_asize_32: bool, ds: i32) {
|
|||
pub unsafe fn cmpsw_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
|
||||
let diff;
|
||||
let mut src: i32 = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut data_src;
|
||||
let mut data_dest;
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
|
@ -407,7 +416,8 @@ pub unsafe fn cmpsw_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn cmpsw_no_rep(is_asize_32: bool, ds: i32) {
|
||||
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let data_src;
|
||||
let data_dest;
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
|
@ -421,7 +431,8 @@ pub unsafe fn cmpsw_no_rep(is_asize_32: bool, ds: i32) {
|
|||
pub unsafe fn cmpsd_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
|
||||
let diff;
|
||||
let mut src: i32 = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut data_src;
|
||||
let mut data_dest;
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
|
@ -489,7 +500,8 @@ pub unsafe fn cmpsd_rep(prefix_flag: i32, is_asize_32: bool, ds: i32) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn cmpsd_no_rep(is_asize_32: bool, ds: i32) {
|
||||
let src = ds + if is_asize_32 { read_reg32(ESI) } else { read_reg16(SI) };
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let data_src;
|
||||
let data_dest;
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
|
@ -502,7 +514,8 @@ pub unsafe fn cmpsd_no_rep(is_asize_32: bool, ds: i32) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn stosb_rep(is_asize_32: bool) {
|
||||
let data = *reg8.offset(AL as isize) as i32;
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
|
||||
if count == 0 {
|
||||
|
@ -556,7 +569,8 @@ pub unsafe fn stosb_rep(is_asize_32: bool) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn stosb_no_rep(is_asize_32: bool) {
|
||||
let data = *reg8.offset(AL as isize) as i32;
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
return_on_pagefault!(safe_write8(dest, data));
|
||||
add_reg_asize(is_asize_32, EDI, size);
|
||||
|
@ -565,7 +579,8 @@ pub unsafe fn stosb_no_rep(is_asize_32: bool) {
|
|||
pub unsafe fn stosw_rep(is_asize_32: bool) {
|
||||
let diff;
|
||||
let data = *reg16.offset(AX as isize) as i32;
|
||||
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
|
||||
if count == 0 {
|
||||
|
@ -621,7 +636,8 @@ pub unsafe fn stosw_rep(is_asize_32: bool) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn stosw_no_rep(is_asize_32: bool) {
|
||||
let data = *reg16.offset(AX as isize) as i32;
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
return_on_pagefault!(safe_write16(dest, data));
|
||||
add_reg_asize(is_asize_32, EDI, size);
|
||||
|
@ -630,7 +646,8 @@ pub unsafe fn stosw_no_rep(is_asize_32: bool) {
|
|||
pub unsafe fn stosd_rep(is_asize_32: bool) {
|
||||
let diff;
|
||||
let data = *reg32.offset(EAX as isize);
|
||||
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
|
||||
if count == 0 {
|
||||
|
@ -703,7 +720,8 @@ pub unsafe fn stosd_rep(is_asize_32: bool) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn stosd_no_rep(is_asize_32: bool) {
|
||||
let data = *reg32.offset(EAX as isize);
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
return_on_pagefault!(safe_write32(dest, data));
|
||||
add_reg_asize(is_asize_32, EDI, size);
|
||||
|
@ -825,7 +843,8 @@ pub unsafe fn lodsd_no_rep(is_asize_32: bool, ds: i32) {
|
|||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn scasb_rep(prefix_flag: i32, is_asize_32: bool) {
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
let mut data_dest;
|
||||
let data_src = *reg8.offset(AL as isize) as i32;
|
||||
|
@ -865,7 +884,8 @@ pub unsafe fn scasb_rep(prefix_flag: i32, is_asize_32: bool) {
|
|||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn scasb_no_rep(is_asize_32: bool) {
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
let data_dest;
|
||||
let data_src = *reg8.offset(AL as isize) as i32;
|
||||
|
@ -876,7 +896,8 @@ pub unsafe fn scasb_no_rep(is_asize_32: bool) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn scasw_rep(prefix_flag: i32, is_asize_32: bool) {
|
||||
let diff;
|
||||
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
let mut data_dest;
|
||||
let data_src = *reg16.offset(AL as isize) as i32;
|
||||
|
@ -936,7 +957,8 @@ pub unsafe fn scasw_rep(prefix_flag: i32, is_asize_32: bool) {
|
|||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn scasw_no_rep(is_asize_32: bool) {
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
let data_dest;
|
||||
let data_src = *reg16.offset(AL as isize) as i32;
|
||||
|
@ -947,7 +969,8 @@ pub unsafe fn scasw_no_rep(is_asize_32: bool) {
|
|||
#[no_mangle]
|
||||
pub unsafe fn scasd_rep(prefix_flag: i32, is_asize_32: bool) {
|
||||
let diff;
|
||||
let mut dest: i32 = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
let mut data_dest;
|
||||
let data_src = *reg32.offset(EAX as isize);
|
||||
|
@ -1007,7 +1030,8 @@ pub unsafe fn scasd_rep(prefix_flag: i32, is_asize_32: bool) {
|
|||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn scasd_no_rep(is_asize_32: bool) {
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
let data_dest;
|
||||
let data_src = *reg32.offset(EAX as isize);
|
||||
|
@ -1022,7 +1046,8 @@ pub unsafe fn insb_rep(is_asize_32: bool) {
|
|||
return;
|
||||
}
|
||||
else {
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
|
||||
if count == 0 {
|
||||
|
@ -1065,7 +1090,8 @@ pub unsafe fn insb_no_rep(is_asize_32: bool) {
|
|||
return;
|
||||
}
|
||||
else {
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
|
||||
return_on_pagefault!(writable_or_pagefault(dest, 1));
|
||||
return_on_pagefault!(safe_write8(dest, io_port_read8(port)));
|
||||
|
@ -1081,8 +1107,8 @@ pub unsafe fn insw_rep(is_asize_32: bool) {
|
|||
return;
|
||||
}
|
||||
else {
|
||||
let mut dest: i32 =
|
||||
get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
|
||||
if count == 0 {
|
||||
|
@ -1145,7 +1171,8 @@ pub unsafe fn insw_no_rep(is_asize_32: bool) {
|
|||
return;
|
||||
}
|
||||
else {
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -2 } else { 2 };
|
||||
return_on_pagefault!(writable_or_pagefault(dest, 2));
|
||||
return_on_pagefault!(safe_write16(dest, io_port_read16(port)));
|
||||
|
@ -1161,8 +1188,8 @@ pub unsafe fn insd_rep(is_asize_32: bool) {
|
|||
return;
|
||||
}
|
||||
else {
|
||||
let mut dest: i32 =
|
||||
get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let mut dest: i32 = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
let mut count: i32 = if is_asize_32 { read_reg32(ECX) } else { read_reg16(CX) };
|
||||
if count == 0 {
|
||||
|
@ -1225,7 +1252,8 @@ pub unsafe fn insd_no_rep(is_asize_32: bool) {
|
|||
return;
|
||||
}
|
||||
else {
|
||||
let dest = get_seg(ES) + if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let dest = return_on_pagefault!(get_seg(ES))
|
||||
+ if is_asize_32 { read_reg32(EDI) } else { read_reg16(DI) };
|
||||
let size = if 0 != *flags & FLAG_DIRECTION { -4 } else { 4 };
|
||||
return_on_pagefault!(writable_or_pagefault(dest, 4));
|
||||
return_on_pagefault!(safe_write32(dest, io_port_read32(port)));
|
||||
|
|
Loading…
Reference in a new issue