forked from M-Labs/libfringe
move stack creation / destruction into platform
This commit is contained in:
parent
3957ac99ae
commit
a94bc324fe
|
@ -1,5 +1,4 @@
|
||||||
#![feature(default_type_params, macro_rules)]
|
#![feature(default_type_params, macro_rules)]
|
||||||
extern crate libc;
|
|
||||||
extern crate fn_box;
|
extern crate fn_box;
|
||||||
|
|
||||||
pub use context::Context;
|
pub use context::Context;
|
||||||
|
|
|
@ -1,8 +1,75 @@
|
||||||
use libc;
|
extern crate libc;
|
||||||
|
use std::os::{errno, page_size, MemoryMap, MapReadable, MapWritable,
|
||||||
|
MapNonStandardFlags};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[link_name = "lwt_stack_register"]
|
#[link_name = "lwt_stack_register"]
|
||||||
pub fn stack_register(start: *const u8, end: *const u8) -> libc::c_uint;
|
fn stack_register(start: *const u8, end: *const u8) -> libc::c_uint;
|
||||||
#[link_name = "lwt_stack_deregister"]
|
#[link_name = "lwt_stack_deregister"]
|
||||||
pub fn stack_deregister(id: libc::c_uint);
|
fn stack_deregister(id: libc::c_uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Stack {
|
||||||
|
buf: MemoryMap,
|
||||||
|
valgrind_id: libc::c_uint
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const STACK_FLAGS: libc::c_int = libc::MAP_STACK
|
||||||
|
| libc::MAP_PRIVATE
|
||||||
|
| libc::MAP_ANON;
|
||||||
|
|
||||||
|
impl Stack {
|
||||||
|
pub fn new(size: uint) -> Stack {
|
||||||
|
let buf = match MemoryMap::new(size, &[MapReadable, MapWritable,
|
||||||
|
MapNonStandardFlags(STACK_FLAGS)]) {
|
||||||
|
Ok(map) => map,
|
||||||
|
Err(e) => panic!("mmap for stack of size {} failed: {}", size, e)
|
||||||
|
};
|
||||||
|
|
||||||
|
if !protect_last_page(&buf) {
|
||||||
|
panic!("Could not memory-protect guard page. stack={}, errno={}",
|
||||||
|
buf.data(), errno());
|
||||||
|
}
|
||||||
|
|
||||||
|
let valgrind_id = unsafe {
|
||||||
|
stack_register(buf.data().offset(buf.len() as int) as *const _,
|
||||||
|
buf.data() as *const _)
|
||||||
|
};
|
||||||
|
|
||||||
|
Stack {
|
||||||
|
buf: buf,
|
||||||
|
valgrind_id: valgrind_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn protect_last_page(stack: &MemoryMap) -> bool {
|
||||||
|
unsafe {
|
||||||
|
let last_page = stack.data() as *mut libc::c_void;
|
||||||
|
libc::mprotect(last_page, page_size() as libc::size_t,
|
||||||
|
libc::PROT_NONE) != -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Stack {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
stack_deregister(self.valgrind_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stack {
|
||||||
|
pub fn top(&mut self) -> *mut u8 {
|
||||||
|
unsafe {
|
||||||
|
self.buf.data().offset(self.buf.len() as int)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn limit(&self) -> *const u8 {
|
||||||
|
unsafe {
|
||||||
|
self.buf.data().offset(page_size() as int) as *const _
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
73
src/stack.rs
73
src/stack.rs
|
@ -1,48 +1,16 @@
|
||||||
use libc;
|
|
||||||
use platform;
|
use platform;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::os::{errno, page_size, MemoryMap, MapReadable, MapWritable,
|
|
||||||
MapNonStandardFlags};
|
|
||||||
|
|
||||||
const STACK_FLAGS: libc::c_int = libc::MAP_STACK
|
|
||||||
| libc::MAP_PRIVATE
|
|
||||||
| libc::MAP_ANON;
|
|
||||||
|
|
||||||
pub enum Stack {
|
pub enum Stack {
|
||||||
Native {
|
Native {
|
||||||
sp_limit: *const u8
|
sp_limit: *const u8
|
||||||
},
|
},
|
||||||
Managed {
|
Managed(platform::Stack)
|
||||||
buf: MemoryMap,
|
|
||||||
valgrind_id: libc::c_uint
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stack {
|
impl Stack {
|
||||||
pub fn new(size: uint) -> Stack {
|
pub fn new(size: uint) -> Stack {
|
||||||
let buf = match MemoryMap::new(size, &[MapReadable, MapWritable,
|
Stack::Managed(platform::Stack::new(size))
|
||||||
MapNonStandardFlags(STACK_FLAGS)]) {
|
|
||||||
Ok(map) => map,
|
|
||||||
Err(e) => panic!("mmap for stack of size {} failed: {}", size, e)
|
|
||||||
};
|
|
||||||
|
|
||||||
if !protect_last_page(&buf) {
|
|
||||||
panic!("Could not memory-protect guard page. stack={}, errno={}",
|
|
||||||
buf.data(), errno());
|
|
||||||
}
|
|
||||||
|
|
||||||
let valgrind_id = unsafe {
|
|
||||||
platform::stack_register(buf.data().offset(buf.len() as int) as *const _,
|
|
||||||
buf.data() as *const _)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
let stk = Stack::Managed {
|
|
||||||
buf: buf,
|
|
||||||
valgrind_id: valgrind_id
|
|
||||||
};
|
|
||||||
|
|
||||||
stk
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn native(limit: *const u8) -> Stack {
|
pub unsafe fn native(limit: *const u8) -> Stack {
|
||||||
|
@ -52,43 +20,16 @@ impl Stack {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn top(&mut self) -> *mut u8 {
|
pub fn top(&mut self) -> *mut u8 {
|
||||||
unsafe {
|
match *self {
|
||||||
match *self {
|
Stack::Native { .. } => ptr::null_mut(),
|
||||||
Stack::Native { .. } => ptr::null_mut(),
|
Stack::Managed(ref mut stack) => stack.top()
|
||||||
Stack::Managed { ref buf, .. } => {
|
|
||||||
buf.data().offset(buf.len() as int)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn limit(&self) -> *const u8 {
|
pub fn limit(&self) -> *const u8 {
|
||||||
unsafe {
|
|
||||||
match *self {
|
|
||||||
Stack::Native { sp_limit, .. } => sp_limit,
|
|
||||||
Stack::Managed { ref buf, .. } => {
|
|
||||||
buf.data().offset(page_size() as int) as *const _
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn protect_last_page(stack: &MemoryMap) -> bool {
|
|
||||||
unsafe {
|
|
||||||
let last_page = stack.data() as *mut libc::c_void;
|
|
||||||
libc::mprotect(last_page, page_size() as libc::size_t,
|
|
||||||
libc::PROT_NONE) != -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Stack {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
match *self {
|
match *self {
|
||||||
Stack::Native { .. } => {},
|
Stack::Native { sp_limit, .. } => sp_limit,
|
||||||
Stack::Managed { valgrind_id, .. } => unsafe {
|
Stack::Managed(ref stack) => stack.limit()
|
||||||
platform::stack_deregister(valgrind_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue