// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Utilities for safely operating on memory shared between untrusting
//! processes.
//!
//! `shared-buffer` provides support for safely operating on memory buffers
//! which are shared with another process which is untrusted. The Rust memory
//! model assumes that only code running in the current process - and thus
//! either trusted or generated by Rust itself - operates on a given region of
//! memory. As a result, simply treating a region of memory to which another,
//! untrusted process has read or write access as equivalent to normal process
//! memory is unsafe. This crate provides the `SharedBuffer` type, which has
//! methods that allow safe access to such memory.
//!
//! Examples of issues that could arise if shared memory were treated as normal
//! memory include:
//! - Unintentionally leaking sensitive values to another process
//! - Allowing other processes to cause an invalid sequence of memory to be
//!   interpreted as a given type

// NOTES(joshlf) on implementation: We need to worry about the following issues:
// - If another process has write access to a given region of memory, then
//   arbitrary writes may happen at any time. Thus, it is never safe to access
//   this memory through any Rust type other than a raw pointer, or else the
//   compiler might allow operations or make optimizations based on the
//   assumption that the memory is either owned (in the case of a mutable
//   reference) or immutable (in the case of an immutable reference). In either
//   of these cases, any such allowance or optimization would be unsound. For
//   example, the compiler might decide that, after having written a T to a
//   particular memory location, it is safe to read that memory location and
//   treat it as a T. This would cause undefined behavior if the other process
//   modified that memory location in the meantime. Perhaps more fundamentally,
//   both mutable and immutable references guarantee that nobody else is
//   modifying this memory other than me (and not even me, in the case of an
//   immutable reference). On this basis alone, it is clear that neither
//   reference is compatible with foreign write access to the referent.
// - If another process has read access to a given region of memory, then it
//   cannot affect the correctness of a Rust program. However, it can do things
//   that do not technically violate correctness, but are still undesirable. The
//   canonical example is reading memory which contains sensitive information.
//   Even if the programmer were to construct a mutable reference to such memory
//   and write a value to it which the programmer intended to be shared with the
//   other process, the compiler might use the fact that it had exclusive access
//   to the memory (so says the mutable reference...) to store any arbitrary
//   value in the memory temporarily. So long as it's not observable from the
//   Rust program, it preserves the semantics of the program. Of course, it *is*
//   observable from the other process, and there are no guarantees on what the
//   compiler might decide to store there, including any value currently in your
//   memory space, including particularly sensitive values. As a result, while
//   read-only access doesn't violate the correctness of a Rust program, it's
//   still worth handling carefully.
//
// In order to address both of these issues, our approach is simple: never treat
// the memory as anything other than a raw pointer. Do not construct any
// references, mutable or immutable, even temporarily, and even if they are
// never used. This basically boils down to only accessing the memory using the
// various functions from core::ptr which operate directly on raw pointers.

// NOTE(joshlf):
// - Since you must assume that the other process might be writing to the
//   memory, there's no technical requirement to have exclusive access. E.g., we
//   could safely implement Clone, have write and write_at take immutable
//   references, etc. (see here for a discussion of the soundness of using
//   copy_nonoverlapping simultaneously in multiple threads:
//   https://users.rust-lang.org/t/copy-nonoverlapping-concurrently/18353).
//   However, this would be confusing because it would depart from the Rust
//   idiom. Instead, we provide SharedBuffer, which has ownership semantics
//   analogous to Vec, and SharedBufferSlice and SharedBufferSliceMut, which
//   have reference semantics analogous to immutable and mutable slice
//   references. Similarly, write, write_at, and release_writes take mutable
//   references.
//   Clone and provide slicing methods. There's no point not to.
// - Since all access to these buffers must go through the methods of
//   SharedBuffer, correct code may not construct a reference to this memory.
//   Thus, the references to dst and src passed to read, read_at, write, and
//   write_at cannot overlap with the buffer itself, and so it's safe to use
//   ptr::copy_nonoverlapping.
// - Note on volatility and observability: The memory in a SharedBuffer is
//   either allocated by this process and then sent to another process, or
//   allocated by another process and sent to this process. However, on Fuchsia,
//   what's actually shared is a VMO, which is then mapped into the address
//   space. While LLVM is almost certainly guaranteed to treat this call as
//   opaque, and thus to be unable to prove to itself that the returned memory
//   is not shared, it is worth hedging against that reasoning being wrong. If
//   LLVM were, for some reason, to decide that mapping a VMO resulted in
//   uniquely owned memory, it would be able to reason that writes to that
//   memory could never be observed by other threads, and so if the writes were
//   not observed by the _current_ thread, they could be elided altogether since
//   they could have no effect. In order to hedge against this possibility, and
//   to ensure that LLVM definitely cannot take this line of reasoning, we
//   volatile write the pointer when we first construct the SharedBuffer. LLVM
//   must conclude that it doesn't know who else is using the memory once a
//   pointer to it has been written in a volatile manner, and so must assume
//   that all future writes must be observable. This single volatile write which
//   happens at most once per message (although more likely once when the
//   connection is first established) has minimal performance overhead.

// TODO(joshlf):
// - Create a variant for read-only memory
// - Create a variant for write-only memory?

#![no_std]

use core::marker::PhantomData;
use core::ops::{Bound, Range, RangeBounds};
use core::ptr;
use core::sync::atomic::{fence, Ordering};

// A buffer with no ownership or reference semantics. It is the caller's
// responsibility to wrap this type in a type which provides ownership or
// reference semantics, and to only call methods when apporpriate.
#[derive(Debug)]
struct SharedBufferInner {
    // invariant: '(buf as usize) + len' doesn't overflow usize
    buf: *mut u8,
    len: usize,
}

