about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/error.rs14
-rw-r--r--src/libstd/io/mod.rs2
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/path.rs2
-rw-r--r--src/libstd/primitive_docs.rs5
-rw-r--r--src/libstd/sys/sgx/abi/mem.rs4
-rw-r--r--src/libstd/sys/sgx/backtrace.rs87
-rw-r--r--src/libstd/sys/sgx/ext/arch.rs4
8 files changed, 96 insertions, 24 deletions
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index f026cadd639..2f9efb3f0fb 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -30,17 +30,17 @@ use string;
 /// themselves through the [`Display`] and [`Debug`] traits, and may provide
 /// cause chain information:
 ///
-/// The [`cause`] method is generally used when errors cross "abstraction
-/// boundaries", i.e.,  when a one module must report an error that is "caused"
-/// by an error from a lower-level module. This setup makes it possible for the
-/// high-level module to provide its own errors that do not commit to any
-/// particular implementation, but also reveal some of its implementation for
-/// debugging via [`cause`] chains.
+/// The [`source`] method is generally used when errors cross "abstraction
+/// boundaries". If one module must report an error that is caused by an error
+/// from a lower-level module, it can allow access to that error via the
+/// [`source`] method. This makes it possible for the high-level module to
+/// provide its own errors while also revealing some of the implementation for
+/// debugging via [`source`] chains.
 ///
 /// [`Result<T, E>`]: ../result/enum.Result.html
 /// [`Display`]: ../fmt/trait.Display.html
 /// [`Debug`]: ../fmt/trait.Debug.html
-/// [`cause`]: trait.Error.html#method.cause
+/// [`source`]: trait.Error.html#method.source
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Error: Debug + Display {
     /// **This method is soft-deprecated.**
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 0991957fa7f..28a6fbd48cf 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -252,7 +252,7 @@
 //! [`println!`]: ../macro.println.html
 //! [`Lines`]: struct.Lines.html
 //! [`io::Result`]: type.Result.html
-//! [`?` operator]: ../../book/first-edition/syntax-index.html
+//! [`?` operator]: ../../book/appendix-02-operators.html
 //! [`Read::read`]: trait.Read.html#tymethod.read
 //! [`Result`]: ../result/enum.Result.html
 //! [`.unwrap()`]: ../result/enum.Result.html#method.unwrap
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 701565191b9..e2200808449 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -305,7 +305,7 @@
 #![feature(maybe_uninit)]
 #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
             feature(global_asm, range_contains, slice_index_methods,
-                    decl_macro, coerce_unsized, sgx_platform))]
+                    decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))]
 
 #![default_lib_allocator]
 
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 317a7d817db..5c7bff70a0d 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -2203,6 +2203,8 @@ impl Path {
     ///   `a/b` all have `a` and `b` as components, but `./a/b` starts with
     ///   an additional [`CurDir`] component.
     ///
+    /// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
+    ///
     /// Note that no other normalization takes place; in particular, `a/c`
     /// and `a/b/../c` are distinct, to account for the possibility that `b`
     /// is a symbolic link (so its parent isn't `a`).
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index 475c9b4aeaa..c2751508ce0 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -550,7 +550,6 @@ mod prim_array { }
 #[doc(alias = "[")]
 #[doc(alias = "]")]
 #[doc(alias = "[]")]
-//
 /// A dynamically-sized view into a contiguous sequence, `[T]`.
 ///
 /// *[See also the `std::slice` module](slice/index.html).*
@@ -572,11 +571,11 @@ mod prim_array { }
 /// points to:
 ///
 /// ```
-/// let x = &mut [1, 2, 3];
+/// let mut x = [1, 2, 3];
+/// let x = &mut x[..]; // Take a full slice of `x`.
 /// x[1] = 7;
 /// assert_eq!(x, &[1, 7, 3]);
 /// ```
-///
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_slice { }
 
diff --git a/src/libstd/sys/sgx/abi/mem.rs b/src/libstd/sys/sgx/abi/mem.rs
index 09552d5b4af..808f1ce3ff2 100644
--- a/src/libstd/sys/sgx/abi/mem.rs
+++ b/src/libstd/sys/sgx/abi/mem.rs
@@ -17,8 +17,10 @@ extern {
 // Do not remove inline: will result in relocation failure
 // For the same reason we use inline ASM here instead of an extern static to
 // locate the base
+/// Returns address at which current enclave is loaded.
 #[inline(always)]
-fn image_base() -> u64 {
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub fn image_base() -> u64 {
     let base;
     unsafe { asm!("lea IMAGE_BASE(%rip),$0":"=r"(base)) };
     base
diff --git a/src/libstd/sys/sgx/backtrace.rs b/src/libstd/sys/sgx/backtrace.rs
index 52d4a63bb63..2b8e1da0579 100644
--- a/src/libstd/sys/sgx/backtrace.rs
+++ b/src/libstd/sys/sgx/backtrace.rs
@@ -1,21 +1,90 @@
 use io;
-use sys::unsupported;
+use error::Error;
+use libc;
 use sys_common::backtrace::Frame;
+use unwind as uw;
+use sys::sgx::abi::mem::image_base;
 
 pub struct BacktraceContext;
 
-pub fn unwind_backtrace(_frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    unsupported()
+struct Context<'a> {
+    idx: usize,
+    frames: &'a mut [Frame],
+}
+
+#[derive(Debug)]
+struct UnwindError(uw::_Unwind_Reason_Code);
+
+impl Error for UnwindError {
+    fn description(&self) -> &'static str {
+        "unexpected return value while unwinding"
+    }
+}
+
+impl ::fmt::Display for UnwindError {
+    fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
+        write!(f, "{}: {:?}", self.description(), self.0)
+    }
+}
+
+#[inline(never)] // this function call can be skipped it when tracing.
+pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
+    let mut cx = Context { idx: 0, frames };
+    let result_unwind =
+        unsafe { uw::_Unwind_Backtrace(trace_fn, &mut cx as *mut Context as *mut libc::c_void) };
+    // See libunwind:src/unwind/Backtrace.c for the return values.
+    // No, there is no doc.
+    let res = match result_unwind {
+        // These return codes seem to be benign and need to be ignored for backtraces
+        // to show up properly on all tested platforms.
+        uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
+            Ok((cx.idx, BacktraceContext))
+        }
+        _ => Err(io::Error::new(
+            io::ErrorKind::Other,
+            UnwindError(result_unwind),
+        )),
+    };
+    res
+}
+
+extern "C" fn trace_fn(
+    ctx: *mut uw::_Unwind_Context,
+    arg: *mut libc::c_void,
+) -> uw::_Unwind_Reason_Code {
+    let cx = unsafe { &mut *(arg as *mut Context) };
+    if cx.idx >= cx.frames.len() {
+        return uw::_URC_NORMAL_STOP;
+    }
+
+    let mut ip_before_insn = 0;
+    let mut ip = unsafe { uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void };
+    if !ip.is_null() && ip_before_insn == 0 {
+        // this is a non-signaling frame, so `ip` refers to the address
+        // after the calling instruction. account for that.
+        ip = (ip as usize - 1) as *mut _;
+    }
+
+    let symaddr = unsafe { uw::_Unwind_FindEnclosingFunction(ip) };
+    cx.frames[cx.idx] = Frame {
+        symbol_addr: symaddr as *mut u8,
+        exact_position: ip as *mut u8,
+        inline_context: 0,
+    };
+    cx.idx += 1;
+
+    uw::_URC_NO_REASON
 }
 
