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 a0cafb0d authored by qinsoon's avatar qinsoon

[wip] fixing bugs to get throw test working

currently its not working because we cannot restore callee saved
regsiter from the last frame (or the rust frame to throw exception).
One solution is to save all the callee saved registers in a function
that can throw.
parent fde94d2b
...@@ -2778,9 +2778,10 @@ impl <'a> InstructionSelection { ...@@ -2778,9 +2778,10 @@ impl <'a> InstructionSelection {
// GETIREF -> [base] // GETIREF -> [base]
Instruction_::GetIRef(op_index) => { Instruction_::GetIRef(op_index) => {
let ref ref_op = ops[op_index]; let ref ref_op = ops[op_index];
let tmp_op = self.emit_ireg(ref_op, f_content, f_context, vm);
let ret = MemoryLocation::Address { let ret = MemoryLocation::Address {
base: ref_op.clone_value(), base: tmp_op,
offset: None, offset: None,
index: None, index: None,
scale: None scale: None
......
...@@ -109,7 +109,7 @@ pub extern fn muentry_throw_exception(exception_obj: Address) { ...@@ -109,7 +109,7 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
match cursor.callee_saved_locs.get(&$reg.id()) { match cursor.callee_saved_locs.get(&$reg.id()) {
Some(addr) => unsafe {addr.load::<Word>()}, Some(addr) => unsafe {addr.load::<Word>()},
None => { None => {
warn!("no {} value was saved along unwinding, please check", $reg.name().unwrap()); info!("no {} value was saved along unwinding", $reg.name().unwrap());
0 0
} }
} }
...@@ -125,7 +125,8 @@ pub extern fn muentry_throw_exception(exception_obj: Address) { ...@@ -125,7 +125,8 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
let array = vec![rbx, rbp, r12, r13, r14, r15]; let array = vec![rbx, rbp, r12, r13, r14, r15];
let rsp = cursor.rbp.offset(frame.cur_offset()); let rsp = cursor.rbp.offset(frame.cur_offset());
info!("going to restore thread to {} with RSP {}", dest_addr, rsp);
unsafe {thread::exception_restore(dest_addr, array.as_ptr(), rsp)}; unsafe {thread::exception_restore(dest_addr, array.as_ptr(), rsp)};
unreachable!() unreachable!()
......
...@@ -28,6 +28,7 @@ pub mod exception; ...@@ -28,6 +28,7 @@ pub mod exception;
extern "C" { extern "C" {
fn dlopen(filename: *const c_char, flags: isize) -> *const c_void; fn dlopen(filename: *const c_char, flags: isize) -> *const c_void;
fn dlsym(handle: *const c_void, symbol: *const c_char) -> *const c_void; fn dlsym(handle: *const c_void, symbol: *const c_char) -> *const c_void;
fn dlerror() -> *const c_char;
} }
pub fn resolve_symbol(symbol: String) -> Address { pub fn resolve_symbol(symbol: String) -> Address {
...@@ -35,9 +36,14 @@ pub fn resolve_symbol(symbol: String) -> Address { ...@@ -35,9 +36,14 @@ pub fn resolve_symbol(symbol: String) -> Address {
let rtld_default = unsafe {dlopen(ptr::null(), 0)}; let rtld_default = unsafe {dlopen(ptr::null(), 0)};
let ret = unsafe {dlsym(rtld_default, CString::new(symbol.clone()).unwrap().as_ptr())}; let ret = unsafe {dlsym(rtld_default, CString::new(symbol.clone()).unwrap().as_ptr())};
if ret == 0 as *const c_void { let error = unsafe {dlerror()};
panic!("cannot find symbol {}", symbol); if !error.is_null() {
let cstr = unsafe {CStr::from_ptr(error)};
println!("cannot find symbol: {}", symbol);
println!("{}", cstr.to_str().unwrap());
panic!("failed to resolve symbol");
} }
Address::from_ptr(ret) Address::from_ptr(ret)
......
...@@ -18,7 +18,7 @@ void set_thread_local(void* thread) { ...@@ -18,7 +18,7 @@ void set_thread_local(void* thread) {
} }
void* muentry_get_thread_local() { void* muentry_get_thread_local() {
// printf("Thread%p: getting mu_tls as %p\n", (void*) pthread_self(), mu_tls); // printf("Thread%p: getting mu_tls as %p\n", (void*) pthread_self(), mu_tls);
return mu_tls; return mu_tls;
} }
......
...@@ -19,6 +19,7 @@ use std::mem; ...@@ -19,6 +19,7 @@ use std::mem;
use std::thread; use std::thread;
use std::thread::JoinHandle; use std::thread::JoinHandle;
use std::sync::Arc; use std::sync::Arc;
use std::fmt;
pub const STACK_SIZE : ByteSize = (4 << 20); // 4mb pub const STACK_SIZE : ByteSize = (4 << 20); // 4mb
...@@ -204,11 +205,11 @@ pub struct MuThread { ...@@ -204,11 +205,11 @@ pub struct MuThread {
pub allocator: mm::Mutator, pub allocator: mm::Mutator,
pub stack: Option<Box<MuStack>>, pub stack: Option<Box<MuStack>>,
native_sp_loc: Address, pub native_sp_loc: Address,
user_tls: Address, // can be zero pub user_tls: Address, // can be zero
pub vm: Arc<VM>, pub exception_obj: Address,
pub exception_obj: Address pub vm: Arc<VM>
} }
// this depends on the layout of MuThread // this depends on the layout of MuThread
...@@ -216,14 +217,26 @@ lazy_static! { ...@@ -216,14 +217,26 @@ lazy_static! {
pub static ref ALLOCATOR_OFFSET : usize = mem::size_of::<MuEntityHeader>(); pub static ref ALLOCATOR_OFFSET : usize = mem::size_of::<MuEntityHeader>();
pub static ref NATIVE_SP_LOC_OFFSET : usize = *ALLOCATOR_OFFSET pub static ref NATIVE_SP_LOC_OFFSET : usize = *ALLOCATOR_OFFSET
+ mem::size_of::<Box<mm::Mutator>>() + mem::size_of::<mm::Mutator>()
+ mem::size_of::<Option<Box<MuStack>>>(); + mem::size_of::<Option<Box<MuStack>>>();
pub static ref USER_TLS_OFFSET : usize = *NATIVE_SP_LOC_OFFSET + mem::size_of::<Address>(); pub static ref USER_TLS_OFFSET : usize = *NATIVE_SP_LOC_OFFSET + mem::size_of::<Address>();
pub static ref VM_OFFSET : usize = *USER_TLS_OFFSET + mem::size_of::<Address>();
pub static ref EXCEPTION_OBJ_OFFSET : usize = *VM_OFFSET + mem::size_of::<Arc<VM>>(); pub static ref EXCEPTION_OBJ_OFFSET : usize = *USER_TLS_OFFSET + mem::size_of::<Address>();
}
impl fmt::Display for MuThread {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "MuThread @{:?}: {}\n", self as *const MuThread, self.hdr).unwrap();
write!(f, "- header @{:?}\n", &self.hdr as *const MuEntityHeader).unwrap();
write!(f, "- allocator @{:?}\n", &self.allocator as *const mm::Mutator).unwrap();
write!(f, "- stack @{:?}: {}\n", &self.stack as *const Option<Box<MuStack>>, self.stack.is_some()).unwrap();
write!(f, "- native sp @{:?}: {}\n", &self.native_sp_loc as *const Address, self.native_sp_loc).unwrap();
write!(f, "- user_tls @{:?}: {}\n", &self.user_tls as *const Address, self.user_tls).unwrap();
write!(f, "- exc obj @{:?}: {}\n", &self.exception_obj as *const Address, self.exception_obj).unwrap();
Ok(())
}
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
......
...@@ -54,7 +54,7 @@ def compile_c_script(c_src_name): ...@@ -54,7 +54,7 @@ def compile_c_script(c_src_name):
def ctypes_fncptr_from_lib(libpath, fnc_name, argtypes=[], restype=ctypes.c_longlong): def ctypes_fncptr_from_lib(libpath, fnc_name, argtypes=[], restype=ctypes.c_longlong):
lib = ctypes.CDLL(libpath.strpath) lib = ctypes.CDLL(libpath.strpath, ctypes.RTLD_GLOBAL)
fnp = getattr(lib, fnc_name) fnp = getattr(lib, fnc_name)
fnp.argtypes = argtypes fnp.argtypes = argtypes
fnp.restype = restype fnp.restype = restype
......
mod test_threadlocal;
mod test_entry_offset;
\ No newline at end of file
use utils::Address;
use mu::runtime::mm;
use mu::runtime::thread;
use mu::runtime::thread::MuThread;
use mu::vm::VM;
use std::usize;
use std::sync::Arc;
#[test]
fn test_muthread_entry_offset() {
let vm = Arc::new(VM::new());
unsafe {
MuThread::current_thread_as_mu_thread(Address::max(), vm.clone());
}
let tl : &MuThread = MuThread::current();
let tl_ptr = tl as *const MuThread;
let tl_addr = unsafe {thread::muentry_get_thread_local()};
assert_eq!(tl_addr, Address::from_ptr(tl_ptr));
let allocator_ptr = &tl.allocator as *const mm::Mutator;
let allocator_addr = tl_addr.plus(*thread::ALLOCATOR_OFFSET);
assert_eq!(allocator_addr, Address::from_ptr(allocator_ptr));
let native_sp_ptr = &tl.native_sp_loc as *const Address;
let native_sp_addr = tl_addr.plus(*thread::NATIVE_SP_LOC_OFFSET);
assert_eq!(native_sp_addr, Address::from_ptr(native_sp_ptr));
let user_tls_ptr = &tl.user_tls as *const Address;
let user_tls_addr = tl_addr.plus(*thread::USER_TLS_OFFSET);
assert_eq!(user_tls_addr, Address::from_ptr(user_tls_ptr));
let exc_obj_ptr = &tl.exception_obj as *const Address;
let exc_obj_addr = tl_addr.plus(*thread::EXCEPTION_OBJ_OFFSET);
assert_eq!(exc_obj_addr, Address::from_ptr(exc_obj_ptr));
}
\ No newline at end of file
use utils::Address;
use mu::runtime::thread;
use mu::runtime::thread::MuThread;
use mu::vm::VM;
use std::usize;
use std::sync::Arc;
#[test]
fn test_access_exception_obj() {
let vm = Arc::new(VM::new());
unsafe {
MuThread::current_thread_as_mu_thread(Address::max(), vm.clone());
}
let cur = MuThread::current();
println!("{}", cur);
println!("reference = {:?}", cur as *const MuThread);
assert_eq!(cur.exception_obj, unsafe {Address::zero()});
// set exception obj using offset
let tl_addr = unsafe {thread::muentry_get_thread_local()};
let exc_obj_addr = tl_addr.plus(*thread::EXCEPTION_OBJ_OFFSET);
println!("storing exception obj Address::max() to {}", exc_obj_addr);
unsafe {exc_obj_addr.store(usize::MAX)};
println!("{}", cur);
assert_eq!(cur.exception_obj, unsafe {Address::max()});
}
\ No newline at end of file
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