use super::usercalls::alloc::UserRef; use crate::cmp; use crate::io::{self, Write}; use crate::mem; extern "C" { fn take_debug_panic_buf_ptr() -> *mut u8; static DEBUG: 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 { if unsafe { DEBUG == 0 } { None } else { Some(SgxPanicOutput(None)) } } 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() { empty_user_slice() } else { UserRef::from_raw_parts_mut(ptr, 1024) } }) } } impl Write for SgxPanicOutput { fn write(&mut self, src: &[u8]) -> io::Result { 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<()> { Ok(()) } }