about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-01-12 11:22:20 +0000
committerbors <bors@rust-lang.org>2019-01-12 11:22:20 +0000
commitd6525ef539a04cb43de40080bdabc5f2f5a4a197 (patch)
tree8abef858718c138adecb80e45339ba8df8bf9f97 /src/libstd/sys
parent1190f7cdf7a62e25c9a8eaf58e0906849692bf2b (diff)
parent3117784c1846e8d45c711703d1693e835cf4679e (diff)
downloadrust-d6525ef539a04cb43de40080bdabc5f2f5a4a197.tar.gz
rust-d6525ef539a04cb43de40080bdabc5f2f5a4a197.zip
Auto merge of #57542 - Centril:rollup, r=Centril
Rollup of 26 pull requests

Successful merges:

 - #56425 (Redo the docs for Vec::set_len)
 - #56906 (Issue #56905)
 - #57042 (Don't call `FieldPlacement::count` when count is too large)
 - #57175 (Stabilize `let` bindings and destructuring in constants and const fn)
 - #57192 (Change std::error::Error trait documentation to talk about `source` instead of `cause`)
 - #57296 (Fixed the link to the ? operator)
 - #57368 (Use CMAKE_{C,CXX}_COMPILER_LAUNCHER for ccache)
 - #57400 (Rustdoc: update Source Serif Pro and replace Heuristica italic)
 - #57417 (rustdoc: use text-based doctest parsing if a macro is wrapping main)
 - #57433 (Add link destination for `read-ownership`)
 - #57434 (Remove `CrateNum::Invalid`.)
 - #57441 (Supporting backtrace for x86_64-fortanix-unknown-sgx.)
 - #57450 (actually take a slice in this example)
 - #57459 (Reference tracking issue for inherent associated types in diagnostic)
 - #57463 (docs: Fix some 'second-edition' links)
 - #57466 (Remove outdated comment)
 - #57493 (use structured suggestion when casting a reference)
 - #57498 (make note of one more normalization that Paths do)
 - #57499 (note that FromStr does not work for borrowed types)
 - #57505 (Remove submodule step from README)
 - #57510 (Add a profiles section to the manifest)
 - #57511 (Fix undefined behavior)
 - #57519 (Correct RELEASES.md for 1.32.0)
 - #57522 (don't unwrap unexpected tokens in `format!`)
 - #57530 (Fixing a typographical error.)
 - #57535 (Stabilise irrefutable if-let and while-let patterns)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libstd/sys')
-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
3 files changed, 83 insertions, 12 deletions
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()