Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SGX target: improve panic & exit handling #57971

Merged
merged 1 commit into from
Jan 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/libstd/sys/sgx/abi/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ IMAGE_BASE:
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:
Expand All @@ -80,7 +80,7 @@ IMAGE_BASE:
.org .+48 /* reserved bits */

.data
.Lpanicked:
.Laborted:
.byte 0

/* TCS local storage section */
Expand Down Expand Up @@ -134,6 +134,9 @@ sgx_entry:
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
Expand Down Expand Up @@ -164,9 +167,6 @@ sgx_entry:
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 */
Expand Down Expand Up @@ -237,18 +237,18 @@ sgx_entry:
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
Expand Down
30 changes: 20 additions & 10 deletions src/libstd/sys/sgx/abi/panic.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
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> {
Expand All @@ -17,32 +23,36 @@ impl SgxPanicOutput {
}
}

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) -> !; }
2 changes: 1 addition & 1 deletion src/libstd/sys/sgx/abi/usercalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ pub unsafe fn launch_thread() -> IoResult<()> {
/// 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.
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/sgx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
}

pub unsafe fn abort_internal() -> ! {
abi::panic::panic_exit()
abi::panic::usercall_exit(true)
}

pub fn hashmap_random_keys() -> (u64, u64) {
Expand Down