impl SharedBufferInner {
    fn read_at(&self, offset: usize, dst: &mut [u8]) -> usize {
        if let Some(to_copy) = overlap(offset, dst.len(), self.len) {
            // Since overlap returned Some, we're guaranteed that 'offset +
            // to_copy <= self.len'. That in turn means that, so long as the
            // invariant holds that '(self.buf as usize) + self.len' doesn't
            // overflow usize, then this call to offset_from won't overflow, and
            // neither will the call to copy_nonoverlapping.
            let base = offset_from(self.buf, offset);
            unsafe { ptr::copy_nonoverlapping(base, dst.as_mut_ptr(), to_copy) };
            to_copy
        } else {
            panic!("byte offset {} out of range for SharedBuffer of length {}", offset, self.len);
        }
    }

    fn write_at(&self, offset: usize, src: &[u8]) -> usize {
        if let Some(to_copy) = overlap(offset, src.len(), self.len) {
            // Since overlap returned Some, we're guaranteed that 'offset +
            // to_copy <= self.len'. That in turn means that, so long as the
            // invariant holds that '(self.buf as usize) + self.len' doesn't
            // overflow usize, then this call to offset_from won't overflow, and
            // neither will the call to copy_nonoverlapping.
            let base = offset_from(self.buf, offset);
            unsafe { ptr::copy_nonoverlapping(src.as_ptr(), base, to_copy) };
            to_copy
        } else {
            panic!("byte offset {} out of range for SharedBuffer of length {}", offset, self.len);
        }
    }

    fn slice<R: RangeBounds<usize>>(&self, range: R) -> SharedBufferInner {
        let range = canonicalize_range_infallible(self.len, range);
        SharedBufferInner { buf: offset_from(self.buf, range.start), len: range.end - range.start }
    }

    fn split_at(&self, idx: usize) -> (SharedBufferInner, SharedBufferInner) {
        assert!(idx <= self.len, "split index out of bounds");
        let a = SharedBufferInner { buf: self.buf, len: idx };
        let b = SharedBufferInner { buf: offset_from(self.buf, idx), len: self.len - idx };
        (a, b)
    }
}

// Verifies that 'offset' is in range of range_len (that 'offset <= range_len'),
// and returns the amount of overlap between a copy of length 'copy_len'
// starting at 'offset' and a buffer of length 'range_len'. The number it
// returns is guaranteed to be less than or equal to 'range_len'.
//
// overlap is guaranteed to be correct for any three usize values.
fn overlap(offset: usize, copy_len: usize, range_len: usize) -> Option<usize> {
    if offset > range_len {
        None
    } else if offset.checked_add(copy_len).map(|sum| sum <= range_len).unwrap_or(false) {
        // if 'offset + copy_len' overflows usize, then 'offset + copy_len >
        // range_len', so we unwrap_or(false)
        Some(copy_len)
    } else {
        Some(range_len - offset)
    }
}

// Like the offset method on primitive pointers, but for unsigned offsets. Both
// the 'offset' and 'add' methods on primitive pointers have the limitation that
// the offset cannot overflow an isize or else it will cause UB. offset_from
// function has no such restriction.
//
// The caller must guarantee that '(ptr as usize) + offset' doesn't overflow
// usize.
fn offset_from(ptr: *mut u8, offset: usize) -> *mut u8 {
    // just in case our logic is wrong, better to catch it at runtime than
    // invoke UB
    (ptr as usize).checked_add(offset).unwrap() as *mut u8
}

// Return the inclusive equivalent of the bound.
fn canonicalize_lower_bound(bound: Bound<&usize>) -> usize {
    match bound {
        Bound::Included(x) => *x,
        Bound::Excluded(x) => *x + 1,
        Bound::Unbounded => 0,
    }
}
// Return the exclusive equivalent of the bound, verifying that it is in range
// of len.
fn canonicalize_upper_bound(len: usize, bound: Bound<&usize>) -> Option<usize> {
    let bound = match bound {
        Bound::Included(x) => *x + 1,
        Bound::Excluded(x) => *x,
        Bound::Unbounded => len,
    };
    if bound > len {
        return None;
    }
    Some(bound)
}
// Return the inclusive-exclusive equivalent of the bound, verifying that it is
// in range of len, and panicking if it is not or if the range is nonsensical.
fn canonicalize_range_infallible<R: RangeBounds<usize>>(len: usize, range: R) -> Range<usize> {
    let lower = canonicalize_lower_bound(range.start_bound());
    let upper =
        canonicalize_upper_bound(len, range.end_bound()).expect("slice range out of bounds");
    assert!(lower <= upper, "invalid range");
    lower..upper
}

/// A shared region of memory.
///
/// A `SharedBuffer` is a view into a region of memory to which another process
/// has access. It provides methods to access this memory in a way that
/// preserves memory safety. From the perspective of the current process, it
/// owns its memory (analogous to a `Vec`).
///
/// Since the buffer is shared by an untrusted process, it is never valid to
/// assume that a given region of the buffer will not change in between method
/// calls. Even if no thread in this process wrote anything to the buffer, the
/// other process might have.
///
/// # Unmapping
///
/// `SharedBuffer`s do nothing when dropped. In order to avoid leaking memory,
/// use the `consume` method to consume the `SharedBuffer` and get back the
/// underlying pointer and length, and unmap the memory manually.
#[derive(Debug)]
pub struct SharedBuffer {
    inner: SharedBufferInner,
}

