GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

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
Pipeline #262 failed with stage
in 30 minutes and 59 seconds
......@@ -2778,9 +2778,10 @@ impl <'a> InstructionSelection {
// GETIREF -> [base]
Instruction_::GetIRef(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 {
base: ref_op.clone_value(),
base: tmp_op,
offset: None,
index: None,
scale: None
......
......@@ -109,7 +109,7 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
match cursor.callee_saved_locs.get(&$reg.id()) {
Some(addr) => unsafe {addr.load::<Word>()},
None => {
warn!("no {} value was saved along unwinding, please check", $reg.name().unwrap());
info!("no {} value was saved along unwinding", $reg.name().unwrap());
0
}
}
......@@ -125,7 +125,8 @@ pub extern fn muentry_throw_exception(exception_obj: Address) {
let array = vec![rbx, rbp, r12, r13, r14, r15];
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)};
unreachable!()
......
......@@ -28,6 +28,7 @@ pub mod exception;
extern "C" {
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 dlerror() -> *const c_char;
}
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 ret = unsafe {dlsym(rtld_default, CString::new(symbol.clone()).unwrap().as_ptr())};
if ret == 0 as *const c_void {
panic!("cannot find symbol {}", symbol);
let error = unsafe {dlerror()};
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)
......
......@@ -18,7 +18,7 @@ void set_thread_local(void* thread) {
}
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;
}
......
......@@ -19,6 +19,7 @@ use std::mem;
use std::thread;
use std::thread::JoinHandle;
use std::sync::Arc;
use std::fmt;
pub const STACK_SIZE : ByteSize = (4 << 20); // 4mb
......@@ -204,11 +205,11 @@ pub struct MuThread {
pub allocator: mm::Mutator,
pub stack: Option<Box<MuStack>>,
native_sp_loc: Address,
user_tls: Address, // can be zero
pub vm: Arc<VM>,
pub exception_obj: Address
pub native_sp_loc: Address,
pub user_tls: Address, // can be zero
pub exception_obj: Address,
pub vm: Arc<VM>
}
// this depends on the layout of MuThread
......@@ -216,14 +217,26 @@ lazy_static! {
pub static ref ALLOCATOR_OFFSET : usize = mem::size_of::<MuEntityHeader>();
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>>>();
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")]
......
......@@ -54,7 +54,7 @@ def compile_c_script(c_src_name):
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.argtypes = argtypes
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