From face6f07f3f342d17caec1806962a6b8fe054492 Mon Sep 17 00:00:00 2001 From: jD91mZM2 <me@krake.one> Date: Thu, 9 Aug 2018 10:54:44 +0200 Subject: [PATCH] Implement mmap --- Cargo.lock | 1 + include/bits/sys/mman.h | 6 +++++ include/limits.h | 6 ++++- include/stddef.h | 2 ++ src/fcntl/src/linux.rs | 1 + src/platform/Cargo.toml | 1 + src/platform/src/lib.rs | 9 ++++--- src/platform/src/linux/mod.rs | 15 +++++++++++ src/platform/src/redox/mod.rs | 50 ++++++++++++++++++++++++++++++++--- src/sys_mman/cbindgen.toml | 1 + src/sys_mman/src/lib.rs | 12 ++++----- src/sys_mman/src/linux.rs | 2 ++ src/sys_mman/src/redox.rs | 10 +++++++ 13 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 include/bits/sys/mman.h diff --git a/Cargo.lock b/Cargo.lock index ca2660b0..5750edb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,6 +247,7 @@ dependencies = [ "ralloc 1.0.0", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/include/bits/sys/mman.h b/include/bits/sys/mman.h new file mode 100644 index 00000000..e2ece78c --- /dev/null +++ b/include/bits/sys/mman.h @@ -0,0 +1,6 @@ +#ifndef _BITS_SYS_MMAN_H +#define _BITS_SYS_MMAN_H + +#define MAP_FAILED ((void *) -1) + +#endif diff --git a/include/limits.h b/include/limits.h index a8a750bb..1b2de46f 100644 --- a/include/limits.h +++ b/include/limits.h @@ -1,7 +1,11 @@ #define MB_LEN_MAX 4 // unicode #define CHAR_BIT __CHAR_BIT__ -#define CHAR_MAX __CHAR_MAX__ +#ifdef __CHAR_MAX__ +# define CHAR_MAX __CHAR_MAX__ +#else +# define CHAR_MAX 0xFF +#endif #define CHAR_MIN 0 #define INT_MAX __INT_MAX__ #define INT_MIN (-INT_MAX - 1) diff --git a/include/stddef.h b/include/stddef.h index 1dc7f60f..0ee2d471 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -10,4 +10,6 @@ typedef int32_t wchar_t; typedef unsigned long long size_t; +#define offsetof(type, member) __builtin_offsetof(type, member) + #endif /* _STDDEF_H */ diff --git a/src/fcntl/src/linux.rs b/src/fcntl/src/linux.rs index 98a5f8a2..05948a6d 100644 --- a/src/fcntl/src/linux.rs +++ b/src/fcntl/src/linux.rs @@ -10,3 +10,4 @@ pub const O_APPEND: c_int = 0o2000; pub const O_CLOEXEC: c_int = 0o2_000_000; pub const O_DIRECTORY: c_int = 0o200_000; pub const O_EXCL: c_int = 0o200; +pub const O_NONBLOCK: c_int = 0o4000; diff --git a/src/platform/Cargo.toml b/src/platform/Cargo.toml index 3a1ecfbf..6c179a9f 100644 --- a/src/platform/Cargo.toml +++ b/src/platform/Cargo.toml @@ -13,3 +13,4 @@ sc = "0.2" [target.'cfg(target_os = "redox")'.dependencies] redox_syscall = "0.1" +spin = "0.4" diff --git a/src/platform/src/lib.rs b/src/platform/src/lib.rs index 37964737..2a634a4e 100644 --- a/src/platform/src/lib.rs +++ b/src/platform/src/lib.rs @@ -6,13 +6,16 @@ #[cfg_attr(target_os = "redox", macro_use)] extern crate alloc; -#[cfg(all(not(feature = "no_std"), target_os = "linux"))] +#[cfg(target_os = "linux")] #[macro_use] extern crate sc; -#[cfg(all(not(feature = "no_std"), target_os = "redox"))] +#[cfg(target_os = "redox")] extern crate syscall; +#[cfg(target_os = "redox")] +extern crate spin; + pub use allocator::*; #[cfg(not(feature = "ralloc"))] @@ -38,7 +41,7 @@ pub mod types; pub use rawfile::RawFile; -use alloc::Vec; +use alloc::vec::Vec; use core::{fmt, ptr}; use types::*; diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs index be108e8d..5446a52f 100644 --- a/src/platform/src/linux/mod.rs +++ b/src/platform/src/linux/mod.rs @@ -284,6 +284,21 @@ pub fn mkfifo(path: *const c_char, mode: mode_t) -> c_int { e(unsafe { syscall!(MKNODAT, AT_FDCWD, path, mode, 0) }) as c_int } +pub unsafe fn mmap( + addr: *mut c_void, + len: usize, + prot: c_int, + flags: c_int, + fildes: c_int, + off: off_t, +) -> *mut c_void { + e(syscall!(MMAP, addr, len, prot, flags, fildes, off)) as *mut c_void +} + +pub unsafe fn munmap(addr: *mut c_void, len: usize) -> c_int { + e(syscall!(MUNMAP, addr, len)) as c_int +} + pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int { e(unsafe { syscall!(NANOSLEEP, rqtp, rmtp) }) as c_int } diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index 789e7748..6d9afdb3 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -1,9 +1,9 @@ //! sys/socket implementation, following http://pubs.opengroup.org/onlinepubs/009696699/basedefs/sys/socket.h.html +use alloc::btree_map::BTreeMap; use core::fmt::Write; -use core::mem; -use core::ptr; -use core::slice; +use core::{mem, ptr, slice}; +use spin::{Once, Mutex, MutexGuard}; use syscall::data::Stat as redox_stat; use syscall::data::TimeSpec as redox_timespec; use syscall::flag::*; @@ -13,10 +13,17 @@ use types::*; use *; const EINVAL: c_int = 22; +const MAP_ANON: c_int = 1; #[thread_local] static mut SIG_HANDLER: Option<extern "C" fn(c_int)> = None; +static ANONYMOUS_MAPS: Once<Mutex<BTreeMap<usize, usize>>> = Once::new(); + +fn anonymous_maps() -> MutexGuard<'static, BTreeMap<usize, usize>> { + ANONYMOUS_MAPS.call_once(|| Mutex::new(BTreeMap::new())).lock() +} + extern "C" fn sig_handler(sig: usize) { if let Some(ref callback) = unsafe { SIG_HANDLER } { callback(sig as c_int); @@ -640,6 +647,43 @@ pub fn mkfifo(path: *const c_char, mode: mode_t) -> c_int { } } +pub unsafe fn mmap( + _addr: *mut c_void, + len: usize, + _prot: c_int, + flags: c_int, + fildes: c_int, + off: off_t, +) -> *mut c_void { + if flags & MAP_ANON == MAP_ANON { + let fd = e(syscall::open("memory:", 0)); // flags don't matter currently + if fd == !0 { + return !0 as *mut c_void; + } + + let addr = e(syscall::fmap(fd, off as usize, len as usize)); + if addr == !0 { + let _ = syscall::close(fd); + return !0 as *mut c_void; + } + + anonymous_maps().insert(addr as usize, fd); + addr as *mut c_void + } else { + e(syscall::fmap(fildes as usize, off as usize, len as usize)) as *mut c_void + } +} + +pub unsafe fn munmap(addr: *mut c_void, _len: usize) -> c_int { + if e(syscall::funmap(addr as usize)) == !0 { + return !0; + } + if let Some(fd) = anonymous_maps().remove(&(addr as usize)) { + let _ = syscall::close(fd); + } + 0 +} + pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int { let redox_rqtp = unsafe { redox_timespec::from(&*rqtp) }; let mut redox_rmtp: redox_timespec; diff --git a/src/sys_mman/cbindgen.toml b/src/sys_mman/cbindgen.toml index baaa5325..1fecef57 100644 --- a/src/sys_mman/cbindgen.toml +++ b/src/sys_mman/cbindgen.toml @@ -1,5 +1,6 @@ sys_includes = ["stdint.h", "sys/types.h"] include_guard = "_SYS_MMAN_H" +trailer = "#include <bits/sys/mman.h>" language = "C" style = "Tag" diff --git a/src/sys_mman/src/lib.rs b/src/sys_mman/src/lib.rs index 4c47b135..c2151e40 100644 --- a/src/sys_mman/src/lib.rs +++ b/src/sys_mman/src/lib.rs @@ -24,8 +24,8 @@ pub extern "C" fn mlockall(flags: c_int) -> c_int { unimplemented!(); } -// #[no_mangle] -pub extern "C" fn mmap( +#[no_mangle] +pub unsafe extern "C" fn mmap( addr: *mut c_void, len: usize, prot: c_int, @@ -33,7 +33,7 @@ pub extern "C" fn mmap( fildes: c_int, off: off_t, ) -> *mut c_void { - unimplemented!(); + platform::mmap(addr, len, prot, flags, fildes, off) } // #[no_mangle] @@ -56,9 +56,9 @@ pub extern "C" fn munlockall() -> c_int { unimplemented!(); } -// #[no_mangle] -pub extern "C" fn munmap(addr: *mut c_void, len: usize) -> c_int { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn munmap(addr: *mut c_void, len: usize) -> c_int { + platform::munmap(addr, len) } // #[no_mangle] diff --git a/src/sys_mman/src/linux.rs b/src/sys_mman/src/linux.rs index 1e002271..0a6933af 100644 --- a/src/sys_mman/src/linux.rs +++ b/src/sys_mman/src/linux.rs @@ -7,3 +7,5 @@ pub const PROT_NONE: c_int = 0x0; pub const MAP_SHARED: c_int = 0x1; pub const MAP_PRIVATE: c_int = 0x2; +pub const MAP_ANON: c_int = 0x20; +pub const MAP_ANONYMOUS: c_int = MAP_ANON; diff --git a/src/sys_mman/src/redox.rs b/src/sys_mman/src/redox.rs index 8b137891..1822e152 100644 --- a/src/sys_mman/src/redox.rs +++ b/src/sys_mman/src/redox.rs @@ -1 +1,11 @@ +use platform::types::*; +pub const PROT_READ: c_int = 0; +pub const PROT_WRITE: c_int = 0; +pub const PROT_EXEC: c_int = 0; +pub const PROT_NONE: c_int = 0; + +pub const MAP_SHARED: c_int = 0; +pub const MAP_PRIVATE: c_int = 0; +pub const MAP_ANON: c_int = 1; +pub const MAP_ANONYMOUS: c_int = MAP_ANON; -- GitLab