GitLab will be partched to the latest stable version on 15 July 2020 at 2.00pm (AEDT) to 2.30pm (AEDT) due to Security Patch Availability. 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 c24b8896 authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano

Fixed kill_stack bug

parent 15e35778
......@@ -1425,7 +1425,7 @@ impl<'a> InstructionSelection {
);
self.emit_runtime_entry(
&entrypoints::MUENTRY_THREAD_EXIT,
&entrypoints::THREAD_EXIT,
vec![tl.clone()],
None,
Some(node),
......@@ -1449,7 +1449,7 @@ impl<'a> InstructionSelection {
let (_, _, stack_arg_size) = compute_argument_locations(&sig.arg_tys, &SP, 0, &vm);
self.emit_runtime_entry(
&entrypoints::MUENTRY_NEW_STACK,
&entrypoints::NEW_STACK,
vec![tmp_func, make_value_int_const(stack_arg_size as u64, vm)],
Some(vec![tmp_res]),
Some(node),
......@@ -1457,6 +1457,18 @@ impl<'a> InstructionSelection {
vm
);
}
Instruction_::KillStack(op) => {
trace!("instself on KILL_STACK");
let op = self.emit_ireg(&inst.ops[op], f_content, f_context, vm);
self.emit_runtime_entry(
&entrypoints::KILL_STACK,
vec![op],
None,
Some(node),
f_context,
vm
);
}
Instruction_::CurrentStack => {
trace!("instsel on CURRENT_STACK");
......
......@@ -2084,7 +2084,6 @@ fn split_int128(
.unwrap()
.set_split(vec![arg_l.clone(), arg_h.clone()]);
trace!("ISAAC <- make temporary ({}, {})", &arg_l, &arg_h);
(arg_l, arg_h)
}
}
......@@ -2106,13 +2105,6 @@ pub fn emit_ireg_ex_value(
emit_mov_u64(backend, &tmp_l, val[0]);
emit_mov_u64(backend, &tmp_h, val[1]);
trace!(
"ISAAC <- ({}, {}) = ({}, {})",
&tmp_l,
&tmp_h,
val[0],
val[1]
);
(tmp_l, tmp_h)
}
_ => panic!("expected ireg_ex")
......
......@@ -57,7 +57,7 @@ lazy_static! {
// impl: runtime_asm_ARCH_OS.s
// decl: thread.rs
pub static ref MUENTRY_THREAD_EXIT : RuntimeEntrypoint = RuntimeEntrypoint {
pub static ref THREAD_EXIT : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![],
......@@ -70,7 +70,7 @@ lazy_static! {
}
lazy_static! {
// impl/decl: thread.rs
pub static ref MUENTRY_NEW_STACK: RuntimeEntrypoint = RuntimeEntrypoint {
pub static ref NEW_STACK: RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![STACKREF_TYPE.clone()],
......@@ -80,6 +80,17 @@ lazy_static! {
jit: RwLock::new(None),
};
// impl/decl: thread.rs
pub static ref KILL_STACK: RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![],
arg_tys: vec![STACKREF_TYPE.clone()]
}),
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_kill_stack")),
jit: RwLock::new(None),
};
// impl/decl: gc/lib.rs
pub static ref ALLOC_FAST : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
......
......@@ -46,16 +46,14 @@ begin_func exception_restore
end_func exception_restore
# Swapstack internals
.macro stack_pass new_sp
MOV SP, \new_sp
.macro stack_pass
# On the new stack, reverse the above
pop_callee_saved
exit_frame
RET
.endm
.macro stack_throw new_sp
MOV SP, \new_sp
.macro stack_throw
# The new stack will have the same layout as the stack when muentry_throw_exception
# calls throw_exception_internal, so we can do that directly here
......@@ -73,12 +71,10 @@ end_func exception_restore
STR X11, [\old_sp]
.endm
.macro stack_kill old_sp
.macro stack_kill old_stack
mov_args_to_callee_saved
push_pair X9, X10
MOV X0, \old_sp
MOV X0, \old_stack
BL muentry_kill_stack
pop_pair X10, X9
mov_callee_saved_to_args
.endm
......@@ -89,7 +85,8 @@ begin_func muthread_start_pass
stack_ret X1
MOV X9, X0 # X1 will be overriden by the next instructions
load_arguments X9
stack_pass X9
MOV SP, X9
stack_pass
end_func muthread_start_pass
......@@ -98,7 +95,8 @@ end_func muthread_start_pass
# X0 X1 X2
begin_func muthread_start_throw
stack_ret X2
stack_throw X1
MOV SP, X1
stack_throw
end_func muthread_start_throw
# restores the thread
......@@ -106,7 +104,8 @@ end_func muthread_start_throw
# X0
begin_func muentry_thread_exit
# Rust code will be responsible for actually killing the stack
stack_pass X0
MOV SP, X0
stack_pass
end_func muentry_thread_exit
# swap to the new stack whilst passing values and saving the old stack
......@@ -114,7 +113,8 @@ end_func muentry_thread_exit
# X0 ... X7 [x8] X9 X10
begin_func muentry_swapstack_ret_pass
stack_ret X10
stack_pass X9
MOV SP, X9
stack_pass
end_func muentry_swapstack_ret_pass
# Same as swapstack_ret_pass except will throw an exception to the new stack instead of passing values
......@@ -122,21 +122,24 @@ end_func muentry_swapstack_ret_pass
# X0 X1 X2
begin_func muentry_swapstack_ret_throw
stack_ret X2
stack_throw X1
MOV SP, X1
stack_throw
end_func muentry_swapstack_ret_throw
# swap to the new stack whilst passing values and killing the old stack
# muentry_swapstack_kill_pass(new_stack args..., new_sp: Address, old_stack: *mut MuStack)
# X0 ... X7 [x8] X9 X10
begin_func muentry_swapstack_kill_pass
MOV SP, X9
stack_kill X10
stack_pass X9
stack_pass
end_func muentry_swapstack_kill_pass
# Same as muentry_swapstack_kill_pass except will throw an exception to the new stack instead of passing values
# muentry_swapstack_kill_throw(exception: Address, new_sp: Address, old_stack: *mut MuStack)
# X0 X1 X2
begin_func muentry_swapstack_kill_throw
MOV SP, X1
stack_kill X2
stack_throw X1
stack_throw
end_func muentry_swapstack_kill_throw
......@@ -107,26 +107,6 @@ pub struct MuStack {
mmap: Option<memmap::Mmap>
}
impl Drop for MuStack
{
fn drop(&mut self) {
// Reverse memory protection so that dropping will work...
//trace!("dropping MuStack {}", Address::from_ref(self));
unsafe {
memsec::mprotect(
self.overflow_guard.to_ptr_mut::<u8>(),
PAGE_SIZE,
memsec::Prot::ReadWriteExec
);
memsec::mprotect(
self.underflow_guard.to_ptr_mut::<u8>(),
PAGE_SIZE,
memsec::Prot::ReadWriteExec
);
}
}
}
impl MuStack {
/// creates a new MuStack for given entry function and function address
pub fn new(id: MuID, func_addr: Address, stack_arg_size: usize) -> MuStack {
......@@ -673,10 +653,7 @@ pub unsafe extern "C" fn muentry_prepare_swapstack_ret(new_stack: *mut MuStack)
// Save the current stack, don't deallocate it
let cur_stack = Box::into_raw(cur_thread.stack.take().unwrap());
cur_thread.stack = Some(Box::from_raw(new_stack));
let new_sp = (*new_stack).sp;
let old_sp_loc =&mut (*cur_stack).sp;
trace!("ISAAC: muentry_prepare_swapstack_ret({}) -> ({}, {})", Address::from_ptr(new_stack), new_sp, Address::from_ref(old_sp_loc));
(new_sp, old_sp_loc)
((*new_stack).sp, &mut (*cur_stack).sp)
}
// This prepares a thread for a swap stack operation that kills the current stack
......@@ -691,24 +668,19 @@ pub unsafe extern "C" fn muentry_prepare_swapstack_kill(new_stack: *mut MuStack)
// (i.e. when were are not on the current stack)
let cur_stack = Box::into_raw(cur_thread.stack.take().unwrap());
cur_thread.stack = Some(Box::from_raw(new_stack));
let new_sp = (*new_stack).sp;
trace!("ISAAC: muentry_prepare_swapstack_kill({}) -> ({}, {})", Address::from_ptr(new_stack), new_sp, Address::from_ptr(cur_stack));
(new_sp, cur_stack)
((*new_stack).sp, cur_stack)
}
#[no_mangle]
pub unsafe extern "C" fn muentry_new_stack(entry: Address, stack_size: usize) -> *mut MuStack {
let ref vm = MuThread::current_mut().vm;
let stack = Box::new(MuStack::new(vm.next_id(), entry, stack_size));
let a = Box::into_raw(stack);
trace!("ISAAC: muentry_new_stack({}, {}) -> {}", entry, stack_size, Address::from_mut_ptr(a));
a
Box::into_raw(stack)
}
// Kills the given stack. WARNING! do not call this whilst on the given stack
#[no_mangle]
pub unsafe extern "C" fn muentry_kill_stack(stack: *mut MuStack) {
// This new box will be destroyed upon returning
trace!("ISAAC: muentry_kill_stack({})", Address::from_mut_ptr(stack));
//Box::from_raw(stack);
Box::from_raw(stack);
}
......@@ -3897,7 +3897,7 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
hdr: hdr,
value: None,
ops: vec![impl_opnd],
v: Instruction_::NewStack(0)
v: Instruction_::KillStack(0)
}
}
CMU_CI_UVM_TR64_IS_FP => {
......
......@@ -1201,15 +1201,11 @@ impl<'a> VM {
let func_addr = resolve_symbol(self.name_of(func_id));
let stack_arg_size = backend::call_stack_size(func.sig.clone(), self);
let b = Box::new(MuStack::new(
Box::new(MuStack::new(
self.next_id(),
func_addr,
stack_arg_size
));
let a: Address = unsafe{*(std::mem::transmute::<&Box<MuStack>, &Address>(&b))};
trace!("ISAAC: vm.new_stack({}) -> {}", func_addr, a);
b
))
}
/// creates a handle that we can return to the client
......
......@@ -145,3 +145,25 @@ def test_swapstack_throw_back():
}
""", "test_swapstack_throw_back");
assert(execute("test_swapstack_throw_back", []) == 3);
def test_kill_stack():
compile_bundle(
"""
.funcdef new_func <(stackref)->()>
{
entry(<stackref>s):
COMMINST uvm.kill_stack(s)
CCALL #DEFAULT <exit_type exit_sig> exit(<int<32>>3)
RET
}
.funcdef test_kill_stack <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
cs = COMMINST uvm.current_stack()
s = COMMINST uvm.new_stack<[(stackref)->()]>(new_func)
SWAPSTACK s RET_WITH<> PASS_VALUES<stackref>(cs)
RET <int<32>>0
}
""", "test_kill_stack");
assert(execute("test_kill_stack", []) == 3);
\ 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