impl SharedBuffer {
    /// Create a new `SharedBuffer` from a raw buffer.
    ///
    /// `new` creates a new `SharedBuffer` from the provided buffer and lenth,
    /// taking ownership of the memory.
    ///
    /// # Safety
    ///
    /// Memory in a shared buffer must never be accessed except through the
    /// methods of `SharedBuffer`. It must not be treated as normal memory, and
    /// pointers to it must not be passed to unsafe code which is designed to
    /// operate on normal memory. It must be guaranteed that, for the lifetime
    /// of the `SharedBuffer`, the memory region is mapped, readable, and
    /// writable.
    ///
    /// If any of these guarantees are violated, it may cause undefined
    /// behavior.
    #[inline]
    pub unsafe fn new(buf: *mut u8, len: usize) -> SharedBuffer {
        // Write the pointer and the length using a volatile write so that LLVM
        // must assume that the memory has escaped, and that all future writes
        // to it are observable. See the NOTE above for more details.
        let mut scratch = (ptr::null_mut(), 0);
        ptr::write_volatile(&mut scratch, (buf, len));

        // Acquire any writes to the buffer that happened in a different thread
        // or process already so they are visible without having to call the
        // acquire_writes method.
        fence(Ordering::Acquire);
        SharedBuffer { inner: SharedBufferInner { buf, len } }
    }

    /// Read bytes from the buffer.
    ///
    /// Read up to `dst.len()` bytes from the buffer, returning how many bytes
    /// were read. The only thing that can cause fewer bytes to be read than
    /// requested is if `dst` is larger than the buffer itself.
    ///
    /// A call to `read` is only guaranteed to happen after an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `acquire_writes` method must be called before `read` and after receiving
    /// a signal from the other process in order to provide such ordering
    /// guarantees. In practice, this means that `acquire_writes` should be the
    /// first read operation that happens after receiving a signal from another
    /// process that the memory may be read. See the `acquire_writes`
    /// documentation for more details.
    #[inline]
    pub fn read(&self, dst: &mut [u8]) -> usize {
        self.inner.read_at(0, dst)
    }

    /// Read bytes from the buffer at an offset.
    ///
    /// Read up to `dst.len()` bytes starting at `offset` into the buffer,
    /// returning how many bytes were read. The only thing that can cause fewer
    /// bytes to be read than requested is if there are fewer than `dst.len()`
    /// bytes available starting at `offset` within the buffer.
    ///
    /// A call to `read_at` is only guaranteed to happen after an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `acquire_writes` method must be called before `read_at` and after
    /// receiving a signal from the other process in order to provide such
    /// ordering guarantees. In practice, this means that `acquire_writes`
    /// should be the first read operation that happens after receiving a signal
    /// from another process that the memory may be read. See the
    /// `acquire_writes` documentation for more details.
    ///
    /// # Panics
    ///
    /// `read_at` panics if `offset` is greater than the length of the buffer.
    #[inline]
    pub fn read_at(&self, offset: usize, dst: &mut [u8]) -> usize {
        self.inner.read_at(offset, dst)
    }

    /// Write bytes to the buffer.
    ///
    /// Write up to `src.len()` bytes into the buffer, returning how many bytes
    /// were written. The only thing that can cause fewer bytes to be written
    /// than requested is if `src` is larger than the buffer itself.
    ///
    /// A call to `write` is only guaranteed to happen before an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `release_writes` method must be called after `write` and before
    /// signalling the other process in order to provide such ordering
    /// guarantees. In practice, this means that `release_writes` should be the
    /// last write operation that happens before signalling another process that
    /// the memory may be read. See the `release_writes` documentation for more
    /// details.
    #[inline]
    pub fn write(&self, src: &[u8]) -> usize {
        self.inner.write_at(0, src)
    }

    /// Write bytes to the buffer at an offset.
    ///
    /// Write up to `src.len()` bytes starting at `offset` into the buffer,
    /// returning how many bytes were written. The only thing that can cause
    /// fewer bytes to be written than requested is if there are fewer than
    /// `src.len()` bytes available starting at `offset` within the buffer.
    ///
    /// A call to `write_at` is only guaranteed to happen before an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `release_writes` method must be called after `write_at` and before
    /// signalling the other process in order to provide such ordering
    /// guarantees. In practice, this means that `release_writes` should be the
    /// last write operation that happens before signalling another process that
    /// the memory may be read. See the `release_writes` documentation for more
    /// details.
    ///
    /// # Panics
    ///
    /// `write_at` panics if `offset` is greater than the length of the buffer.
    #[inline]
    pub fn write_at(&self, offset: usize, src: &[u8]) -> usize {
        self.inner.write_at(offset, src)
    }

    /// Acquire all writes performed by the other process.
    ///
    /// On some systems (such as Fuchsia, currently), the communication
    /// mechanism used for signalling a process that memory is readable does not
    /// have well-defined synchronization semantics. On those systems, this
    /// method MUST be called after receiving such a signal, or else writes
    /// performed before that signal are not guaranteed to be observed by this
    /// process.
    ///
    /// `acquire_writes` acquires any writes performed on this buffer or any
    /// slice within the buffer.
    ///
    /// # Note on Fuchsia
    ///
    /// Zircon, the Fuchsia kernel, will likely eventually have well-defined
    /// semantics around the synchronization behavior of various syscalls. Once
    /// that happens, calling this method in Fuchsia programs may become
    /// optional. This work is tracked in [fxbug.dev/32098].
    ///
    /// [fxbug.dev/32098]: #
    // TODO(joshlf): Replace with link once issues are public.
    #[inline]
    pub fn acquire_writes(&self) {
        fence(Ordering::Acquire);
    }

