globvar EH_FRM_HDR_SIZE 8
.Lreentry_panic_msg:
- .asciz "Re-entered panicked enclave!"
+ .asciz "Re-entered aborted enclave!"
.Lreentry_panic_msg_end:
.Lusercall_panic_msg:
.org .+48 /* reserved bits */
.data
-.Lpanicked:
+.Laborted:
.byte 0
/* TCS local storage section */
jz .Lskip_debug_init
mov %r10,%gs:tcsls_debug_panic_buf_ptr
.Lskip_debug_init:
+/* check for abort */
+ bt $0,.Laborted(%rip)
+ jc .Lreentry_panic
/* check if returning from usercall */
mov %gs:tcsls_last_rsp,%r11
test %r11,%r11
mov %r14,%r8
mov %r15,%r9
.Lskip_init:
-/* check for panic */
- bt $0,.Lpanicked(%rip)
- jc .Lreentry_panic
/* call into main entry point */
load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */
call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */
stmxcsr (%rsp)
.endm
-.global panic_exit
-panic_exit:
+.global usercall_exit
+usercall_exit:
/* save registers in DEBUG mode, so that debugger can reconstruct the stack */
testb $0xff,DEBUG(%rip)
jz .Lskip_save_registers
push_callee_saved_registers
movq %rsp,%gs:tcsls_panic_last_rsp
.Lskip_save_registers:
-/* set panicked bit */
- movb $1,.Lpanicked(%rip)
+/* set aborted bit */
+ movb $1,.Laborted(%rip)
/* call usercall exit(true) */
- mov $1,%esi /* RSI = usercall() argument: panic = true */
+ /* NOP: mov %rsi,%rsi */ /* RSI = usercall() argument: panic */
xor %rdx,%rdx /* RDX cleared */
movq $usercall_nr_exit,%rdi /* RDI = usercall exit */
jmp .Lexit
+use super::usercalls::alloc::UserRef;
+use cmp;
use io::{self, Write};
-use slice::from_raw_parts_mut;
+use mem;
extern "C" {
fn take_debug_panic_buf_ptr() -> *mut u8;
static DEBUG: u8;
}
-pub(crate) struct SgxPanicOutput(Option<&'static mut [u8]>);
+pub(crate) struct SgxPanicOutput(Option<&'static mut UserRef<[u8]>>);
+
+fn empty_user_slice() -> &'static mut UserRef<[u8]> {
+ unsafe { UserRef::from_raw_parts_mut(1 as *mut u8, 0) }
+}
impl SgxPanicOutput {
pub(crate) fn new() -> Option<Self> {
}
}
- fn init(&mut self) -> &mut &'static mut [u8] {
+ fn init(&mut self) -> &mut &'static mut UserRef<[u8]> {
self.0.get_or_insert_with(|| unsafe {
let ptr = take_debug_panic_buf_ptr();
if ptr.is_null() {
- &mut []
+ empty_user_slice()
} else {
- from_raw_parts_mut(ptr, 1024)
+ UserRef::from_raw_parts_mut(ptr, 1024)
}
})
}
}
impl Write for SgxPanicOutput {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.init().write(buf)
+ fn write(&mut self, src: &[u8]) -> io::Result<usize> {
+ let dst = mem::replace(self.init(), empty_user_slice());
+ let written = cmp::min(src.len(), dst.len());
+ dst[..written].copy_from_enclave(&src[..written]);
+ self.0 = Some(&mut dst[written..]);
+ Ok(written)
}
fn flush(&mut self) -> io::Result<()> {
- self.init().flush()
+ Ok(())
}
}
#[no_mangle]
pub extern "C" fn panic_msg(msg: &str) -> ! {
let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes()));
- unsafe { panic_exit(); }
+ unsafe { usercall_exit(true); }
}
-extern "C" { pub fn panic_exit() -> !; }
+extern "C" { pub fn usercall_exit(panic: bool) -> !; }
/// Usercall `exit`. See the ABI documentation for more information.
#[unstable(feature = "sgx_platform", issue = "56975")]
pub fn exit(panic: bool) -> ! {
- unsafe { raw::exit(panic) }
+ unsafe { super::panic::usercall_exit(panic) }
}
/// Usercall `wait`. See the ABI documentation for more information.
}
pub unsafe fn abort_internal() -> ! {
- abi::panic::panic_exit()
+ abi::panic::usercall_exit(true)
}
pub fn hashmap_random_keys() -> (u64, u64) {