diff options
| author | bors <bors@rust-lang.org> | 2019-04-05 22:56:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-04-05 22:56:15 +0000 |
| commit | 05b4554e77ef32a97060b1bfffd1f621bf15bb88 (patch) | |
| tree | 245d505fa744308ff7ffd95a061c6c41f536638f /src/libstd | |
| parent | acd8dd6a50d505057a7d7ad8d0d7a4c2bd274200 (diff) | |
| parent | 8455818b319f47bbe3505ff5307e21d9c4acb869 (diff) | |
| download | rust-05b4554e77ef32a97060b1bfffd1f621bf15bb88.tar.gz rust-05b4554e77ef32a97060b1bfffd1f621bf15bb88.zip | |
Auto merge of #59741 - Centril:rollup-3us4b8q, r=Centril
Rollup of 6 pull requests Successful merges: - #58894 (Fix invalid bounds string generation in rustdoc) - #59599 (Updated RELEASES.md for 1.34.0) - #59624 (SGX target: Use linker option to avoid code CGU assignment kludge) - #59696 (Remove invalid assertion back::link::from add_upstream_rust_crates().) - #59707 (Add missing tryfrom example) - #59727 (wasi: Use shared API for preopened fds) Failed merges: r? @ghost
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/sys/sgx/alloc.rs | 16 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/mod.rs | 9 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/rwlock.rs | 42 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/stdio.rs | 18 | ||||
| -rw-r--r-- | src/libstd/sys/wasi/fs.rs | 173 |
5 files changed, 130 insertions, 128 deletions
diff --git a/src/libstd/sys/sgx/alloc.rs b/src/libstd/sys/sgx/alloc.rs index 98eb8397436..b385d567dd8 100644 --- a/src/libstd/sys/sgx/alloc.rs +++ b/src/libstd/sys/sgx/alloc.rs @@ -1,4 +1,4 @@ -use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::alloc::{self, GlobalAlloc, Layout, System}; use super::waitqueue::SpinMutex; @@ -30,3 +30,17 @@ unsafe impl GlobalAlloc for System { DLMALLOC.lock().realloc(ptr, layout.size(), layout.align(), new_size) } } + +// The following functions are needed by libunwind. These symbols are named +// in pre-link args for the target specification, so keep that in sync. +#[cfg(not(test))] +#[no_mangle] +pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 { + alloc::alloc(Layout::from_size_align_unchecked(size, align)) +} + +#[cfg(not(test))] +#[no_mangle] +pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) { + alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) +} diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index b0679f65f0d..a99a534f41e 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -130,6 +130,15 @@ pub unsafe fn abort_internal() -> ! { abi::usercalls::exit(true) } +// This function is needed by the panic runtime. The symbol is named in +// pre-link args for the target specification, so keep that in sync. +#[cfg(not(test))] +#[no_mangle] +// NB. used by both libunwind and libpanic_abort +pub unsafe extern "C" fn __rust_abort() { + abort_internal(); +} + pub fn hashmap_random_keys() -> (u64, u64) { fn rdrand64() -> u64 { unsafe { diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index 09b5ffb1996..30c47e44eef 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -1,10 +1,4 @@ -#[cfg(not(test))] -use crate::alloc::{self, Layout}; use crate::num::NonZeroUsize; -#[cfg(not(test))] -use crate::slice; -#[cfg(not(test))] -use crate::str; use super::waitqueue::{ try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable, @@ -165,10 +159,11 @@ impl RWLock { pub unsafe fn destroy(&self) {} } +// The following functions are needed by libunwind. These symbols are named +// in pre-link args for the target specification, so keep that in sync. #[cfg(not(test))] const EINVAL: i32 = 22; -// used by libunwind port #[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 { @@ -198,39 +193,6 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 { return 0; } -// the following functions are also used by the libunwind port. They're -// included here to make sure parallel codegen and LTO don't mess things up. -#[cfg(not(test))] -#[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); - } -} - -#[cfg(not(test))] -#[no_mangle] -// NB. used by both libunwind and libpanic_abort -pub unsafe extern "C" fn __rust_abort() { - crate::sys::abort_internal(); -} - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 { - alloc::alloc(Layout::from_size_align_unchecked(size, align)) -} - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) { - alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/libstd/sys/sgx/stdio.rs b/src/libstd/sys/sgx/stdio.rs index f2c6892bfb7..a575401f5f6 100644 --- a/src/libstd/sys/sgx/stdio.rs +++ b/src/libstd/sys/sgx/stdio.rs @@ -2,6 +2,10 @@ use fortanix_sgx_abi as abi; use crate::io; use crate::sys::fd::FileDesc; +#[cfg(not(test))] +use crate::slice; +#[cfg(not(test))] +use crate::str; pub struct Stdin(()); pub struct Stdout(()); @@ -62,3 +66,17 @@ pub fn is_ebadf(err: &io::Error) -> bool { pub fn panic_output() -> Option<impl io::Write> { super::abi::panic::SgxPanicOutput::new() } + +// This function is needed by libunwind. The symbol is named in pre-link args +// for the target specification, so keep that in sync. +#[cfg(not(test))] +#[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); + } +} diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs index 7b1c2bd79cc..589593299d6 100644 --- a/src/libstd/sys/wasi/fs.rs +++ b/src/libstd/sys/wasi/fs.rs @@ -1,5 +1,4 @@ -use crate::collections::HashMap; -use crate::ffi::{OsStr, OsString}; +use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; use crate::io::{self, IoVec, IoVecMut, SeekFrom}; use crate::iter; @@ -7,11 +6,10 @@ use crate::mem::{self, ManuallyDrop}; use crate::os::wasi::ffi::{OsStrExt, OsStringExt}; use crate::path::{Path, PathBuf}; use crate::ptr; -use crate::sync::atomic::{AtomicPtr, Ordering::SeqCst}; use crate::sync::Arc; use crate::sys::fd::{DirCookie, WasiFd}; use crate::sys::time::SystemTime; -use crate::sys::{cvt_wasi, unsupported}; +use crate::sys::unsupported; use crate::sys_common::FromInner; pub use crate::sys_common::fs::copy; @@ -230,7 +228,11 @@ impl DirEntry { } pub fn metadata(&self) -> io::Result<FileAttr> { - metadata_at(&self.inner.dir.fd, 0, OsStr::from_bytes(&self.name).as_ref()) + metadata_at( + &self.inner.dir.fd, + 0, + OsStr::from_bytes(&self.name).as_ref(), + ) } pub fn file_type(&self) -> io::Result<FileType> { @@ -377,8 +379,8 @@ impl OpenOptions { impl File { pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> { - let (dir, file) = open_parent(path)?; - open_at(&dir, file, opts) + let (dir, file) = open_parent(path, libc::__WASI_RIGHT_PATH_OPEN)?; + open_at(&dir, &file, opts) } pub fn open_at(&self, path: &Path, opts: &OpenOptions) -> io::Result<File> { @@ -475,7 +477,7 @@ impl DirBuilder { } pub fn mkdir(&self, p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p)?; + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_CREATE_DIRECTORY)?; dir.create_directory(file.as_os_str().as_bytes()) } } @@ -506,13 +508,13 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> { } pub fn unlink(p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p)?; + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_UNLINK_FILE)?; dir.unlink_file(file.as_os_str().as_bytes()) } pub fn rename(old: &Path, new: &Path) -> io::Result<()> { - let (old, old_file) = open_parent(old)?; - let (new, new_file) = open_parent(new)?; + let (old, old_file) = open_parent(old, libc::__WASI_RIGHT_PATH_RENAME_SOURCE)?; + let (new, new_file) = open_parent(new, libc::__WASI_RIGHT_PATH_RENAME_TARGET)?; old.rename( old_file.as_os_str().as_bytes(), &new, @@ -527,13 +529,13 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { } pub fn rmdir(p: &Path) -> io::Result<()> { - let (dir, file) = open_parent(p)?; + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_REMOVE_DIRECTORY)?; dir.remove_directory(file.as_os_str().as_bytes()) } pub fn readlink(p: &Path) -> io::Result<PathBuf> { - let (dir, file) = open_parent(p)?; - read_link(&dir, file) + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_READLINK)?; + read_link(&dir, &file) } fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> { @@ -568,13 +570,13 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> { } pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { - let (dst, dst_file) = open_parent(dst)?; + let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_SYMLINK)?; dst.symlink(src.as_os_str().as_bytes(), dst_file.as_os_str().as_bytes()) } pub fn link(src: &Path, dst: &Path) -> io::Result<()> { - let (src, src_file) = open_parent(src)?; - let (dst, dst_file) = open_parent(dst)?; + let (src, src_file) = open_parent(src, libc::__WASI_RIGHT_PATH_LINK_SOURCE)?; + let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_LINK_TARGET)?; src.link( libc::__WASI_LOOKUP_SYMLINK_FOLLOW, src_file.as_os_str().as_bytes(), @@ -584,13 +586,13 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> { } pub fn stat(p: &Path) -> io::Result<FileAttr> { - let (dir, file) = open_parent(p)?; - metadata_at(&dir, libc::__WASI_LOOKUP_SYMLINK_FOLLOW, file) + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?; + metadata_at(&dir, libc::__WASI_LOOKUP_SYMLINK_FOLLOW, &file) } pub fn lstat(p: &Path) -> io::Result<FileAttr> { - let (dir, file) = open_parent(p)?; - metadata_at(&dir, 0, file) + let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?; + metadata_at(&dir, 0, &file) } fn metadata_at( @@ -621,72 +623,69 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> { Ok(File { fd }) } -// FIXME: we shouldn't implement this. It'd be much better to share this between -// libc (the wasi-sysroot) and Rust as the logic here is likely far more tricky -// than what we're executing below. For now this is a stopgap to enable this -// module, but we should add an official API in upstream wasi-libc which looks -// like this. -// -// In the meantime this is highly unlikely to be correct. It allows some basic -// testing but is not at all robust. -fn open_parent(p: &Path) -> io::Result<(&'static WasiFd, &Path)> { - let map = preopened_map(); - for ancestor in p.ancestors() { - if let Some(fd) = map.get(ancestor) { - let tail = p.strip_prefix(ancestor).unwrap(); - let tail = if tail == Path::new("") { - ".".as_ref() - } else { - tail - }; - return Ok((fd, tail)) - } - } - let msg = format!("failed to find a preopened file descriptor to open {:?}", p); - return Err(io::Error::new(io::ErrorKind::Other, msg)); - - type Preopened = HashMap<PathBuf, ManuallyDrop<WasiFd>>; - fn preopened_map() -> &'static Preopened { - static PTR: AtomicPtr<Preopened> = AtomicPtr::new(ptr::null_mut()); - unsafe { - let ptr = PTR.load(SeqCst); - if !ptr.is_null() { - return &*ptr; - } - - let mut map = Box::new(HashMap::new()); - for fd in 3.. { - let mut buf = mem::zeroed(); - if cvt_wasi(libc::__wasi_fd_prestat_get(fd, &mut buf)).is_err() { - break; - } - if buf.pr_type != libc::__WASI_PREOPENTYPE_DIR { - continue; - } - let len = buf.u.dir.pr_name_len; - let mut v = vec![0u8; len]; - let res = cvt_wasi(libc::__wasi_fd_prestat_dir_name( - fd, - v.as_mut_ptr() as *mut i8, - v.len(), - )); - if res.is_err() { - continue; - } - let path = PathBuf::from(OsString::from_vec(v)); - map.insert(path, ManuallyDrop::new(WasiFd::from_raw(fd))); - } - let ptr = Box::into_raw(map); - match PTR.compare_exchange(ptr::null_mut(), ptr, SeqCst, SeqCst) { - Ok(_) => &*ptr, - - // If we lost the race for initialization clean up the map we - // made and just use the one that's already there - Err(other) => { - drop(Box::from_raw(ptr)); - &*other - } - } +/// Attempts to open a bare path `p`. +/// +/// WASI has no fundamental capability to do this. All syscalls and operations +/// are relative to already-open file descriptors. The C library, however, +/// manages a map of preopened file descriptors to their path, and then the C +/// library provides an API to look at this. In other words, when you want to +/// open a path `p`, you have to find a previously opened file descriptor in a +/// global table and then see if `p` is relative to that file descriptor. +/// +/// This function, if successful, will return two items: +/// +/// * The first is a `ManuallyDrop<WasiFd>`. This represents a preopened file +/// descriptor which we don't have ownership of, but we can use. You shouldn't +/// actually drop the `fd`. +/// +/// * The second is a path that should be a part of `p` and represents a +/// relative traversal from the file descriptor specified to the desired +/// location `p`. +/// +/// If successful you can use the returned file descriptor to perform +/// file-descriptor-relative operations on the path returned as well. The +/// `rights` argument indicates what operations are desired on the returned file +/// descriptor, and if successful the returned file descriptor should have the +/// appropriate rights for performing `rights` actions. +/// +/// Note that this can fail if `p` doesn't look like it can be opened relative +/// to any preopened file descriptor. +fn open_parent( + p: &Path, + rights: libc::__wasi_rights_t, +) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> { + let p = CString::new(p.as_os_str().as_bytes())?; + unsafe { + let mut ret = ptr::null(); + let fd = __wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret); + if fd == -1 { + let msg = format!( + "failed to find a preopened file descriptor \ + through which {:?} could be opened", + p + ); + return Err(io::Error::new(io::ErrorKind::Other, msg)); } + let path = Path::new(OsStr::from_bytes(CStr::from_ptr(ret).to_bytes())); + + // FIXME: right now `path` is a pointer into `p`, the `CString` above. + // When we return `p` is deallocated and we can't use it, so we need to + // currently separately allocate `path`. If this becomes an issue though + // we should probably turn this into a closure-taking interface or take + // `&CString` and then pass off `&Path` tied to the same lifetime. + let path = path.to_path_buf(); + + return Ok((ManuallyDrop::new(WasiFd::from_raw(fd as u32)), path)); + } + + // FIXME(rust-lang/libc#1314) use the `libc` crate for this when the API + // there is published + extern "C" { + pub fn __wasilibc_find_relpath( + path: *const libc::c_char, + rights_base: libc::__wasi_rights_t, + rights_inheriting: libc::__wasi_rights_t, + relative_path: *mut *const libc::c_char, + ) -> libc::c_int; } } |