    /// Release all writes performed so far.
    ///
    /// On some systems (such as Fuchsia, currently), the communication
    /// mechanism used for signalling the other process that memory is readable
    /// does not have well-defined synchronization semantics. On those systems,
    /// this method MUST be called before such signalling, or else writes
    /// performed before that signal are not guaranteed to be observed by the
    /// other process.
    ///
    /// `release_writes` releases any writes performed on this buffer or any
    /// slice within the buffer.
    ///
    /// # Note on Fuchsia
    ///
    /// Zircon, the Fuchsia kernel, will likely eventually have well-defined
    /// semantics around the synchronization behavior of various syscalls. Once
    /// that happens, calling this method in Fuchsia programs may become
    /// optional. This work is tracked in [fxbug.dev/32098].
    ///
    /// [fxbug.dev/32098]: #
    // TODO(joshlf): Replace with link once issues are public.
    #[inline]
    pub fn release_writes(&mut self) {
        fence(Ordering::Release);
    }

    /// The number of bytes in this `SharedBuffer`.
    #[inline]
    pub fn len(&self) -> usize {
        self.inner.len
    }

    /// Create a slice of the original `SharedBuffer`.
    ///
    /// Just like the slicing operation on array and slice references, `slice`
    /// constructs a `SharedBufferSlice` which points to the same memory as the
    /// original `SharedBuffer`, but starting and index `from` (inclusive) and
    /// ending at index `to` (exclusive).
    ///
    /// # Panics
    ///
    /// `slice` panics if `range` is out of bounds of `self` or if `range` is
    /// nonsensical (its lower bound is larger than its upper bound).
    #[inline]
    pub fn slice<'a, R: RangeBounds<usize>>(&'a self, range: R) -> SharedBufferSlice<'a> {
        SharedBufferSlice { inner: self.inner.slice(range), _marker: PhantomData }
    }

    /// Create a mutable slice of the original `SharedBuffer`.
    ///
    /// Just like the mutable slicing operation on array and slice references,
    /// `slice_mut` constructs a `SharedBufferSliceMut` which points to the same
    /// memory as the original `SharedBuffer`, but starting and index `from`
    /// (inclusive) and ending at index `to` (exclusive).
    ///
    /// # Panics
    ///
    /// `slice_mut` panics if `range` is out of bounds of `self` or if `range`
    /// is nonsensical (its lower bound is larger than its upper bound).
    #[inline]
    pub fn slice_mut<'a, R: RangeBounds<usize>>(
        &'a mut self,
        range: R,
    ) -> SharedBufferSliceMut<'a> {
        SharedBufferSliceMut { inner: self.inner.slice(range), _marker: PhantomData }
    }

    /// Create two non-overlapping slices of the original `SharedBuffer`.
    ///
    /// Just like the `split_at` method on array and slice references,
    /// `split_at` constructs one `SharedBufferSlice` which represents bytes
    /// `[0, idx)`, and one which represents bytes `[idx, len)`, where `len` is
    /// the length of the buffer.
    ///
    /// # Panics
    ///
    /// `split_at` panics if `idx > self.len()`.
    #[inline]
    pub fn split_at<'a>(&'a self, idx: usize) -> (SharedBufferSlice<'a>, SharedBufferSlice<'a>) {
        let (a, b) = self.inner.split_at(idx);
        let a = SharedBufferSlice { inner: a, _marker: PhantomData };
        let b = SharedBufferSlice { inner: b, _marker: PhantomData };
        (a, b)
    }

    /// Create two non-overlapping mutable slices of the original `SharedBuffer`.
    ///
    /// Just like the `split_at_mut` method on array and slice references,
    /// `split_at_miut` constructs one `SharedBufferSliceMut` which represents
    /// bytes `[0, idx)`, and one which represents bytes `[idx, len)`, where
    /// `len` is the length of the buffer.
    ///
    /// # Panics
    ///
    /// `split_at_mut` panics if `idx > self.len()`.
    #[inline]
    pub fn split_at_mut<'a>(
        &'a mut self,
        idx: usize,
    ) -> (SharedBufferSliceMut<'a>, SharedBufferSliceMut<'a>) {
        let (a, b) = self.inner.split_at(idx);
        let a = SharedBufferSliceMut { inner: a, _marker: PhantomData };
        let b = SharedBufferSliceMut { inner: b, _marker: PhantomData };
        (a, b)
    }

    /// Get the buffer pointer and length so that the memory can be freed.
    ///
    /// This method is an alternative to calling `consume` if relinquishing
    /// ownership of the object is infeasible (for example, when the object is a
    /// struct field and thus can't be moved out of the struct). Since it allows
    /// the object to continue existing, it must be used with care (see the
    /// "Safety" section below).
    ///
    /// # Safety
    ///
    /// The returned pointer must *only* be used to free the memory. Since the
    /// memory is shared by another process, using it as a normal raw pointer to
    /// normal memory owned by this process is unsound.
    ///
    /// If the pointer is used for this purpose, then the caller must ensure
    /// that no methods will be called on the object after the call to
    /// `as_ptr_len`. The only scenario in which the object may be used again is
    /// if the caller does nothing at all with the return value of this method
    /// (although that would be kind of pointless...).
    pub fn as_ptr_len(&mut self) -> (*mut u8, usize) {
        (self.inner.buf, self.inner.len)
    }

    /// Consume the `SharedBuffer`, returning the underlying buffer pointer and
    /// length.
    ///
    /// Since `SharedBuffer`s do nothing on drop, the only way to ensure that
    /// resources are not leaked is to `consume` a `SharedBuffer` and then unmap
    /// the memory manually.
    #[inline]
    pub fn consume(self) -> (*mut u8, usize) {
        (self.inner.buf, self.inner.len)
    }
}

