Expose fringe::STACK_ALIGNMENT, and make OwnedStack respect it.

This commit is contained in:
whitequark 2016-09-02 22:14:07 +00:00 committed by edef
parent 0ca4bc86ff
commit c6ece101e2
7 changed files with 29 additions and 13 deletions

View File

@ -40,6 +40,8 @@
// when unwinding as well as returning normally, because LLVM does not do it for us. // when unwinding as well as returning normally, because LLVM does not do it for us.
use stack::Stack; use stack::Stack;
pub const STACK_ALIGNMENT: usize = 4;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StackPointer(*mut usize); pub struct StackPointer(*mut usize);

View File

@ -41,6 +41,8 @@
// when unwinding as well as returning normally, because LLVM does not do it for us. // when unwinding as well as returning normally, because LLVM does not do it for us.
use stack::Stack; use stack::Stack;
pub const STACK_ALIGNMENT: usize = 16;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StackPointer(*mut usize); pub struct StackPointer(*mut usize);

View File

@ -45,6 +45,8 @@
// when unwinding as well as returning normally, because LLVM does not do it for us. // when unwinding as well as returning normally, because LLVM does not do it for us.
use stack::Stack; use stack::Stack;
pub const STACK_ALIGNMENT: usize = 16;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StackPointer(*mut usize); pub struct StackPointer(*mut usize);

View File

@ -5,7 +5,7 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be // http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms. // copied, modified, or distributed except according to those terms.
#![feature(asm, naked_functions, cfg_target_vendor)] #![feature(asm, naked_functions, cfg_target_vendor)]
#![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "alloc", feature(alloc, heap_api))]
#![cfg_attr(test, feature(test, thread_local, const_fn))] #![cfg_attr(test, feature(test, thread_local, const_fn))]
#![no_std] #![no_std]
@ -45,6 +45,10 @@ pub use owned_stack::OwnedStack;
pub use os::Stack as OsStack; pub use os::Stack as OsStack;
mod arch; mod arch;
/// Minimum alignment of a stack base address on the target platform.
pub const STACK_ALIGNMENT: usize = arch::STACK_ALIGNMENT;
mod debug; mod debug;
mod context; mod context;

View File

@ -3,18 +3,22 @@
// See the LICENSE file included in this distribution. // See the LICENSE file included in this distribution.
extern crate alloc; extern crate alloc;
use self::alloc::raw_vec::RawVec; use core::slice;
use self::alloc::heap;
use self::alloc::boxed::Box; use self::alloc::boxed::Box;
/// OwnedStack allocates on heap and owns a non-guarded stack. /// OwnedStack holds a non-guarded, heap-allocated stack.
#[derive(Debug)] #[derive(Debug)]
pub struct OwnedStack(Box<[u8]>); pub struct OwnedStack(Box<[u8]>);
impl OwnedStack { impl OwnedStack {
/// Allocates a new stack with exactly `size` accessible bytes using /// Allocates a new stack with exactly `size` accessible bytes and alignment appropriate
/// the default Rust allocator. /// for the current platform using the default Rust allocator.
pub fn new(size: usize) -> OwnedStack { pub fn new(size: usize) -> OwnedStack {
OwnedStack(unsafe { RawVec::with_capacity(size).into_box() }) unsafe {
let ptr = heap::allocate(size, ::STACK_ALIGNMENT);
OwnedStack(Box::from_raw(slice::from_raw_parts_mut(ptr, size)))
}
} }
} }

View File

@ -2,8 +2,10 @@
// Copyright (c) whitequark <whitequark@whitequark.org> // Copyright (c) whitequark <whitequark@whitequark.org>
// See the LICENSE file included in this distribution. // See the LICENSE file included in this distribution.
/// SliceStack holds a non-guarded stack allocated elsewhere and provided as a mutable /// SliceStack holds a non-guarded stack allocated elsewhere and provided as a mutable slice.
/// slice. ///
/// Any slice used in a SliceStack must adhere to the [Stack contract][contract].
/// [contract]: trait.Stack.html
#[derive(Debug)] #[derive(Debug)]
pub struct SliceStack<'a>(pub &'a mut [u8]); pub struct SliceStack<'a>(pub &'a mut [u8]);

View File

@ -11,17 +11,17 @@
/// To preserve memory safety, an implementation of this trait must fulfill /// To preserve memory safety, an implementation of this trait must fulfill
/// the following contract: /// the following contract:
/// ///
/// * The base of the stack must be aligned to a platform-specific boundary. /// * The base address of the stack must be aligned to
/// a [`STACK_ALIGNMENT`][align]-byte boundary.
/// * Every address between the base and the limit must be readable and writable. /// * Every address between the base and the limit must be readable and writable.
/// ///
/// On any platform supported by libfringe, it is safe to align the stack to a 16-byte boundary. /// [align]: constant.STACK_ALIGNMENT.html
/// The platform ABI document lists the specific alignment requirement.
pub trait Stack { pub trait Stack {
/// Returns the base of the stack. /// Returns the base address of the stack.
/// On all modern architectures, the stack grows downwards, /// On all modern architectures, the stack grows downwards,
/// so this is the highest address. /// so this is the highest address.
fn base(&self) -> *mut u8; fn base(&self) -> *mut u8;
/// Returns the limit of the stack. /// Returns the limit address of the stack.
/// On all modern architectures, the stack grows downwards, /// On all modern architectures, the stack grows downwards,
/// so this is the lowest address. /// so this is the lowest address.
fn limit(&self) -> *mut u8; fn limit(&self) -> *mut u8;