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 7e5c1e7a authored by qinsoon's avatar qinsoon
Browse files

[wip] fixed an exception bug: when finding a catch block, by mistake we

still restored callee-saved registers, should directly jump to it
parent c6bdd727
......@@ -470,7 +470,7 @@ impl ASMCode {
None
} else {
let mut cur = i;
while cur >= 0 {
loop {
if !asm[cur].is_symbol {
return Some(cur);
}
......@@ -481,8 +481,6 @@ impl ASMCode {
cur -= 1;
}
}
None
}
}
......
......@@ -81,7 +81,7 @@ macro_rules! FPR {
GPR_ALIAS!(RAX_ALIAS: (0, RAX) -> EAX, AX , AL, AH);
GPR_ALIAS!(RCX_ALIAS: (5, RCX) -> ECX, CX , CL, CH);
GPR_ALIAS!(RDX_ALIAS: (10, RDX) -> EDX, DX , DL, DH);
GPR_ALIAS!(RDX_ALIAS: (10,RDX) -> EDX, DX , DL, DH);
GPR_ALIAS!(RBX_ALIAS: (15,RBX) -> EBX, BX , BL, BH);
GPR_ALIAS!(RSP_ALIAS: (20,RSP) -> ESP, SP , SPL);
GPR_ALIAS!(RBP_ALIAS: (24,RBP) -> EBP, BP , BPL);
......
......@@ -102,41 +102,21 @@ pub extern fn throw_exception_internal(exception_obj: Address, last_frame_callee
rwlock_cf.frame.clone()
};
trace!("frame info: {}", frame);
// update callee saved register location
for reg in x86_64::CALLEE_SAVED_GPRs.iter() {
let reg_id = reg.id();
trace!("update callee saved register {}", reg_id);
if frame.allocated.contains_key(&reg_id) {
let offset_from_rbp = frame.allocated.get(&reg_id).unwrap().offset;
let reg_restore_addr = cursor.rbp.offset(offset_from_rbp);
trace!("update callee saved register {} with loc 0x{:x}", reg_id, reg_restore_addr);
cursor.callee_saved_locs.insert(reg_id, reg_restore_addr);
} else {
// rbp won't find a location
if reg_id == x86_64::RBP.id() {
} else {
info!("failed to find an entry for {} in current frame", reg_id);
}
}
}
// find exception block - comparing callsite with frame info
trace!("checking catch block: looking for callsite 0x{:x}", callsite);
let exception_callsites = frame.get_exception_callsites();
for &(ref possible_callsite, ref dest) in exception_callsites.iter() {
let possible_callsite_addr = possible_callsite.to_address();
trace!("..check {} at 0x{:x}", possible_callsite, possible_callsite_addr);
if callsite == possible_callsite_addr {
trace!("found catch block at {}", dest);
// found an exception block
let dest_addr = dest.to_address();
// restore callee saved register and jump to dest_addr
// prepare a plain array [rbx, rbp, r12, r13, r14, r15]
macro_rules! unpack_callee_saved_from_cursor {
($reg: expr) => {
......@@ -149,7 +129,7 @@ pub extern fn throw_exception_internal(exception_obj: Address, last_frame_callee
}
}
};
let rbx = unpack_callee_saved_from_cursor!(x86_64::RBX);
let r12 = unpack_callee_saved_from_cursor!(x86_64::R12);
let r13 = unpack_callee_saved_from_cursor!(x86_64::R13);
......@@ -157,16 +137,36 @@ pub extern fn throw_exception_internal(exception_obj: Address, last_frame_callee
let r15 = unpack_callee_saved_from_cursor!(x86_64::R15);
let rbp = cursor.rbp.as_usize() as Word;
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!()
}
}
trace!("didnt find a catch block");
// update callee saved register location
for reg in x86_64::CALLEE_SAVED_GPRs.iter() {
let reg_id = reg.id();
trace!("update callee saved register {}", reg.name().unwrap());
if frame.allocated.contains_key(&reg_id) {
let offset_from_rbp = frame.allocated.get(&reg_id).unwrap().offset;
let reg_restore_addr = cursor.rbp.offset(offset_from_rbp);
trace!("update callee saved register {} with loc 0x{:x}", reg.name().unwrap(), reg_restore_addr);
cursor.callee_saved_locs.insert(reg_id, reg_restore_addr);
} else {
// rbp won't find a location
if reg_id == x86_64::RBP.id() {
info!("skip RBP");
} else {
info!("failed to find an entry for {} in current frame", reg.name().unwrap());
}
}
}
// keep unwinding
callsite = cursor.return_addr;
......@@ -239,7 +239,8 @@ impl fmt::Display for FrameCursor {
writeln!(f, " rbp=0x{:x}, return_addr=0x{:x}, func_id={}, func_version_id={}", self.rbp, self.return_addr, self.func_id, self.func_ver_id).unwrap();
writeln!(f, " callee_saved:").unwrap();
for (reg, addr) in self.callee_saved_locs.iter() {
writeln!(f, " #{} at 0x{:x}", reg, addr).unwrap()
let val = unsafe {addr.load::<u64>()};
writeln!(f, " #{} at 0x{:x} (value=0x{:x}", reg, addr, val).unwrap()
}
writeln!(f, "}}")
}
......
......@@ -312,7 +312,6 @@ fn throw_catch_dont_use_exception_arg() -> VM {
}
#[test]
#[ignore]
// issue: didn't restore callee-saved register correctly, temporarily ignore this test
// FIXME: fix the bug
fn test_exception_throw_catch_and_add() {
......@@ -455,13 +454,23 @@ fn create_catch_exception_and_add(vm: &VM) {
inst! ((vm, catch_and_add_v1) blk_exception_px4:
PRINTHEX ev4
);
// load and print exc_arg
let iref_int64 = vm.get_type(vm.id_of("iref_int64"));
ssa! ((vm, catch_and_add_v1) <iref_int64> exc_iref);
inst! ((vm, catch_and_add_v1) blk_exception_getiref:
exc_iref = GETIREF exc_arg
);
ssa! ((vm, catch_and_add_v1) <int64> exc_val);
inst! ((vm, catch_and_add_v1) blk_exception_load_exc:
exc_val = LOAD exc_iref (is_ptr: false, order: MemoryOrder::SeqCst)
);
inst! ((vm, catch_and_add_v1) blk_exception_px5:
PRINTHEX exc_arg
PRINTHEX exc_val
);
ssa! ((vm, catch_and_add_v1) <int64> res0);
inst! ((vm, catch_and_add_v1) blk_exception_add0:
res0 = BINOP (BinOp::Add) exc_arg ev0
res0 = BINOP (BinOp::Add) exc_val ev0
);
ssa! ((vm, catch_and_add_v1) <int64> res1);
......@@ -496,6 +505,9 @@ fn create_catch_exception_and_add(vm: &VM) {
blk_exception_px2,
blk_exception_px3,
blk_exception_px4,
blk_exception_getiref,
blk_exception_load_exc,
blk_exception_px5,
blk_exception_add0,
......
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