From 0bf4e4faf6bc8b31d87d6211dc3d8e825b70af5d Mon Sep 17 00:00:00 2001 From: Amaan Cheval Date: Tue, 25 Sep 2018 13:12:00 +0530 Subject: [PATCH] cpu: Port get_tss_stack_addr to Rust --- src/browser/starter.js | 1 - src/cpu.js | 37 +------------------------------------ src/rust/cpu2/cpu.rs | 35 ++++++++++++++++++++++++++++++++--- src/rust/js_api.rs | 8 ++++++-- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/src/browser/starter.js b/src/browser/starter.js index 73a61001..6dc26e9f 100644 --- a/src/browser/starter.js +++ b/src/browser/starter.js @@ -260,7 +260,6 @@ function V86Starter(options) cpu.do_task_switch(selector, has_error_code, error_code); }, // XXX: Port to Rust - "get_tss_stack_addr": (dpl) => cpu.get_tss_stack_addr(dpl), "switch_cs_real_mode": (selector) => cpu.switch_cs_real_mode(selector), }; diff --git a/src/cpu.js b/src/cpu.js index 2a2f6c1e..6a072d28 100644 --- a/src/cpu.js +++ b/src/cpu.js @@ -306,6 +306,7 @@ CPU.prototype.wasm_patch = function(wm) this.trigger_ss = get_import("trigger_ss"); this.call_interrupt_vector = get_import("call_interrupt_vector_js"); + this.get_tss_stack_addr = get_import("get_tss_stack_addr_js"); this.do_many_cycles_native = get_import("do_many_cycles_native"); this.cycle_internal = get_import("cycle_internal"); @@ -2281,42 +2282,6 @@ CPU.prototype.far_jump = function(eip, selector, is_call) CPU_LOG_VERBOSE && this.debug.dump_state("far " + ["jump", "call"][+is_call] + " end"); }; -CPU.prototype.get_tss_stack_addr = function(dpl) -{ - if(this.tss_size_32[0]) - { - var tss_stack_addr = (dpl << 3) + 4 | 0; - - if((tss_stack_addr + 5 | 0) > this.segment_limits[reg_tr]) - { - throw this.debug.unimpl("#TS handler"); - } - - tss_stack_addr = tss_stack_addr + this.segment_offsets[reg_tr] | 0; - - dbg_assert((tss_stack_addr & 0xFFF) <= 0x1000 - 6); - } - else - { - var tss_stack_addr = (dpl << 2) + 2 | 0; - - if((tss_stack_addr + 5 | 0) > this.segment_limits[reg_tr]) - { - throw this.debug.unimpl("#TS handler"); - } - - tss_stack_addr = tss_stack_addr + this.segment_offsets[reg_tr] | 0; - dbg_assert((tss_stack_addr & 0xFFF) <= 0x1000 - 4); - } - - if(this.cr[0] & CR0_PG) - { - tss_stack_addr = this.translate_address_system_read(tss_stack_addr); - } - - return tss_stack_addr; -}; - CPU.prototype.do_task_switch = function(selector, has_error_code, error_code) { dbg_assert(this.tss_size_32[0], "TODO"); diff --git a/src/rust/cpu2/cpu.rs b/src/rust/cpu2/cpu.rs index 0cd47bb9..bc5eefb8 100644 --- a/src/rust/cpu2/cpu.rs +++ b/src/rust/cpu2/cpu.rs @@ -6,8 +6,6 @@ extern "C" { #[no_mangle] fn do_task_switch(selector: i32, has_error_code: bool, error_code: i32); #[no_mangle] - fn get_tss_stack_addr(dpl: u8) -> u32; - #[no_mangle] fn switch_cs_real_mode(selector: i32); #[no_mangle] fn dbg_trace(); @@ -385,6 +383,36 @@ pub unsafe fn call_interrupt_vector_js( call_interrupt_vector(interrupt_nr, is_software_int, ec); } +pub unsafe fn get_tss_stack_addr(dpl: u8) -> OrPageFault { + let mut tss_stack_addr: u32; + + if *tss_size_32 { + tss_stack_addr = ((dpl << 3) + 4) as u32; + + if tss_stack_addr + 5 > *segment_limits.offset(TR as isize) { + panic!("#TS handler"); + } + + tss_stack_addr = tss_stack_addr + *segment_offsets.offset(TR as isize) as u32; + + dbg_assert!(tss_stack_addr & 0xFFF <= 0x1000 - 6); + } + else { + tss_stack_addr = ((dpl << 2) + 2) as u32; + + if tss_stack_addr + 5 > *segment_limits.offset(TR as isize) { + panic!("#TS handler"); + } + + tss_stack_addr = tss_stack_addr + *segment_offsets.offset(TR as isize) as u32; + dbg_assert!(tss_stack_addr & 0xFFF <= 0x1000 - 4); + } + + tss_stack_addr = translate_address_system_read(tss_stack_addr as i32)?; + + Ok(tss_stack_addr) +} + pub unsafe fn call_interrupt_vector( interrupt_nr: i32, is_software_int: bool, @@ -505,7 +533,8 @@ pub unsafe fn call_interrupt_vector( panic!("Unimplemented: #GP handler for non-0 cs segment dpl when in vm86 mode"); } - let tss_stack_addr = get_tss_stack_addr(cs_segment_descriptor.dpl()); + let tss_stack_addr = + return_on_pagefault!(get_tss_stack_addr(cs_segment_descriptor.dpl())); let new_esp = read32s(tss_stack_addr); let new_ss = read16(tss_stack_addr + if *tss_size_32 { 4 } else { 2 }); diff --git a/src/rust/js_api.rs b/src/rust/js_api.rs index 22646c39..ae0e0947 100644 --- a/src/rust/js_api.rs +++ b/src/rust/js_api.rs @@ -1,6 +1,7 @@ use cpu2::cpu::{ - safe_read16, safe_read32s, safe_write16, safe_write32, translate_address_read, - translate_address_system_read, translate_address_system_write, writable_or_pagefault, + get_tss_stack_addr, safe_read16, safe_read32s, safe_write16, safe_write32, + translate_address_read, translate_address_system_read, translate_address_system_write, + writable_or_pagefault, }; use cpu2::misc_instr::{push16, push32}; @@ -35,3 +36,6 @@ pub unsafe fn push16_js(value: i32) { push16(value).unwrap() } #[no_mangle] pub unsafe fn push32_js(value: i32) { push32(value).unwrap() } + +#[no_mangle] +pub unsafe fn get_tss_stack_addr_js(dpl: u8) -> u32 { get_tss_stack_addr(dpl).unwrap() }