diff options
| author | XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com> | 2020-02-26 21:39:30 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-26 21:39:30 +0100 |
| commit | 526280a853f31bbc3120334dfe46e19ea4dbaa25 (patch) | |
| tree | cd35561be4cdcd7591d98bae715726c0e40995b7 /src/libstd | |
| parent | e7a344fb745a0a663e21be947b2619df05df6d31 (diff) | |
| parent | abc3073c92df034636a823c5382ece2186d22b9e (diff) | |
| download | rust-526280a853f31bbc3120334dfe46e19ea4dbaa25.tar.gz rust-526280a853f31bbc3120334dfe46e19ea4dbaa25.zip | |
Merge branch 'master' into relnotes-1.42.0
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/Cargo.toml | 2 | ||||
| -rw-r--r-- | src/libstd/backtrace.rs | 69 | ||||
| -rw-r--r-- | src/libstd/collections/hash/map.rs | 126 | ||||
| -rw-r--r-- | src/libstd/collections/hash/set.rs | 20 | ||||
| -rw-r--r-- | src/libstd/ffi/c_str.rs | 27 | ||||
| -rw-r--r-- | src/libstd/fs.rs | 12 | ||||
| -rw-r--r-- | src/libstd/future.rs | 3 | ||||
| -rw-r--r-- | src/libstd/io/stdio.rs | 2 | ||||
| -rw-r--r-- | src/libstd/keyword_docs.rs | 49 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 6 | ||||
| -rw-r--r-- | src/libstd/sync/once.rs | 11 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/abi/entry.S | 40 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/args.rs | 7 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/rwlock.rs | 24 | ||||
| -rw-r--r-- | src/libstd/sys/unix/thread.rs | 5 | ||||
| -rw-r--r-- | src/libstd/sys/wasi/fd.rs | 12 | ||||
| -rw-r--r-- | src/libstd/sys/wasi/fs.rs | 10 | ||||
| -rw-r--r-- | src/libstd/sys_common/backtrace.rs | 1 |
18 files changed, 284 insertions, 142 deletions
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index c9ff93eac02..b147aa55b2a 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -27,7 +27,7 @@ hashbrown = { version = "0.6.2", default-features = false, features = ['rustc-de [dependencies.backtrace_rs] package = "backtrace" -version = "0.3.37" +version = "0.3.44" default-features = false # without the libstd `backtrace` feature, stub out everything features = [ "rustc-dep-of-std" ] # enable build support for integrating into libstd diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs index 5ba1c940251..a1c9aa75d77 100644 --- a/src/libstd/backtrace.rs +++ b/src/libstd/backtrace.rs @@ -159,6 +159,69 @@ enum BytesOrWide { Wide(Vec<u16>), } +impl fmt::Debug for Backtrace { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut capture = match &self.inner { + Inner::Unsupported => return fmt.write_str("unsupported backtrace"), + Inner::Disabled => return fmt.write_str("disabled backtrace"), + Inner::Captured(c) => c.lock().unwrap(), + }; + capture.resolve(); + + let frames = &capture.frames[capture.actual_start..]; + + write!(fmt, "Backtrace ")?; + + let mut dbg = fmt.debug_list(); + + for frame in frames { + if frame.frame.ip().is_null() { + continue; + } + + dbg.entries(&frame.symbols); + } + + dbg.finish() + } +} + +impl fmt::Debug for BacktraceSymbol { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "{{ ")?; + + if let Some(fn_name) = self.name.as_ref().map(|b| backtrace::SymbolName::new(b)) { + write!(fmt, "fn: \"{:#}\"", fn_name)?; + } else { + write!(fmt, "fn: \"<unknown>\"")?; + } + + if let Some(fname) = self.filename.as_ref() { + write!(fmt, ", file: {:?}", fname)?; + } + + if let Some(line) = self.lineno.as_ref() { + write!(fmt, ", line: {:?}", line)?; + } + + write!(fmt, " }}") + } +} + +impl fmt::Debug for BytesOrWide { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + output_filename( + fmt, + match self { + BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w), + BytesOrWide::Wide(w) => BytesOrWideString::Wide(w), + }, + backtrace::PrintFmt::Short, + crate::env::current_dir().as_ref().ok(), + ) + } +} + impl Backtrace { /// Returns whether backtrace captures are enabled through environment /// variables. @@ -268,12 +331,6 @@ impl Backtrace { impl fmt::Display for Backtrace { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self, fmt) - } -} - -impl fmt::Debug for Backtrace { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let mut capture = match &self.inner { Inner::Unsupported => return fmt.write_str("unsupported backtrace"), Inner::Disabled => return fmt.write_str("disabled backtrace"), diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index fdc587ba5da..d0e1a01b006 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -203,7 +203,7 @@ pub struct HashMap<K, V, S = RandomState> { base: base::HashMap<K, V, S>, } -impl<K: Hash + Eq, V> HashMap<K, V, RandomState> { +impl<K, V> HashMap<K, V, RandomState> { /// Creates an empty `HashMap`. /// /// The hash map is initially created with a capacity of 0, so it will not allocate until it @@ -240,6 +240,59 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomState> { } impl<K, V, S> HashMap<K, V, S> { + /// Creates an empty `HashMap` which will use the given hash builder to hash + /// keys. + /// + /// The created map has the default initial capacity. + /// + /// Warning: `hash_builder` is normally randomly generated, and + /// is designed to allow HashMaps to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut map = HashMap::with_hasher(s); + /// map.insert(1, 2); + /// ``` + #[inline] + #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] + pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> { + HashMap { base: base::HashMap::with_hasher(hash_builder) } + } + + /// Creates an empty `HashMap` with the specified capacity, using `hash_builder` + /// to hash the keys. + /// + /// The hash map will be able to hold at least `capacity` elements without + /// reallocating. If `capacity` is 0, the hash map will not allocate. + /// + /// Warning: `hash_builder` is normally randomly generated, and + /// is designed to allow HashMaps to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashMap; + /// use std::collections::hash_map::RandomState; + /// + /// let s = RandomState::new(); + /// let mut map = HashMap::with_capacity_and_hasher(10, s); + /// map.insert(1, 2); + /// ``` + #[inline] + #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] + pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> { + HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) } + } + /// Returns the number of elements the map can hold without reallocating. /// /// This number is a lower bound; the `HashMap<K, V>` might be able to hold @@ -457,65 +510,6 @@ impl<K, V, S> HashMap<K, V, S> { pub fn clear(&mut self) { self.base.clear(); } -} - -impl<K, V, S> HashMap<K, V, S> -where - K: Eq + Hash, - S: BuildHasher, -{ - /// Creates an empty `HashMap` which will use the given hash builder to hash - /// keys. - /// - /// The created map has the default initial capacity. - /// - /// Warning: `hash_builder` is normally randomly generated, and - /// is designed to allow HashMaps to be resistant to attacks that - /// cause many collisions and very poor performance. Setting it - /// manually using this function can expose a DoS attack vector. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashMap; - /// use std::collections::hash_map::RandomState; - /// - /// let s = RandomState::new(); - /// let mut map = HashMap::with_hasher(s); - /// map.insert(1, 2); - /// ``` - #[inline] - #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> { - HashMap { base: base::HashMap::with_hasher(hash_builder) } - } - - /// Creates an empty `HashMap` with the specified capacity, using `hash_builder` - /// to hash the keys. - /// - /// The hash map will be able to hold at least `capacity` elements without - /// reallocating. If `capacity` is 0, the hash map will not allocate. - /// - /// Warning: `hash_builder` is normally randomly generated, and - /// is designed to allow HashMaps to be resistant to attacks that - /// cause many collisions and very poor performance. Setting it - /// manually using this function can expose a DoS attack vector. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashMap; - /// use std::collections::hash_map::RandomState; - /// - /// let s = RandomState::new(); - /// let mut map = HashMap::with_capacity_and_hasher(10, s); - /// map.insert(1, 2); - /// ``` - #[inline] - #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> { - HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) } - } /// Returns a reference to the map's [`BuildHasher`]. /// @@ -536,7 +530,13 @@ where pub fn hasher(&self) -> &S { self.base.hasher() } +} +impl<K, V, S> HashMap<K, V, S> +where + K: Eq + Hash, + S: BuildHasher, +{ /// Reserves capacity for at least `additional` more elements to be inserted /// in the `HashMap`. The collection may reserve more space to avoid /// frequent reallocations. @@ -984,9 +984,8 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl<K, V, S> Debug for HashMap<K, V, S> where - K: Eq + Hash + Debug, + K: Debug, V: Debug, - S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map().entries(self.iter()).finish() @@ -996,8 +995,7 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl<K, V, S> Default for HashMap<K, V, S> where - K: Eq + Hash, - S: BuildHasher + Default, + S: Default, { /// Creates an empty `HashMap<K, V, S>`, with the `Default` value for the hasher. #[inline] diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index b48700fb944..1ad99f03703 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -110,7 +110,7 @@ pub struct HashSet<T, S = RandomState> { map: HashMap<T, (), S>, } -impl<T: Hash + Eq> HashSet<T, RandomState> { +impl<T> HashSet<T, RandomState> { /// Creates an empty `HashSet`. /// /// The hash set is initially created with a capacity of 0, so it will not allocate until it @@ -261,13 +261,7 @@ impl<T, S> HashSet<T, S> { pub fn clear(&mut self) { self.map.clear() } -} -impl<T, S> HashSet<T, S> -where - T: Eq + Hash, - S: BuildHasher, -{ /// Creates a new empty hash set which will use the given hasher to hash /// keys. /// @@ -340,7 +334,13 @@ where pub fn hasher(&self) -> &S { self.map.hasher() } +} +impl<T, S> HashSet<T, S> +where + T: Eq + Hash, + S: BuildHasher, +{ /// Reserves capacity for at least `additional` more elements to be inserted /// in the `HashSet`. The collection may reserve more space to avoid /// frequent reallocations. @@ -928,8 +928,7 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl<T, S> fmt::Debug for HashSet<T, S> where - T: Eq + Hash + fmt::Debug, - S: BuildHasher, + T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_set().entries(self.iter()).finish() @@ -977,8 +976,7 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl<T, S> Default for HashSet<T, S> where - T: Eq + Hash, - S: BuildHasher + Default, + S: Default, { /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher. #[inline] diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 700e015b08e..04eaba515ff 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -6,6 +6,7 @@ use crate::fmt::{self, Write}; use crate::io; use crate::mem; use crate::memchr; +use crate::num::NonZeroU8; use crate::ops; use crate::os::raw::c_char; use crate::ptr; @@ -741,6 +742,32 @@ impl From<Box<CStr>> for CString { } } +#[stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0")] +impl From<Vec<NonZeroU8>> for CString { + /// Converts a [`Vec`]`<`[`NonZeroU8`]`>` into a [`CString`] without + /// copying nor checking for inner null bytes. + /// + /// [`CString`]: ../ffi/struct.CString.html + /// [`NonZeroU8`]: ../num/struct.NonZeroU8.html + /// [`Vec`]: ../vec/struct.Vec.html + #[inline] + fn from(v: Vec<NonZeroU8>) -> CString { + unsafe { + // Transmute `Vec<NonZeroU8>` to `Vec<u8>`. + let v: Vec<u8> = { + // Safety: + // - transmuting between `NonZeroU8` and `u8` is sound; + // - `alloc::Layout<NonZeroU8> == alloc::Layout<u8>`. + let (ptr, len, cap): (*mut NonZeroU8, _, _) = Vec::into_raw_parts(v); + Vec::from_raw_parts(ptr.cast::<u8>(), len, cap) + }; + // Safety: `v` cannot contain null bytes, given the type-level + // invariant of `NonZeroU8`. + CString::from_vec_unchecked(v) + } + } +} + #[stable(feature = "more_box_slice_clone", since = "1.29.0")] impl Clone for Box<CStr> { #[inline] diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index cff7bbe5ef1..09be3f13050 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -844,10 +844,7 @@ impl OpenOptions { self } - /// Sets the option for creating a new file. - /// - /// This option indicates whether a new file will be created if the file - /// does not yet already exist. + /// Sets the option to create a new file, or open it if it already exists. /// /// In order for the file to be created, [`write`] or [`append`] access must /// be used. @@ -868,11 +865,10 @@ impl OpenOptions { self } - /// Sets the option to always create a new file. + /// Sets the option to create a new file, failing if it already exists. /// - /// This option indicates whether a new file will be created. - /// No file is allowed to exist at the target location, also no (dangling) - /// symlink. + /// No file is allowed to exist at the target location, also no (dangling) symlink. In this + /// way, if the call succeeds, the file returned is guaranteed to be new. /// /// This option is useful because it is atomic. Otherwise between checking /// whether a file exists and creating a new one, the file may have been diff --git a/src/libstd/future.rs b/src/libstd/future.rs index f74c84e6dfd..7b1beb1ecda 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -16,9 +16,10 @@ pub use core::future::*; /// /// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give /// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`). +// This is `const` to avoid extra errors after we recover from `const async fn` #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] -pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> { +pub const fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> { GenFuture(x) } diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 6add644dcc2..d410faca30d 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -302,7 +302,7 @@ impl Stdin { StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } } - /// Locks this handle and reads a line of input into the specified buffer. + /// Locks this handle and reads a line of input, appending it to the specified buffer. /// /// For detailed semantics of this method, see the documentation on /// [`BufRead::read_line`]. diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index 5c7ee9bded9..58f4e76cd30 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -1100,10 +1100,28 @@ mod trait_keyword {} // /// A value of type [`bool`] representing logical **true**. /// -/// The documentation for this keyword is [not yet complete]. Pull requests welcome! +/// Logically `true` is not equal to [`false`]. +/// +/// ## Control structures that check for **true** +/// +/// Several of Rust's control structures will check for a `bool` condition evaluating to **true**. +/// +/// * The condition in an [`if`] expression must be of type `bool`. +/// Whenever that condition evaluates to **true**, the `if` expression takes +/// on the value of the first block. If however, the condition evaluates +/// to `false`, the expression takes on value of the `else` block if there is one. /// +/// * [`while`] is another control flow construct expecting a `bool`-typed condition. +/// As long as the condition evaluates to **true**, the `while` loop will continually +/// evaluate its associated block. +/// +/// * [`match`] arms can have guard clauses on them. +/// +/// [`if`]: keyword.if.html +/// [`while`]: keyword.while.html +/// [`match`]: ../reference/expressions/match-expr.html#match-guards +/// [`false`]: keyword.false.html /// [`bool`]: primitive.bool.html -/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601 mod true_keyword {} #[doc(keyword = "type")] @@ -1186,12 +1204,33 @@ mod await_keyword {} #[doc(keyword = "dyn")] // -/// Name the type of a [trait object]. +/// `dyn` is a prefix of a [trait object]'s type. /// -/// The documentation for this keyword is [not yet complete]. Pull requests welcome! +/// The `dyn` keyword is used to highlight that calls to methods on the associated `Trait` +/// are dynamically dispatched. To use the trait this way, it must be 'object safe'. +/// +/// Unlike generic parameters or `impl Trait`, the compiler does not know the concrete type that +/// is being passed. That is, the type has been [erased]. +/// As such, a `dyn Trait` reference contains _two_ pointers. +/// One pointer goes to the data (e.g., an instance of a struct). +/// Another pointer goes to a map of method call names to function pointers +/// (known as a virtual method table or vtable). +/// +/// At run-time, when a method needs to be called on the `dyn Trait`, the vtable is consulted to get +/// the function pointer and then that function pointer is called. +/// +/// ## Trade-offs +/// +/// The above indirection is the additional runtime cost of calling a function on a `dyn Trait`. +/// Methods called by dynamic dispatch generally cannot be inlined by the compiler. +/// +/// However, `dyn Trait` is likely to produce smaller code than `impl Trait` / generic parameters as +/// the method won't be duplicated for each concrete type. +/// +/// Read more about `object safety` and [trait object]s. /// /// [trait object]: ../book/ch17-02-trait-objects.html -/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601 +/// [erased]: https://en.wikipedia.org/wiki/Type_erasure mod dyn_keyword {} #[doc(keyword = "union")] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index f9c9f224730..7b3c702b929 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -233,12 +233,12 @@ #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] -#![feature(atomic_mut_ptr)] #![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(asm)] #![feature(assoc_int_consts)] #![feature(associated_type_bounds)] +#![feature(atomic_mut_ptr)] #![feature(box_syntax)] #![feature(c_variadic)] #![feature(cfg_target_has_atomic)] @@ -309,6 +309,7 @@ #![feature(unboxed_closures)] #![feature(untagged_unions)] #![feature(unwind_attributes)] +#![feature(vec_into_raw_parts)] // NB: the above list is sorted to minimize merge conflicts. #![default_lib_allocator] @@ -550,6 +551,9 @@ pub use core::{ trace_macros, }; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use core::primitive; + // Include a number of private modules that exist solely to provide // the rustdoc documentation for primitive types. Using `include!` // because rustdoc only looks for these modules at the crate level. diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 61c4d0c2dbf..b99b4d8d9fd 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -331,14 +331,14 @@ impl Once { /// * `call_once` was called, but has not yet completed, /// * the `Once` instance is poisoned /// - /// It is also possible that immediately after `is_completed` - /// returns false, some other thread finishes executing - /// `call_once`. + /// This function returning `false` does not mean that `Once` has not been + /// executed. For example, it may have been executed in the time between + /// when `is_completed` starts executing and when it returns, in which case + /// the `false` return value would be stale (but still permissible). /// /// # Examples /// /// ``` - /// #![feature(once_is_completed)] /// use std::sync::Once; /// /// static INIT: Once = Once::new(); @@ -351,7 +351,6 @@ impl Once { /// ``` /// /// ``` - /// #![feature(once_is_completed)] /// use std::sync::Once; /// use std::thread; /// @@ -364,7 +363,7 @@ impl Once { /// assert!(handle.join().is_err()); /// assert_eq!(INIT.is_completed(), false); /// ``` - #[unstable(feature = "once_is_completed", issue = "54890")] + #[stable(feature = "once_is_completed", since = "1.44.0")] #[inline] pub fn is_completed(&self) -> bool { // An `Acquire` load is enough because that makes all the initialization diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index a3e059e8131..1f06c9da3a9 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -30,6 +30,14 @@ IMAGE_BASE: /* We can store a bunch of data in the gap between MXCSR and the XSAVE header */ +/* MXCSR initialization value for ABI */ +.Lmxcsr_init: + .int 0x1f80 + +/* x87 FPU control word initialization value for ABI */ +.Lfpucw_init: + .int 0x037f + /* The following symbols point at read-only data that will be filled in by the */ /* post-linker. */ @@ -134,6 +142,20 @@ elf_entry: ud2 /* should not be reached */ /* end elf_entry */ +/* This code needs to be called *after* the enclave stack has been setup. */ +/* There are 3 places where this needs to happen, so this is put in a macro. */ +.macro entry_sanitize_final +/* Sanitize rflags received from user */ +/* - DF flag: x86-64 ABI requires DF to be unset at function entry/exit */ +/* - AC flag: AEX on misaligned memory accesses leaks side channel info */ + pushfq + andq $~0x40400, (%rsp) + popfq +/* check for abort */ + bt $0,.Laborted(%rip) + jc .Lreentry_panic +.endm + .text .global sgx_entry .type sgx_entry,function @@ -150,25 +172,18 @@ sgx_entry: stmxcsr %gs:tcsls_user_mxcsr fnstcw %gs:tcsls_user_fcw -/* reset user state */ -/* - DF flag: x86-64 ABI requires DF to be unset at function entry/exit */ -/* - AC flag: AEX on misaligned memory accesses leaks side channel info */ - pushfq - andq $~0x40400, (%rsp) - popfq - /* check for debug buffer pointer */ testb $0xff,DEBUG(%rip) jz .Lskip_debug_init mov %r10,%gs:tcsls_debug_panic_buf_ptr .Lskip_debug_init: -/* check for abort */ - bt $0,.Laborted(%rip) - jc .Lreentry_panic /* check if returning from usercall */ mov %gs:tcsls_last_rsp,%r11 test %r11,%r11 jnz .Lusercall_ret +/* reset user state */ + ldmxcsr .Lmxcsr_init(%rip) + fldcw .Lfpucw_init(%rip) /* setup stack */ mov %gs:tcsls_tos,%rsp /* initially, RSP is not set to the correct value */ /* here. This is fixed below under "adjust stack". */ @@ -179,6 +194,7 @@ sgx_entry: lea IMAGE_BASE(%rip),%rax add %rax,%rsp mov %rsp,%gs:tcsls_tos + entry_sanitize_final /* call tcs_init */ /* store caller-saved registers in callee-saved registers */ mov %rdi,%rbx @@ -194,7 +210,10 @@ sgx_entry: mov %r13,%rdx mov %r14,%r8 mov %r15,%r9 + jmp .Lafter_init .Lskip_init: + entry_sanitize_final +.Lafter_init: /* call into main entry point */ load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */ call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */ @@ -295,6 +314,7 @@ usercall: ldmxcsr (%rsp) fldcw 4(%rsp) add $8, %rsp + entry_sanitize_final pop %rbx pop %rbp pop %r12 diff --git a/src/libstd/sys/sgx/args.rs b/src/libstd/sys/sgx/args.rs index b47a48e752c..5a53695a846 100644 --- a/src/libstd/sys/sgx/args.rs +++ b/src/libstd/sys/sgx/args.rs @@ -22,12 +22,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) { } } -pub unsafe fn cleanup() { - let args = ARGS.swap(0, Ordering::Relaxed); - if args != 0 { - drop(Box::<ArgsStore>::from_raw(args as _)) - } -} +pub unsafe fn cleanup() {} pub fn args() -> Args { let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() }; diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index fda2bb504d4..722b4f5e0ba 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -10,10 +10,10 @@ pub struct RWLock { writer: SpinMutex<WaitVariable<bool>>, } -// Below is to check at compile time, that RWLock has size of 128 bytes. +// Check at compile time that RWLock size matches C definition (see test_c_rwlock_initializer below) #[allow(dead_code)] unsafe fn rw_lock_size_assert(r: RWLock) { - mem::transmute::<RWLock, [u8; 128]>(r); + mem::transmute::<RWLock, [u8; 144]>(r); } impl RWLock { @@ -210,15 +210,17 @@ mod tests { // be changed too. #[test] fn test_c_rwlock_initializer() { + #[rustfmt::skip] 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, + /* 0x00 */ 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x10 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x20 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x30 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x40 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x50 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x60 */ 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x70 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + /* 0x80 */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ]; #[inline(never)] @@ -239,7 +241,7 @@ mod tests { zero_stack(); let mut init = MaybeUninit::<RWLock>::zeroed(); rwlock_new(&mut init); - assert_eq!(mem::transmute::<_, [u8; 128]>(init.assume_init()).as_slice(), RWLOCK_INIT) + assert_eq!(mem::transmute::<_, [u8; 144]>(init.assume_init()).as_slice(), RWLOCK_INIT) }; } } diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 3ca778354e4..674d4c71138 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -255,8 +255,9 @@ pub mod guard { #[cfg(target_os = "macos")] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { - let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize - - libc::pthread_get_stacksize_np(libc::pthread_self()); + let th = libc::pthread_self(); + let stackaddr = + libc::pthread_get_stackaddr_np(th) as usize - libc::pthread_get_stacksize_np(th); Some(stackaddr as *mut libc::c_void) } diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs index 00327c1743c..8458ded5db0 100644 --- a/src/libstd/sys/wasi/fd.rs +++ b/src/libstd/sys/wasi/fd.rs @@ -13,19 +13,15 @@ pub struct WasiFd { fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] { assert_eq!(mem::size_of::<IoSliceMut<'_>>(), mem::size_of::<wasi::Iovec>()); assert_eq!(mem::align_of::<IoSliceMut<'_>>(), mem::align_of::<wasi::Iovec>()); - /// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout - unsafe { - mem::transmute(a) - } + // SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout + unsafe { mem::transmute(a) } } fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] { assert_eq!(mem::size_of::<IoSlice<'_>>(), mem::size_of::<wasi::Ciovec>()); assert_eq!(mem::align_of::<IoSlice<'_>>(), mem::align_of::<wasi::Ciovec>()); - /// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout - unsafe { - mem::transmute(a) - } + // SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout + unsafe { mem::transmute(a) } } impl WasiFd { diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs index 04bfdf67e12..a11f61fdd69 100644 --- a/src/libstd/sys/wasi/fs.rs +++ b/src/libstd/sys/wasi/fs.rs @@ -12,7 +12,6 @@ use crate::sys::time::SystemTime; use crate::sys::unsupported; use crate::sys_common::FromInner; -pub use crate::sys_common::fs::copy; pub use crate::sys_common::fs::remove_dir_all; pub struct File { @@ -647,3 +646,12 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> { pub fn osstr2str(f: &OsStr) -> io::Result<&str> { f.to_str().ok_or_else(|| io::Error::new(io::ErrorKind::Other, "input must be utf-8")) } + +pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { + use crate::fs::File; + + let mut reader = File::open(from)?; + let mut writer = File::create(to)?; + + io::copy(&mut reader, &mut writer) +} diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs index 191add2c31b..289ee07babf 100644 --- a/src/libstd/sys_common/backtrace.rs +++ b/src/libstd/sys_common/backtrace.rs @@ -70,6 +70,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: let mut print_path = move |fmt: &mut fmt::Formatter<'_>, bows: BytesOrWideString<'_>| { output_filename(fmt, bows, print_fmt, cwd.as_ref()) }; + write!(fmt, "stack backtrace:\n")?; let mut bt_fmt = BacktraceFmt::new(fmt, print_fmt, &mut print_path); bt_fmt.add_context()?; let mut idx = 0; |
