forked from M-Labs/libfringe
Expose fringe::STACK_ALIGNMENT, and make OwnedStack respect it.
This commit is contained in:
parent
0ca4bc86ff
commit
c6ece101e2
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
||||||
|
|
10
src/stack.rs
10
src/stack.rs
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue