mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
SGX target: improve panic & exit handling
This commit is contained in:
parent
5f60208ba1
commit
a75ae00c63
@ -66,7 +66,7 @@ IMAGE_BASE:
|
|||||||
globvar EH_FRM_HDR_SIZE 8
|
globvar EH_FRM_HDR_SIZE 8
|
||||||
|
|
||||||
.Lreentry_panic_msg:
|
.Lreentry_panic_msg:
|
||||||
.asciz "Re-entered panicked enclave!"
|
.asciz "Re-entered aborted enclave!"
|
||||||
.Lreentry_panic_msg_end:
|
.Lreentry_panic_msg_end:
|
||||||
|
|
||||||
.Lusercall_panic_msg:
|
.Lusercall_panic_msg:
|
||||||
@ -80,7 +80,7 @@ IMAGE_BASE:
|
|||||||
.org .+48 /* reserved bits */
|
.org .+48 /* reserved bits */
|
||||||
|
|
||||||
.data
|
.data
|
||||||
.Lpanicked:
|
.Laborted:
|
||||||
.byte 0
|
.byte 0
|
||||||
|
|
||||||
/* TCS local storage section */
|
/* TCS local storage section */
|
||||||
@ -134,6 +134,9 @@ sgx_entry:
|
|||||||
jz .Lskip_debug_init
|
jz .Lskip_debug_init
|
||||||
mov %r10,%gs:tcsls_debug_panic_buf_ptr
|
mov %r10,%gs:tcsls_debug_panic_buf_ptr
|
||||||
.Lskip_debug_init:
|
.Lskip_debug_init:
|
||||||
|
/* check for abort */
|
||||||
|
bt $0,.Laborted(%rip)
|
||||||
|
jc .Lreentry_panic
|
||||||
/* check if returning from usercall */
|
/* check if returning from usercall */
|
||||||
mov %gs:tcsls_last_rsp,%r11
|
mov %gs:tcsls_last_rsp,%r11
|
||||||
test %r11,%r11
|
test %r11,%r11
|
||||||
@ -164,9 +167,6 @@ sgx_entry:
|
|||||||
mov %r14,%r8
|
mov %r14,%r8
|
||||||
mov %r15,%r9
|
mov %r15,%r9
|
||||||
.Lskip_init:
|
.Lskip_init:
|
||||||
/* check for panic */
|
|
||||||
bt $0,.Lpanicked(%rip)
|
|
||||||
jc .Lreentry_panic
|
|
||||||
/* call into main entry point */
|
/* call into main entry point */
|
||||||
load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */
|
load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */
|
||||||
call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */
|
call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */
|
||||||
@ -237,18 +237,18 @@ sgx_entry:
|
|||||||
stmxcsr (%rsp)
|
stmxcsr (%rsp)
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.global panic_exit
|
.global usercall_exit
|
||||||
panic_exit:
|
usercall_exit:
|
||||||
/* save registers in DEBUG mode, so that debugger can reconstruct the stack */
|
/* save registers in DEBUG mode, so that debugger can reconstruct the stack */
|
||||||
testb $0xff,DEBUG(%rip)
|
testb $0xff,DEBUG(%rip)
|
||||||
jz .Lskip_save_registers
|
jz .Lskip_save_registers
|
||||||
push_callee_saved_registers
|
push_callee_saved_registers
|
||||||
movq %rsp,%gs:tcsls_panic_last_rsp
|
movq %rsp,%gs:tcsls_panic_last_rsp
|
||||||
.Lskip_save_registers:
|
.Lskip_save_registers:
|
||||||
/* set panicked bit */
|
/* set aborted bit */
|
||||||
movb $1,.Lpanicked(%rip)
|
movb $1,.Laborted(%rip)
|
||||||
/* call usercall exit(true) */
|
/* 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 */
|
xor %rdx,%rdx /* RDX cleared */
|
||||||
movq $usercall_nr_exit,%rdi /* RDI = usercall exit */
|
movq $usercall_nr_exit,%rdi /* RDI = usercall exit */
|
||||||
jmp .Lexit
|
jmp .Lexit
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
|
use super::usercalls::alloc::UserRef;
|
||||||
|
use cmp;
|
||||||
use io::{self, Write};
|
use io::{self, Write};
|
||||||
use slice::from_raw_parts_mut;
|
use mem;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn take_debug_panic_buf_ptr() -> *mut u8;
|
fn take_debug_panic_buf_ptr() -> *mut u8;
|
||||||
static DEBUG: 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 {
|
impl SgxPanicOutput {
|
||||||
pub(crate) fn new() -> Option<Self> {
|
pub(crate) fn new() -> Option<Self> {
|
||||||
@ -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 {
|
self.0.get_or_insert_with(|| unsafe {
|
||||||
let ptr = take_debug_panic_buf_ptr();
|
let ptr = take_debug_panic_buf_ptr();
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
&mut []
|
empty_user_slice()
|
||||||
} else {
|
} else {
|
||||||
from_raw_parts_mut(ptr, 1024)
|
UserRef::from_raw_parts_mut(ptr, 1024)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Write for SgxPanicOutput {
|
impl Write for SgxPanicOutput {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
|
||||||
self.init().write(buf)
|
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<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
self.init().flush()
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn panic_msg(msg: &str) -> ! {
|
pub extern "C" fn panic_msg(msg: &str) -> ! {
|
||||||
let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes()));
|
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) -> !; }
|
||||||
|
@ -119,7 +119,7 @@ pub unsafe fn launch_thread() -> IoResult<()> {
|
|||||||
/// Usercall `exit`. See the ABI documentation for more information.
|
/// Usercall `exit`. See the ABI documentation for more information.
|
||||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||||
pub fn exit(panic: bool) -> ! {
|
pub fn exit(panic: bool) -> ! {
|
||||||
unsafe { raw::exit(panic) }
|
unsafe { super::panic::usercall_exit(panic) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Usercall `wait`. See the ABI documentation for more information.
|
/// Usercall `wait`. See the ABI documentation for more information.
|
||||||
|
@ -125,7 +125,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn abort_internal() -> ! {
|
pub unsafe fn abort_internal() -> ! {
|
||||||
abi::panic::panic_exit()
|
abi::panic::usercall_exit(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hashmap_random_keys() -> (u64, u64) {
|
pub fn hashmap_random_keys() -> (u64, u64) {
|
||||||
|
Loading…
Reference in New Issue
Block a user