mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Adding unwinding support for x86_64_fortanix_unknown_sgx target.
This commit is contained in:
parent
041254b814
commit
885cf2a2af
@ -62,7 +62,7 @@ cfg_if! {
|
||||
if #[cfg(target_os = "emscripten")] {
|
||||
#[path = "emcc.rs"]
|
||||
mod imp;
|
||||
} else if #[cfg(any(target_arch = "wasm32", target_env = "sgx"))] {
|
||||
} else if #[cfg(target_arch = "wasm32")] {
|
||||
#[path = "dummy.rs"]
|
||||
mod imp;
|
||||
} else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] {
|
||||
|
@ -10,28 +10,29 @@
|
||||
|
||||
use std::iter;
|
||||
|
||||
use super::{LinkerFlavor, Target, TargetOptions, PanicStrategy};
|
||||
use super::{LinkerFlavor, PanicStrategy, Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Result<Target, String> {
|
||||
const PRE_LINK_ARGS: &[&str] = &[
|
||||
"-Wl,--as-needed",
|
||||
"-Wl,-z,noexecstack",
|
||||
"-m64",
|
||||
"-fuse-ld=gold",
|
||||
"-nostdlib",
|
||||
"-shared",
|
||||
"-Wl,-e,sgx_entry",
|
||||
"-Wl,-Bstatic",
|
||||
"-Wl,--gc-sections",
|
||||
"-Wl,-z,text",
|
||||
"-Wl,-z,norelro",
|
||||
"-Wl,--rosegment",
|
||||
"-Wl,--no-undefined",
|
||||
"-Wl,--error-unresolved-symbols",
|
||||
"-Wl,--no-undefined-version",
|
||||
"-Wl,-Bsymbolic",
|
||||
"-Wl,--export-dynamic",
|
||||
"-fuse-ld=gold",
|
||||
"-nostdlib",
|
||||
"-shared",
|
||||
"-Wl,-e,sgx_entry",
|
||||
"-Wl,-Bstatic",
|
||||
"-Wl,--gc-sections",
|
||||
"-Wl,-z,text",
|
||||
"-Wl,-z,norelro",
|
||||
"-Wl,--rosegment",
|
||||
"-Wl,--no-undefined",
|
||||
"-Wl,--error-unresolved-symbols",
|
||||
"-Wl,--no-undefined-version",
|
||||
"-Wl,-Bsymbolic",
|
||||
"-Wl,--export-dynamic",
|
||||
];
|
||||
|
||||
const EXPORT_SYMBOLS: &[&str] = &[
|
||||
"sgx_entry",
|
||||
"HEAP_BASE",
|
||||
@ -41,19 +42,26 @@ pub fn target() -> Result<Target, String> {
|
||||
"ENCLAVE_SIZE",
|
||||
"CFGDATA_BASE",
|
||||
"DEBUG",
|
||||
"EH_FRM_HDR_BASE",
|
||||
"EH_FRM_HDR_SIZE",
|
||||
"TEXT_BASE",
|
||||
"TEXT_SIZE",
|
||||
];
|
||||
let opts = TargetOptions {
|
||||
dynamic_linking: false,
|
||||
executables: true,
|
||||
linker_is_gnu: true,
|
||||
max_atomic_width: Some(64),
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
panic_strategy: PanicStrategy::Unwind,
|
||||
cpu: "x86-64".into(),
|
||||
features: "+rdrnd,+rdseed".into(),
|
||||
position_independent_executables: true,
|
||||
pre_link_args: iter::once(
|
||||
(LinkerFlavor::Gcc, PRE_LINK_ARGS.iter().cloned().map(String::from).collect())
|
||||
).collect(),
|
||||
pre_link_args: iter::once((
|
||||
LinkerFlavor::Gcc,
|
||||
PRE_LINK_ARGS.iter().cloned().map(String::from).collect(),
|
||||
))
|
||||
.collect(),
|
||||
post_link_objects: vec!["libunwind.a".into()],
|
||||
override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(String::from).collect()),
|
||||
..Default::default()
|
||||
};
|
||||
|
@ -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!"
|
||||
|
@ -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;
|
||||
@ -128,6 +150,109 @@ 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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -26,10 +26,7 @@ mod macros;
|
||||
cfg_if! {
|
||||
if #[cfg(target_env = "msvc")] {
|
||||
// no extra unwinder support needed
|
||||
} else if #[cfg(any(
|
||||
all(target_arch = "wasm32", not(target_os = "emscripten")),
|
||||
target_env = "sgx"
|
||||
))] {
|
||||
} else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
|
||||
// no unwinder on the system!
|
||||
} else {
|
||||
extern crate libc;
|
||||
|
Loading…
Reference in New Issue
Block a user