include CS in flat_segments

This commit is contained in:
Fabian 2022-11-10 11:01:12 -06:00
commit eea5cb67b0
3 changed files with 30 additions and 15 deletions

View file

@ -12,9 +12,11 @@ use regs;
use wasmgen::wasm_builder::{WasmBuilder, WasmLocal, WasmLocalI64}; use wasmgen::wasm_builder::{WasmBuilder, WasmLocal, WasmLocalI64};
pub fn gen_add_cs_offset(ctx: &mut JitContext) { pub fn gen_add_cs_offset(ctx: &mut JitContext) {
ctx.builder if !ctx.cpu.has_flat_segmentation() {
.load_fixed_i32(global_pointers::get_seg_offset(regs::CS)); ctx.builder
ctx.builder.add_i32(); .load_fixed_i32(global_pointers::get_seg_offset(regs::CS));
ctx.builder.add_i32();
}
} }
pub fn gen_get_eip(builder: &mut WasmBuilder) { pub fn gen_get_eip(builder: &mut WasmBuilder) {
@ -1536,9 +1538,11 @@ pub fn gen_get_real_eip(ctx: &mut JitContext) {
ctx.builder.and_i32(); ctx.builder.and_i32();
ctx.builder.const_i32(ctx.cpu.eip as i32 & 0xFFF); ctx.builder.const_i32(ctx.cpu.eip as i32 & 0xFFF);
ctx.builder.or_i32(); ctx.builder.or_i32();
ctx.builder if !ctx.cpu.has_flat_segmentation() {
.load_fixed_i32(global_pointers::get_seg_offset(regs::CS)); ctx.builder
ctx.builder.sub_i32(); .load_fixed_i32(global_pointers::get_seg_offset(regs::CS));
ctx.builder.sub_i32();
}
} }
pub fn gen_set_last_op1(builder: &mut WasmBuilder, source: &WasmLocal) { pub fn gen_set_last_op1(builder: &mut WasmBuilder, source: &WasmLocal) {

View file

@ -547,6 +547,7 @@ pub unsafe fn iret(is_16: bool) {
cpl_changed(); cpl_changed();
update_cs_size(false); update_cs_size(false);
update_state_flags();
// iret end // iret end
return; return;
@ -1020,6 +1021,8 @@ pub unsafe fn call_interrupt_vector(
handle_irqs(); handle_irqs();
} }
} }
update_state_flags();
} }
else { else {
// call 4 byte cs:ip interrupt vector from ivt at cpu.memory 0 // call 4 byte cs:ip interrupt vector from ivt at cpu.memory 0
@ -1044,6 +1047,7 @@ pub unsafe fn call_interrupt_vector(
switch_cs_real_mode(new_cs); switch_cs_real_mode(new_cs);
*instruction_pointer = get_seg_cs() + new_ip; *instruction_pointer = get_seg_cs() + new_ip;
update_state_flags();
} }
} }
@ -1070,6 +1074,7 @@ pub unsafe fn far_jump(eip: i32, selector: i32, is_call: bool, is_osize_32: bool
} }
switch_cs_real_mode(selector); switch_cs_real_mode(selector);
*instruction_pointer = get_seg_cs() + eip; *instruction_pointer = get_seg_cs() + eip;
update_state_flags();
return; return;
} }
@ -1309,6 +1314,8 @@ pub unsafe fn far_jump(eip: i32, selector: i32, is_call: bool, is_osize_32: bool
dbg_assert!(*sreg.offset(CS as isize) & 3 == *cpl as u16); dbg_assert!(*sreg.offset(CS as isize) & 3 == *cpl as u16);
*instruction_pointer = get_seg_cs() + new_eip; *instruction_pointer = get_seg_cs() + new_eip;
update_state_flags();
} }
else { else {
dbg_assert!(false); dbg_assert!(false);
@ -1374,6 +1381,8 @@ pub unsafe fn far_jump(eip: i32, selector: i32, is_call: bool, is_osize_32: bool
*sreg.offset(CS as isize) = selector as u16 & !3 | *cpl as u16; *sreg.offset(CS as isize) = selector as u16 & !3 | *cpl as u16;
*instruction_pointer = get_seg_cs() + eip; *instruction_pointer = get_seg_cs() + eip;
update_state_flags();
} }
//dbg_log!("far " + ["jump", "call"][+is_call] + " to:", LOG_CPU) //dbg_log!("far " + ["jump", "call"][+is_call] + " to:", LOG_CPU)
@ -1395,6 +1404,7 @@ pub unsafe fn far_return(eip: i32, selector: i32, stack_adjust: i32, is_osize_32
switch_cs_real_mode(selector); switch_cs_real_mode(selector);
*instruction_pointer = get_seg_cs() + eip; *instruction_pointer = get_seg_cs() + eip;
adjust_stack_reg(2 * (if is_osize_32 { 4 } else { 2 }) + stack_adjust); adjust_stack_reg(2 * (if is_osize_32 { 4 } else { 2 }) + stack_adjust);
update_state_flags();
return; return;
} }
@ -1520,6 +1530,8 @@ pub unsafe fn far_return(eip: i32, selector: i32, stack_adjust: i32, is_osize_32
*instruction_pointer = get_seg_cs() + eip; *instruction_pointer = get_seg_cs() + eip;
update_state_flags();
//dbg_log("far return to:", LOG_CPU) //dbg_log("far return to:", LOG_CPU)
//CPU_LOG_VERBOSE && debug.dump_state("far ret end"); //CPU_LOG_VERBOSE && debug.dump_state("far ret end");
} }
@ -1734,6 +1746,8 @@ pub unsafe fn do_task_switch(selector: i32, error_code: Option<i32>) {
push32(error_code).unwrap(); push32(error_code).unwrap();
} }
} }
update_state_flags();
} }
pub unsafe fn after_block_boundary() { jit_block_boundary = true; } pub unsafe fn after_block_boundary() { jit_block_boundary = true; }
@ -2478,6 +2492,7 @@ pub unsafe fn switch_seg(reg: i32, selector_raw: i32) -> bool {
// es, ds, fs, gs // es, ds, fs, gs
*sreg.offset(reg as isize) = selector_raw as u16; *sreg.offset(reg as isize) = selector_raw as u16;
*segment_is_null.offset(reg as isize) = true; *segment_is_null.offset(reg as isize) = true;
update_state_flags();
return true; return true;
} }
} }
@ -2514,7 +2529,6 @@ pub unsafe fn switch_seg(reg: i32, selector_raw: i32) -> bool {
} }
*stack_size_32 = descriptor.is_32(); *stack_size_32 = descriptor.is_32();
update_state_flags();
} }
else if reg == CS { else if reg == CS {
// handled by switch_cs_real_mode, far_return or far_jump // handled by switch_cs_real_mode, far_return or far_jump
@ -2736,15 +2750,11 @@ pub unsafe fn load_pdpte(cr3: i32) {
} }
} }
pub unsafe fn cpl_changed() { pub unsafe fn cpl_changed() { *last_virt_eip = -1 }
*last_virt_eip = -1;
update_state_flags();
}
pub unsafe fn update_cs_size(new_size: bool) { pub unsafe fn update_cs_size(new_size: bool) {
if *is_32 != new_size { if *is_32 != new_size {
*is_32 = new_size; *is_32 = new_size;
update_state_flags();
} }
} }
@ -3092,10 +3102,11 @@ pub fn update_state_flags() {
#[no_mangle] #[no_mangle]
pub unsafe fn has_flat_segmentation() -> bool { pub unsafe fn has_flat_segmentation() -> bool {
// ss can't be null // cs/ss can't be null
return *segment_offsets.offset(SS as isize) == 0 return *segment_offsets.offset(SS as isize) == 0
&& !*segment_is_null.offset(DS as isize) && !*segment_is_null.offset(DS as isize)
&& *segment_offsets.offset(DS as isize) == 0; && *segment_offsets.offset(DS as isize) == 0
&& *segment_offsets.offset(CS as isize) == 0;
} }
pub unsafe fn run_prefix_instruction() { pub unsafe fn run_prefix_instruction() {

View file

@ -265,7 +265,7 @@ enum Imm32 {
} }
fn can_optimize_get_seg(ctx: &mut JitContext, segment: u32) -> bool { fn can_optimize_get_seg(ctx: &mut JitContext, segment: u32) -> bool {
(segment == DS || segment == SS) && ctx.cpu.has_flat_segmentation() (segment == DS || segment == SS || segment == CS) && ctx.cpu.has_flat_segmentation()
} }
pub fn jit_add_seg_offset(ctx: &mut JitContext, default_segment: u32) { pub fn jit_add_seg_offset(ctx: &mut JitContext, default_segment: u32) {