-pub fn resolve_symname<F>(_frame: Frame,
-                          _callback: F,
+// To reduce TCB size in Sgx enclave, we do not want to implement resolve_symname functionality.
+// Rather, we print the offset of the address here, which could be later mapped to correct function.
+pub fn resolve_symname<F>(frame: Frame,
+                          callback: F,
                           _: &BacktraceContext) -> io::Result<()>
     where F: FnOnce(Option<&str>) -> io::Result<()>
 {
-    unsupported()
+    callback(Some(&format!("0x{:x}",
+            (frame.symbol_addr.wrapping_offset_from(image_base() as _)))))
 }
 
 pub fn foreach_symbol_fileline<F>(_: Frame,
@@ -23,5 +92,5 @@ pub fn foreach_symbol_fileline<F>(_: Frame,
                                   _: &BacktraceContext) -> io::Result<bool>
     where F: FnMut(&[u8], u32) -> io::Result<()>
 {
-    unsupported()
+    Ok(false)
 }
diff --git a/src/libstd/sys/sgx/ext/arch.rs b/src/libstd/sys/sgx/ext/arch.rs
index ba6f9e622ad..3bd87b5d265 100644
--- a/src/libstd/sys/sgx/ext/arch.rs
+++ b/src/libstd/sys/sgx/ext/arch.rs
@@ -36,7 +36,7 @@ pub fn egetkey(request: &Align512<[u8; 512]>) -> Result<Align16<[u8; 16]>, u32>
             : "={eax}"(error)
             : "{eax}"(ENCLU_EGETKEY),
               "{rbx}"(request),
-              "{rcx}"(out.get_mut())
+              "{rcx}"(out.as_mut_ptr())
             : "flags"
         );
 
@@ -66,7 +66,7 @@ pub fn ereport(
             : "{eax}"(ENCLU_EREPORT),
               "{rbx}"(targetinfo),
               "{rcx}"(reportdata),
-              "{rdx}"(report.get_mut())
+              "{rdx}"(report.as_mut_ptr())
         );
 
         report.into_inner()