impl Drop for SharedBuffer {
    fn drop(&mut self) {
        // Release any writes performed after the last call to
        // self.release_writes().
        fence(Ordering::Release);
    }
}

/// An immutable slice into a `SharedBuffer`.
///
/// A `SharedBufferSlice` is created with `SharedBuffer::slice`,
/// `SharedBufferSlice::slice`, or `SharedBufferSliceMut::slice`.
#[derive(Debug)]
pub struct SharedBufferSlice<'a> {
    inner: SharedBufferInner,
    _marker: PhantomData<&'a ()>,
}

impl<'a> SharedBufferSlice<'a> {
    /// Read bytes from the buffer.
    ///
    /// Read up to `dst.len()` bytes from the buffer, returning how many bytes
    /// were read. The only thing that can cause fewer bytes to be read than
    /// requested is if `dst` is larger than the buffer itself.
    ///
    /// A call to `read` is only guaranteed to happen after an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `acquire_writes` method must be called before `read` and after receiving
    /// a signal from the other process in order to provide such ordering
    /// guarantees. In practice, this means that `acquire_writes` should be the
    /// first read operation that happens after receiving a signal from another
    /// process that the memory may be read. See the `acquire_writes`
    /// documentation for more details.
    #[inline]
    pub fn read(&self, dst: &mut [u8]) -> usize {
        self.inner.read_at(0, dst)
    }

    /// Read bytes from the buffer at an offset.
    ///
    /// Read up to `dst.len()` bytes starting at `offset` into the buffer,
    /// returning how many bytes were read. The only thing that can cause fewer
    /// bytes to be read than requested is if there are fewer than `dst.len()`
    /// bytes available starting at `offset` within the buffer.
    ///
    /// A call to `read_at` is only guaranteed to happen after an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `acquire_writes` method must be called before `read_at` and after
    /// receiving a signal from the other process in order to provide such
    /// ordering guarantees. In practice, this means that `acquire_writes`
    /// should be the first read operation that happens after receiving a signal
    /// from another process that the memory may be read. See the
    /// `acquire_writes` documentation for more details.
    ///
    /// # Panics
    ///
    /// `read_at` panics if `offset` is greater than the length of the buffer.
    #[inline]
    pub fn read_at(&self, offset: usize, dst: &mut [u8]) -> usize {
        self.inner.read_at(offset, dst)
    }

    /// Acquire all writes performed by the other process.
    ///
    /// On some systems (such as Fuchsia, currently), the communication
    /// mechanism used for signalling a process that memory is readable does not
    /// have well-defined synchronization semantics. On those systems, this
    /// method MUST be called after receiving such a signal, or else writes
    /// performed before that signal are not guaranteed to be observed by this
    /// process.
    ///
    /// `acquire_writes` acquires any writes performed on this buffer or any
    /// slice within the buffer.
    ///
    /// # Note on Fuchsia
    ///
    /// Zircon, the Fuchsia kernel, will likely eventually have well-defined
    /// semantics around the synchronization behavior of various syscalls. Once
    /// that happens, calling this method in Fuchsia programs may become
    /// optional. This work is tracked in [fxbug.dev/32098].
    ///
    /// [fxbug.dev/32098]: #
    // TODO(joshlf): Replace with link once issues are public.
    #[inline]
    pub fn acquire_writes(&self) {
        fence(Ordering::Acquire);
    }

    /// Create a sub-slice of this `SharedBufferSlice`.
    ///
    /// Just like the slicing operation on array and slice references, `slice`
    /// constructs a new `SharedBufferSlice` which points to the same memory as
    /// the original, but starting and index `from` (inclusive) and ending at
    /// index `to` (exclusive).
    ///
    /// # Panics
    ///
    /// `slice` panics if `range` is out of bounds of `self` or if `range` is
    /// nonsensical (its lower bound is larger than its upper bound).
    #[inline]
    pub fn slice<R: RangeBounds<usize>>(&self, range: R) -> SharedBufferSlice<'a> {
        SharedBufferSlice { inner: self.inner.slice(range), _marker: PhantomData }
    }

    /// Split this `SharedBufferSlice` in two.
    ///
    /// Just like the `split_at` method on array and slice references,
    /// `split_at` constructs one `SharedBufferSlice` which represents bytes
    /// `[0, idx)`, and one which represents bytes `[idx, len)`, where `len` is
    /// the length of the buffer slice.
    ///
    /// # Panics
    ///
    /// `split_at` panics if `idx > self.len()`.
    #[inline]
    pub fn split_at(&self, idx: usize) -> (SharedBufferSlice<'a>, SharedBufferSlice<'a>) {
        let (a, b) = self.inner.split_at(idx);
        let a = SharedBufferSlice { inner: a, _marker: PhantomData };
        let b = SharedBufferSlice { inner: b, _marker: PhantomData };
        (a, b)
    }

    /// The number of bytes in this `SharedBufferSlice`.
    #[inline]
    pub fn len(&self) -> usize {
        self.inner.len
    }
}

/// A mutable slice into a `SharedBuffer`.
///
/// A `SharedBufferSliceMut` is created with `SharedBuffer::slice_mut` or
/// `SharedBufferSliceMut::slice_mut`.
#[derive(Debug)]
pub struct SharedBufferSliceMut<'a> {
    inner: SharedBufferInner,
    _marker: PhantomData<&'a ()>,
}

