GitLab will be upgraded to the 12.10.14-ce.0 on 28 Sept 2020 at 2.00pm (AEDT) to 2.30pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

Commit eb300764 authored by qinsoon's avatar qinsoon

[wip] exception should work fine. but it doenst run when running with

other tests
parent a0cafb0d
......@@ -5,7 +5,7 @@ extern crate gcc;
fn main() {
gcc::compile_library("libruntime.a", &["src/runtime/runtime_x64_sysv.c"]);
gcc::Config::new().flag("-O3")
gcc::Config::new().flag("-O3").flag("-c")
.file("src/runtime/swap_stack_x64_sysv.S")
.compile("libswap_stack.a");
}
......@@ -15,7 +15,7 @@ fn main() {
fn main() {
gcc::compile_library("libruntime.a", &["src/runtime/runtime_x64_sysv.c"]);
gcc::Config::new().flag("-O3")
gcc::Config::new().flag("-O3").flag("-c")
.file("src/runtime/swap_stack_x64_sysv.S")
.compile("libswap_stack.a");
}
......@@ -11,22 +11,48 @@ use std::sync::RwLockReadGuard;
use std::collections::HashMap;
use std::fmt;
// muentry_throw_exception in swap_stack_x64_sysV.S
// is like a special calling convention to throw_exception_internal
// in order to save all the callee saved registers at a known location
// normal calling convention:
// ---code--- ---stack---
// push caller saved caller saved
// call return addr
// -> (in callee) push rbp old rbp
// mov rsp -> rbp callee saved
// push callee saved
// this function's calling convention
// ---code--- ---stack---
// push caller saved caller saved
// call return addr
// -> (in asm) push callee saved all callee saved <- 2nd arg
// (in rust) push rbp (by rust) old rbp
// mov rsp -> rbp (by rust) callee saved
// push callee saved
// we do not want to make any assumptionon where rust saves rbp or callee saved
// so we save them by ourselves in assembly, and pass a pointer as 2nd argument
#[no_mangle]
#[allow(unreachable_code)]
pub extern fn muentry_throw_exception(exception_obj: Address) {
// last_frame_callee_saved: a pointer passed from assembly, values of 6 callee_saved
// registers are layed out as rbx, rbp, r12-r15 (from low address to high address)
// and return address is put after 6 callee saved regsiters
pub extern fn throw_exception_internal(exception_obj: Address, last_frame_callee_saved: Address) {
trace!("throwing exception: {}", exception_obj);
trace!("callee saved registers of last frame is saved at {}", last_frame_callee_saved);
inspect_nearby_address(last_frame_callee_saved, 8);
let mut cur_thread = thread::MuThread::current_mut();
// set exception object
cur_thread.exception_obj = exception_obj;
let cf_lock = cur_thread.vm.compiled_funcs().read().unwrap();
// rbp of current frame (mu_throw_exception(), Rust frame)
let rust_frame_rbp = unsafe {thread::get_current_frame_rbp()};
trace!("current frame RBP: 0x{:x}", rust_frame_rbp);
inspect_nearby_address(rust_frame_rbp, 5);
let rust_frame_return_addr = unsafe {rust_frame_rbp.plus(POINTER_SIZE).load::<Address>()};
let rust_frame_return_addr = unsafe {last_frame_callee_saved.plus(POINTER_SIZE * x86_64::CALLEE_SAVED_GPRs.len()).load::<Address>()};
trace!("return address : 0x{:x} - throw instruction", rust_frame_return_addr);
// the return address is within throwing frame
......@@ -36,7 +62,9 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
// skip to previous frame
// this is the frame that throws the exception
let rbp = unsafe {rust_frame_rbp.load::<Address>()};
let previous_frame_rbp_loc = last_frame_callee_saved.plus(POINTER_SIZE);
let rbp = unsafe {previous_frame_rbp_loc.load::<Address>()};
trace!("rbp of previous frame is {} (last_frame_callee_saved {} + 8)", rbp, last_frame_callee_saved);
// set cursor to throwing frame
let mut cursor = FrameCursor {
......@@ -44,7 +72,14 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
return_addr: unsafe {rbp.plus(POINTER_SIZE).load::<Address>()},
func_id: throw_func,
func_ver_id: throw_fv,
callee_saved_locs: HashMap::new()
callee_saved_locs: hashmap!{
x86_64::RBX.id() => last_frame_callee_saved,
x86_64::RBP.id() => previous_frame_rbp_loc,
x86_64::R12.id() => last_frame_callee_saved.plus(POINTER_SIZE * 2),
x86_64::R13.id() => last_frame_callee_saved.plus(POINTER_SIZE * 3),
x86_64::R14.id() => last_frame_callee_saved.plus(POINTER_SIZE * 4),
x86_64::R15.id() => last_frame_callee_saved.plus(POINTER_SIZE * 5),
}
};
trace!("cursor at first Mu frame: {}", cursor);
......
......@@ -70,8 +70,25 @@ begin_func get_current_frame_rbp
ret
end_func get_current_frame_rbp
# muentry_throw_exception(obj: Address)
# %rdi
begin_func muentry_throw_exception
# save all callee-saved
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbp
pushq %rbx
# %rsp points to %rbx, pass this as 2nd argument
movq %rsp, %rsi
jmp CNAME(throw_exception_internal)
# won't return
# _exception_restore(dest: Address, callee_saved: *const Word, rsp: Address) -> !
# %rdi %rsi %rdx
# %rdi %rsi %rdx
# callee_saved: [rbx, rbp, r12, r13, r14, r15]
begin_func exception_restore
movq 0(%rsi), %rbx
......
......@@ -300,6 +300,7 @@ impl MuThread {
if ! unsafe{muentry_get_thread_local()}.is_zero() {
warn!("current thread has a thread local (has a muthread to it)");
panic!("should not have muthread here");
return false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment