about summary refs log tree commit diff
path: root/src/libstd/sys/sgx
diff options
context:
space:
mode:
authorVardhan Thigle <vardhan.thigle@fortanix.com>2018-12-14 18:38:15 +0530
committerVardhan Thigle <vardhan.thigle@fortanix.com>2018-12-19 18:31:58 +0530
commit885cf2a2afd6da270287cfc3bfa651ac737d0378 (patch)
treea58756f602c09a61d71f9a3ea0367a0004f7c7ce /src/libstd/sys/sgx
parent041254b81495a5aa67af839e00b890e78ed0cbeb (diff)
downloadrust-885cf2a2afd6da270287cfc3bfa651ac737d0378.tar.gz
rust-885cf2a2afd6da270287cfc3bfa651ac737d0378.zip
Adding unwinding support for x86_64_fortanix_unknown_sgx target.
Diffstat (limited to 'src/libstd/sys/sgx')
-rw-r--r--src/libstd/sys/sgx/abi/entry.S8
-rw-r--r--src/libstd/sys/sgx/rwlock.rs137
2 files changed, 139 insertions, 6 deletions
diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S
index 4d5cc02e11e..49ede0674ce 100644
--- a/src/libstd/sys/sgx/abi/entry.S
+++ b/src/libstd/sys/sgx/abi/entry.S
@@ -56,6 +56,14 @@ IMAGE_BASE:
     globvar CFGDATA_BASE 8
     /*  Non-zero if debugging is enabled, zero otherwise */
     globvar DEBUG 1
+    /*  The base address (relative to enclave start) of the enclave text section */
+    globvar TEXT_BASE 8
+    /*  The size in bytes of enclacve text section */
+    globvar TEXT_SIZE 8
+    /*  The base address (relative to enclave start) of the enclave EH_FRM_HDR section */
+    globvar EH_FRM_HDR_BASE 8
+    /*  The size in bytes of enclacve EH_FRM_HDR section */
+    globvar EH_FRM_HDR_SIZE 8
 
 .Lreentry_panic_msg:
     .asciz "Re-entered panicked enclave!"
diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs
index a1551dbb53b..d1af98bd4f5 100644
--- a/src/libstd/sys/sgx/rwlock.rs
+++ b/src/libstd/sys/sgx/rwlock.rs
@@ -9,14 +9,25 @@
 // except according to those terms.
 
 use num::NonZeroUsize;
+use slice;
+use str;
 
-use super::waitqueue::{WaitVariable, WaitQueue, SpinMutex, NotifiedTcs, try_lock_or_false};
+use super::waitqueue::{
+    try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable,
+};
+use mem;
 
 pub struct RWLock {
     readers: SpinMutex<WaitVariable<Option<NonZeroUsize>>>,
     writer: SpinMutex<WaitVariable<bool>>,
 }
 
+// Below is to check at compile time, that RWLock has size of 128 bytes.
+#[allow(dead_code)]
+unsafe fn rw_lock_size_assert(r: RWLock) {
+    mem::transmute::<RWLock, [u8; 128]>(r);
+}
+
 //unsafe impl Send for RWLock {}
 //unsafe impl Sync for RWLock {} // FIXME
 
@@ -24,7 +35,7 @@ impl RWLock {
     pub const fn new() -> RWLock {
         RWLock {
             readers: SpinMutex::new(WaitVariable::new(None)),
-            writer: SpinMutex::new(WaitVariable::new(false))
+            writer: SpinMutex::new(WaitVariable::new(false)),
         }
     }
 
@@ -89,9 +100,11 @@ impl RWLock {
     }
 
     #[inline]
-    pub unsafe fn read_unlock(&self) {
-        let mut rguard = self.readers.lock();
-        let wguard = self.writer.lock();
+    unsafe fn __read_unlock(
+        &self,
+        mut rguard: SpinMutexGuard<WaitVariable<Option<NonZeroUsize>>>,
+        wguard: SpinMutexGuard<WaitVariable<bool>>,
+    ) {
         *rguard.lock_var_mut() = NonZeroUsize::new(rguard.lock_var().unwrap().get() - 1);
         if rguard.lock_var().is_some() {
             // There are other active readers
@@ -107,9 +120,18 @@ impl RWLock {
     }
 
     #[inline]
-    pub unsafe fn write_unlock(&self) {
+    pub unsafe fn read_unlock(&self) {
         let rguard = self.readers.lock();
         let wguard = self.writer.lock();
+        self.__read_unlock(rguard, wguard);
+    }
+
+    #[inline]
+    unsafe fn __write_unlock(
+        &self,
+        rguard: SpinMutexGuard<WaitVariable<Option<NonZeroUsize>>>,
+        wguard: SpinMutexGuard<WaitVariable<bool>>,
+    ) {
         if let Err(mut wguard) = WaitQueue::notify_one(wguard) {
             // No writers waiting, release the write lock
             *wguard.lock_var_mut() = false;
@@ -129,5 +151,108 @@ impl RWLock {
     }
 
     #[inline]
+    pub unsafe fn write_unlock(&self) {
+        let rguard = self.readers.lock();
+        let wguard = self.writer.lock();
+        self.__write_unlock(rguard, wguard);
+    }
+
+    #[inline]
+    unsafe fn unlock(&self) {
+        let rguard = self.readers.lock();
+        let wguard = self.writer.lock();
+        if *wguard.lock_var() == true {
+            self.__write_unlock(rguard, wguard);
+        } else {
+            self.__read_unlock(rguard, wguard);
+        }
+    }
+
+    #[inline]
     pub unsafe fn destroy(&self) {}
 }
+
+const EINVAL: i32 = 22;
+
+#[no_mangle]
+pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
+    if p.is_null() {
+        return EINVAL;
+    }
+    (*p).read();
+    return 0;
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
+    if p.is_null() {
+        return EINVAL;
+    }
+    (*p).write();
+    return 0;
+}
+#[no_mangle]
+pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
+    if p.is_null() {
+        return EINVAL;
+    }
+    (*p).unlock();
+    return 0;
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
+    if s < 0 {
+        return;
+    }
+    let buf = slice::from_raw_parts(m as *const u8, s as _);
+    if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) {
+        eprint!("{}", s);
+    }
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn __rust_abort() {
+    ::sys::abort_internal();
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+    use core::array::FixedSizeArray;
+    use mem::MaybeUninit;
+    use {mem, ptr};
+
+    // The below test verifies that the bytes of initialized RWLock are the ones
+    // we use in libunwind.
+    // If they change we need to update src/UnwindRustSgx.h in libunwind.
+    #[test]
+    fn test_c_rwlock_initializer() {
+        const RWLOCK_INIT: &[u8] = &[
+            0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        ];
+
+        let mut init = MaybeUninit::<RWLock>::zeroed();
+        init.set(RWLock::new());
+        assert_eq!(
+            mem::transmute::<_, [u8; 128]>(init.into_inner()).as_slice(),
+            RWLOCK_INIT
+        );
+    }
+}