impl<'a> SharedBufferSliceMut<'a> {
    /// Read bytes from the buffer.
    ///
    /// Read up to `dst.len()` bytes from the buffer, returning how many bytes
    /// were read. The only thing that can cause fewer bytes to be read than
    /// requested is if `dst` is larger than the buffer itself.
    ///
    /// A call to `read` is only guaranteed to happen after an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `acquire_writes` method must be called before `read` and after receiving
    /// a signal from the other process in order to provide such ordering
    /// guarantees. In practice, this means that `acquire_writes` should be the
    /// first read operation that happens after receiving a signal from another
    /// process that the memory may be read. See the `acquire_writes`
    /// documentation for more details.
    #[inline]
    pub fn read(&self, dst: &mut [u8]) -> usize {
        self.inner.read_at(0, dst)
    }

    /// Read bytes from the buffer at an offset.
    ///
    /// Read up to `dst.len()` bytes starting at `offset` into the buffer,
    /// returning how many bytes were read. The only thing that can cause fewer
    /// bytes to be read than requested is if there are fewer than `dst.len()`
    /// bytes available starting at `offset` within the buffer.
    ///
    /// A call to `read_at` is only guaranteed to happen after an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `acquire_writes` method must be called before `read_at` and after
    /// receiving a signal from the other process in order to provide such
    /// ordering guarantees. In practice, this means that `acquire_writes`
    /// should be the first read operation that happens after receiving a signal
    /// from another process that the memory may be read. See the
    /// `acquire_writes` documentation for more details.
    ///
    /// # Panics
    ///
    /// `read_at` panics if `offset` is greater than the length of the buffer.
    #[inline]
    pub fn read_at(&self, offset: usize, dst: &mut [u8]) -> usize {
        self.inner.read_at(offset, dst)
    }

    /// Write bytes to the buffer.
    ///
    /// Write up to `src.len()` bytes into the buffer, returning how many bytes
    /// were written. The only thing that can cause fewer bytes to be written
    /// than requested is if `src` is larger than the buffer itself.
    ///
    /// A call to `write` is only guaranteed to happen before an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `release_writes` method must be called after `write` and before
    /// signalling the other process in order to provide such ordering
    /// guarantees. In practice, this means that `release_writes` should be the
    /// last write operation that happens before signalling another process that
    /// the memory may be read. See the `release_writes` documentation for more
    /// details.
    #[inline]
    pub fn write(&self, src: &[u8]) -> usize {
        self.inner.write_at(0, src)
    }

    /// Write bytes to the buffer at an offset.
    ///
    /// Write up to `src.len()` bytes starting at `offset` into the buffer,
    /// returning how many bytes were written. The only thing that can cause
    /// fewer bytes to be written than requested is if there are fewer than
    /// `src.len()` bytes available starting at `offset` within the buffer.
    ///
    /// A call to `write_at` is only guaranteed to happen before an operation in
    /// another thread or process if the mechanism used to signal the other
    /// process has well-defined memory ordering semantics. Otherwise, the
    /// `release_writes` method must be called after `write_at` and before
    /// signalling the other process in order to provide such ordering
    /// guarantees. In practice, this means that `release_writes` should be the
    /// last write operation that happens before signalling another process that
    /// the memory may be read. See the `release_writes` documentation for more
    /// details.
    ///
    /// # Panics
    ///
    /// `write_at` panics if `offset` is greater than the length of the buffer.
    #[inline]
    pub fn write_at(&self, offset: usize, src: &[u8]) -> usize {
        self.inner.write_at(offset, src)
    }

    /// Acquire all writes performed by the other process.
    ///
    /// On some systems (such as Fuchsia, currently), the communication
    /// mechanism used for signalling a process that memory is readable does not
    /// have well-defined synchronization semantics. On those systems, this
    /// method MUST be called after receiving such a signal, or else writes
    /// performed before that signal are not guaranteed to be observed by this
    /// process.
    ///
    /// `acquire_writes` acquires any writes performed on this buffer or any
    /// slice within the buffer.
    ///
    /// # Note on Fuchsia
    ///
    /// Zircon, the Fuchsia kernel, will likely eventually have well-defined
    /// semantics around the synchronization behavior of various syscalls. Once
    /// that happens, calling this method in Fuchsia programs may become
    /// optional. This work is tracked in [fxbug.dev/32098].
    ///
    /// [fxbug.dev/32098]: #
    // TODO(joshlf): Replace with link once issues are public.
    #[inline]
    pub fn acquire_writes(&self) {
        fence(Ordering::Acquire);
    }

    /// Atomically release all writes performed so far.
    ///
    /// On some systems (such as Fuchsia, currently), the communication
    /// mechanism used for signalling the other process that memory is readable
    /// does not have well-defined synchronization semantics. On those systems,
    /// this method MUST be called before such signalling, or else writes
    /// performed before that signal are not guaranteed to be observed by the
    /// other process.
    ///
    /// `release_writes` releases any writes performed on this slice or any
    /// sub-slice of this slice.
    ///
    /// # Note on Fuchsia
    ///
    /// Zircon, the Fuchsia kernel, will likely eventually have well-defined
    /// semantics around the synchronization behavior of various syscalls. Once
    /// that happens, calling this method in Fuchsia programs may become
    /// optional. This work is tracked in [fxbug.dev/32098].
    ///
    /// [fxbug.dev/32098]: #
    // TODO(joshlf): Replace with link once issues are public.
    #[inline]
    pub fn release_writes(&mut self) {
        fence(Ordering::Release);
    }

