WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 1fd56fe4 authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano
Browse files

Implemented Current_stack common instruction

parent 5584d466
......@@ -101,7 +101,9 @@ impl Instruction {
TailCall(_) | Branch1(_) | Branch2 { .. } | Watchpoint { .. } | WPBranch { .. } |
Call { .. } | CCall { .. }| SwapStackExpr{..}| SwapStackExc { .. } | SwapStackKill { .. } | Switch { .. } | ExnInstruction { .. } |
CommonInst_GetThreadLocal | CommonInst_SetThreadLocal(_) | CommonInst_Pin(_) | CommonInst_Unpin(_) |
CommonInst_GetAddr(_) | PrintHex(_) | SetRetval(_) => true,
CommonInst_GetAddr(_) | PrintHex(_) | SetRetval(_) |
CurrentStack // Just heir to prevent interferance with swapstacks
=> true,
_ => false
}
}
......
......@@ -1457,7 +1457,25 @@ impl<'a> InstructionSelection {
vm
);
}
Instruction_::CurrentStack => {
trace!("instsel on CURRENT_STACK");
// get thread local
let tl = self.emit_get_threadlocal(f_context, vm);
let tmp_res = self.get_result_value(node, 0);
// load [tl + STACK_OFFSET] -> tmp_res
// WARNING: This assumes that an Option<Box<MuStack>> is actually just a pointer to a MuStack
emit_load_base_offset(
self.backend.as_mut(),
&tmp_res,
&tl,
*thread::STACK_OFFSET as i64,
f_context,
vm
);
}
Instruction_::CommonInst_GetThreadLocal => {
trace!("instsel on GETTHREADLOCAL");
// get thread local
......@@ -2044,6 +2062,7 @@ impl<'a> InstructionSelection {
is_exception,
ref args
} => {
trace!("Instruction Selection on SWPASTACK-EXPR");
self.emit_swapstack(
is_exception, // is_exception
false, // is_kill
......@@ -2063,6 +2082,7 @@ impl<'a> InstructionSelection {
ref args,
ref resume
} => {
trace!("Instruction Selection on SWPASTACK-EXC");
self.emit_swapstack(
is_exception, // is_exception
false, // is_kill
......@@ -2082,6 +2102,7 @@ impl<'a> InstructionSelection {
is_exception,
ref args
} => {
trace!("Instruction Selection on SWPASTACK-KILL");
self.emit_swapstack(
is_exception, // is_exception
true, // is_kill
......@@ -4362,10 +4383,6 @@ impl<'a> InstructionSelection {
vm
);
} else {
// Pass new_sp and cur_stack in X9 and X10 respectivley
self.backend.emit_mov(&X9, &new_sp);
self.backend.emit_mov(&X10, &cur_stack);
// Prepare arguments
let mut arg_values = vec![];
let arg_nodes = args.iter().map(|a| ops[*a].clone()).collect::<Vec<_>>();
......@@ -4391,6 +4408,10 @@ impl<'a> InstructionSelection {
f_context,
vm
);
// Pass new_sp and cur_stack in X9 and X10 respectivley
self.backend.emit_mov(&X9, &new_sp);
self.backend.emit_mov(&X10, &cur_stack);
arg_regs.push(X9.clone());
arg_regs.push(X10.clone());
......
......@@ -163,12 +163,6 @@ impl MuStack {
);
}
debug!("creating stack {} with entry address {:?}", id, func_addr);
debug!("overflow_guard : {}", overflow_guard);
debug!("lower_bound : {}", lower_bound);
debug!("upper_bound : {}", upper_bound);
debug!("underflow_guard: {}", underflow_guard);
// Set up the stack
let mut sp = upper_bound;
sp -= stack_arg_size; // Allocate space for the arguments
......@@ -184,6 +178,13 @@ impl MuStack {
// Reserve space for callee saved registers (they will be loaded with undefined values)
sp -= WORD_SIZE*CALLEE_SAVED_COUNT;
debug!("creating stack {} with entry address {:?}", id, func_addr);
debug!("overflow_guard : {}", overflow_guard);
debug!("lower_bound : {}", lower_bound);
debug!("stack_pointer : {}", sp);
debug!("upper_bound : {}", upper_bound);
debug!("underflow_guard: {}", underflow_guard);
MuStack {
hdr: MuEntityHeader::unnamed(id),
func: None,
......@@ -347,6 +348,8 @@ lazy_static! {
offset_of!(MuThread=>native_sp_loc).get_byte_offset();
pub static ref USER_TLS_OFFSET : usize =
offset_of!(MuThread=>user_tls).get_byte_offset();
pub static ref STACK_OFFSET : usize =
offset_of!(MuThread=>stack).get_byte_offset();
pub static ref EXCEPTION_OBJ_OFFSET : usize =
offset_of!(MuThread=>exception_obj).get_byte_offset();
}
......@@ -670,7 +673,10 @@ 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));
((*new_stack).sp, &mut (*cur_stack).sp)
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)
}
// This prepares a thread for a swap stack operation that kills the current stack
......
......@@ -16,6 +16,7 @@ from util import execute, compile_bundle, load_bundle, get_function;
import pytest;
import ctypes;
# passes on aarch64
def test_swapstack_simple():
compile_bundle(
"""
......@@ -34,19 +35,20 @@ def test_swapstack_simple():
""", "test_swapstack_simple");
assert(execute("test_swapstack_simple", []) == 3);
# passes on aarch64
def test_swapstack_swap_back():
compile_bundle(
"""
.funcdef new_func <(stackref)->()>
{
entry(<stackref>s):
SWAPSTACK s KILL_OLD PASS_VALUES<>()
SWAPSTACK s KILL_OLD PASS_VALUES<>()
}
.funcdef test_swapstack_swap_back <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
cs = COMMINST current_stack()
s = COMMINST new_stack<[(stackref)->()]>(new_func)
cs = COMMINST uvm.current_stack()
s = COMMINST uvm.new_stack<[(stackref)->()]>(new_func)
SWAPSTACK s RET_WITH<> PASS_VALUES<stackref>(cs)
RET <int<32>>3
......@@ -54,42 +56,26 @@ def test_swapstack_swap_back():
""", "test_swapstack_swap_back");
assert(execute("test_swapstack_swap_back", []) == 3);
# segfaults on aarch64
def test_swapstack_pass_vals():
compile_bundle(
"""
.funcdef new_func <(stackref)->()>
{
entry(<stackref>s):
SWAPSTACK s KILL_OLD PASS_VALUES<int<32>>(<int<32> 3)
SWAPSTACK s KILL_OLD PASS_VALUES<int<32>>(<int<32>> 3)
}
.funcdef test_swapstack_pass_vals <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
s = COMMINST new_stack<[()->()]>(new_func)
r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<>() EXC(body(r))
RET r
}
""", "test_swapstack_pass_vals");
assert(execute("test_swapstack_pass_vals", []) == 3);
def test_swapstack_pass_vals():
compile_bundle(
"""
.funcdef new_func <(stackref)->()>
{
entry(<stackref>s):
SWAPSTACK s KILL_OLD PASS_VALUES<int<32>>(<int<32> 3)
}
.funcdef test_swapstack_pass_vals <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
s = COMMINST new_stack<[()->()]>(new_func)
s = COMMINST uvm.new_stack<[(stackref)->()]>(new_func)
r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<>()
RET r
}
""", "test_swapstack_pass_vals");
assert(execute("test_swapstack_pass_vals", []) == 3);
# Work in progress...
def test_swapstack_throw():
compile_bundle(
"""
......@@ -102,8 +88,13 @@ def test_swapstack_throw():
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
s = COMMINST new_stack<[()->()]>(new_func)
r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<>() EXC(norm(r))
r = SWAPSTACK s RET_WITH<int<32>> PASS_VALUES<>() EXC(nor_dest(r) exc_dest())
RET r
nor_dest(<int<32>>):
RET <int<32>>0
exc_dest()[exc_param]:
REFCAST <from_ty tot__ty>
RET <int<32>>0
}
""", "test_swapstack_pass_vals");
assert(execute("test_swapstack_pass_vals", []) == 3);
\ No newline at end of file
assert(execute("test_swapstack_pass_vals", []) == 3);
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