    /// Create a sub-slice of this `SharedBufferSliceMut`.
    ///
    /// Just like the slicing operation on array and slice references, `slice`
    /// constructs a new `SharedBufferSlice` which points to the same memory as
    /// the original, but starting and index `from` (inclusive) and ending at
    /// index `to` (exclusive).
    ///
    /// # Panics
    ///
    /// `slice` panics if `range` is out of bounds of `self` or if `range` is
    /// nonsensical (its lower bound is larger than its upper bound).
    #[inline]
    pub fn slice<R: RangeBounds<usize>>(&self, range: R) -> SharedBufferSlice<'a> {
        SharedBufferSlice { inner: self.inner.slice(range), _marker: PhantomData }
    }

    /// Create a mutable slice of the original `SharedBufferSliceMut`.
    ///
    /// Just like the mutable slicing operation on array and slice references,
    /// `slice_mut` constructs a new `SharedBufferSliceMut` which points to the
    /// same memory as the original, but starting and index `from` (inclusive)
    /// and ending at index `to` (exclusive).
    ///
    /// # Panics
    ///
    /// `slice_mut` panics if `range` is out of bounds of `self` or if `range`
    /// is nonsensical (its lower bound is larger than its upper bound).
    #[inline]
    pub fn slice_mut<R: RangeBounds<usize>>(&mut self, range: R) -> SharedBufferSliceMut<'a> {
        SharedBufferSliceMut { inner: self.inner.slice(range), _marker: PhantomData }
    }

    /// Split this `SharedBufferSliceMut` into two immutable slices.
    ///
    /// Just like the `split_at` method on array and slice references,
    /// `split_at` constructs one `SharedBufferSlice` which represents bytes
    /// `[0, idx)`, and one which represents bytes `[idx, len)`, where `len` is
    /// the length of the buffer slice.
    ///
    /// # Panics
    ///
    /// `split_at` panics if `idx > self.len()`.
    #[inline]
    pub fn split_at(&self, idx: usize) -> (SharedBufferSlice<'a>, SharedBufferSlice<'a>) {
        let (a, b) = self.inner.split_at(idx);
        let a = SharedBufferSlice { inner: a, _marker: PhantomData };
        let b = SharedBufferSlice { inner: b, _marker: PhantomData };
        (a, b)
    }

    /// Split this `SharedBufferSliceMut` in two.
    ///
    /// Just like the `split_at_mut` method on array and slice references,
    /// `split_at` constructs one `SharedBufferSliceMut` which represents bytes
    /// `[0, idx)`, and one which represents bytes `[idx, len)`, where `len` is
    /// the length of the buffer slice.
    ///
    /// # Panics
    ///
    /// `split_at_mut` panics if `idx > self.len()`.
    #[inline]
    pub fn split_at_mut(
        &mut self,
        idx: usize,
    ) -> (SharedBufferSliceMut<'a>, SharedBufferSliceMut<'a>) {
        let (a, b) = self.inner.split_at(idx);
        let a = SharedBufferSliceMut { inner: a, _marker: PhantomData };
        let b = SharedBufferSliceMut { inner: b, _marker: PhantomData };
        (a, b)
    }

    /// The number of bytes in this `SharedBufferSlice`.
    #[inline]
    pub fn len(&self) -> usize {
        self.inner.len
    }
}

// Send and Sync implementations. Send and Sync are definitely safe since
// SharedBufferXXX are all written under the assumption that a remote process is
// concurrently modifying the memory. However, we aim to provide a Rust-like API
// with lifetimes and an immutable/mutable distinction, so the real question is
// whether Send and Sync make sense by analogy to normal Rust types. Insofar as
// SharedBuffer is analogous to [u8], SharedBufferSlice is analogous to &[u8],
// and SharedBufferSliceMut is analogous to &mut [u8], the answer is yes - all
// of those types implement both Send and Sync.

unsafe impl Send for SharedBuffer {}
unsafe impl Sync for SharedBuffer {}
unsafe impl<'a> Send for SharedBufferSlice<'a> {}
unsafe impl<'a> Sync for SharedBufferSlice<'a> {}
unsafe impl<'a> Send for SharedBufferSliceMut<'a> {}
unsafe impl<'a> Sync for SharedBufferSliceMut<'a> {}

#[cfg(test)]
mod tests {
    use core::mem;
    use core::ptr;

    use super::{overlap, SharedBuffer};

    // use the referent as the backing memory for a SharedBuffer
    unsafe fn buf_from_ref<T>(x: &mut T) -> SharedBuffer {
        let size = mem::size_of::<T>();
        SharedBuffer::new(x as *mut _ as *mut u8, size)
    }

    #[test]
    fn test_buf() {
        // initialize some memory and turn it into a SharedBuffer
        const ONE: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
        let mut buf_memory = ONE;
        let buf = unsafe { buf_from_ref(&mut buf_memory) };

        // we read the same initial contents back
        let mut bytes = [0u8; 8];
        assert_eq!(buf.read(&mut bytes[..]), 8);
        assert_eq!(bytes, ONE);

        // when we write new contents, we read those back
        const TWO: [u8; 8] = [7, 6, 5, 4, 3, 2, 1, 0];
        assert_eq!(buf.write(&TWO[..]), 8);
        assert_eq!(buf.read(&mut bytes[..]), 8);
        assert_eq!(bytes, TWO);

        // even with a bigger buffer, we still only read 8 bytes
        let mut bytes = [0u8; 16];
        assert_eq!(buf.read(&mut bytes[..]), 8);
        // starting at offset 4, there are only 4 bytes left, so we only read 4
        // bytes
        assert_eq!(buf.read_at(4, &mut bytes[..]), 4);
    }

    #[test]
    fn test_slice() {
        // various slices give us the lengths we expect
        let buf = unsafe { SharedBuffer::new(ptr::null_mut(), 10) };
        let tmp = buf.slice(..);
        assert_eq!(tmp.len(), 10);
        let tmp = buf.slice(..10);
        assert_eq!(tmp.len(), 10);
        let tmp = buf.slice(5..10);
        assert_eq!(tmp.len(), 5);
        let tmp = buf.slice(0..0);
        assert_eq!(tmp.len(), 0);
        let tmp = buf.slice(10..10);
        assert_eq!(tmp.len(), 0);

        // initialize some memory and turn it into a SharedBuffer
        const INIT: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
        let mut buf_memory = INIT;
        let buf = unsafe { buf_from_ref(&mut buf_memory) };

        // we read the same initial contents back
        let mut bytes = [0u8; 8];
        assert_eq!(buf.read_at(0, &mut bytes[..]), 8);
        assert_eq!(bytes, INIT);

        // create a slice to the second half of the SharedBuffer
        let buf2 = buf.slice(4..8);

        // now we read back only the second half of the original SharedBuffer
        bytes = [0; 8];
        assert_eq!(buf2.read(&mut bytes[..]), 4);
        assert_eq!(bytes, [4, 5, 6, 7, 0, 0, 0, 0]);
    }

    #[test]
    fn test_split() {
        // various splits give us the lengths we expect
        let buf = unsafe { SharedBuffer::new(ptr::null_mut(), 10) };
        let (tmp1, tmp2) = buf.split_at(10);
        assert_eq!(tmp1.len(), 10);
        assert_eq!(tmp2.len(), 0);
        let (tmp1, tmp2) = buf.split_at(5);
        assert_eq!(tmp1.len(), 5);
        assert_eq!(tmp2.len(), 5);
        let (tmp1, tmp2) = buf.split_at(0);
        assert_eq!(tmp1.len(), 0);
        assert_eq!(tmp2.len(), 10);

        // initialize some memory and turn it into a SharedBuffer
        const INIT: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
        let mut buf_memory = INIT;
        let mut buf = unsafe { buf_from_ref(&mut buf_memory) };

        // we read the same initial contents back
        let mut bytes = [0u8; 8];
        assert_eq!(buf.read_at(0, &mut bytes[..]), 8);
        assert_eq!(bytes, INIT);

        // split in two equal-sized halves
        let (buf1, buf2) = buf.split_at_mut(4);

        // now we read back the halves separately
        bytes = [0; 8];
        assert_eq!(buf1.read(&mut bytes[..4]), 4);
        assert_eq!(buf2.read(&mut bytes[4..]), 4);
        assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);

        // use the mutable slices to write to the buffer
        assert_eq!(buf1.write(&[7, 6, 5, 4]), 4);
        assert_eq!(buf2.write(&[3, 2, 1, 0]), 4);

        // split again into equal-sized quarters
        let ((buf1, buf2), (buf3, buf4)) = (buf1.split_at(2), buf2.split_at(2));

        // now we read back the quarters separately
        bytes = [0; 8];
        assert_eq!(buf1.read(&mut bytes[..2]), 2);
        assert_eq!(buf2.read(&mut bytes[2..4]), 2);
        assert_eq!(buf3.read(&mut bytes[4..6]), 2);
        assert_eq!(buf4.read(&mut bytes[6..]), 2);
        assert_eq!(bytes, [7, 6, 5, 4, 3, 2, 1, 0]);
    }

    #[test]
    fn test_overlap() {
        // overlap(offset, copy_len, range_len)

        // first branch: offset > range_len
        assert_eq!(overlap(10, 4, 8), None);

        // middle branch: offset + copy_len <= range_len
        assert_eq!(overlap(0, 4, 8), Some(4));
        assert_eq!(overlap(4, 4, 8), Some(4));

        // middle branch: 'offset + copy_len' overflows usize
        assert_eq!(overlap(4, ::core::usize::MAX, 8), Some(4));

        // last branch: else
        assert_eq!(overlap(6, 4, 8), Some(2));
        assert_eq!(overlap(8, 4, 8), Some(0));
    }

    #[test]
    #[should_panic]
    fn test_panic_read_at() {
        let buf = unsafe { SharedBuffer::new(ptr::null_mut(), 10) };
        // "byte offset 11 out of range for SharedBuffer of length 10"
        buf.read_at(11, &mut [][..]);
    }

    #[test]
    #[should_panic]
    fn test_panic_write_at() {
        let buf = unsafe { SharedBuffer::new(ptr::null_mut(), 10) };
        // "byte offset 11 out of range for SharedBuffer of length 10"
        buf.write_at(11, &[][..]);
    }

    #[test]
    #[should_panic]
    fn test_panic_slice_1() {
        let buf = unsafe { SharedBuffer::new(ptr::null_mut(), 10) };
        // "byte index 11 out of range for SharedBuffer of length 10"
        buf.slice(0..11);
    }

    #[test]
    #[should_panic]
    fn test_panic_slice_2() {
        let buf = unsafe { SharedBuffer::new(ptr::null_mut(), 10) };
        // "slice starts at byte 6 but ends at byte 5"
        buf.slice(6..5);
    }
}
