diff --git a/src/arch/aarch64.rs b/src/arch/aarch64.rs index e771396..63c64cf 100644 --- a/src/arch/aarch64.rs +++ b/src/arch/aarch64.rs @@ -3,6 +3,8 @@ use core::ops::{Deref, DerefMut}; use super::error::{Error, Result}; +pub const PAGE_SIZE: usize = 4096; + macro_rules! syscall { ($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, )?)?)?)?)?);)+) => { $( diff --git a/src/arch/nonredox.rs b/src/arch/nonredox.rs index f99a714..65c44fc 100644 --- a/src/arch/nonredox.rs +++ b/src/arch/nonredox.rs @@ -1,5 +1,8 @@ use super::error::{Error, Result, ENOSYS}; +// Doesn't really matter, but since we will most likely run on an x86_64 host, why not 4096? +pub const PAGE_SIZE: usize = 4096; + pub unsafe fn syscall0(_a: usize) -> Result { Err(Error::new(ENOSYS)) } diff --git a/src/arch/x86.rs b/src/arch/x86.rs index 2f9301e..a97ba81 100644 --- a/src/arch/x86.rs +++ b/src/arch/x86.rs @@ -4,6 +4,8 @@ use core::ops::{Deref, DerefMut}; use super::error::{Error, Result}; +pub const PAGE_SIZE: usize = 4096; + macro_rules! syscall { ($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, )?)?)?)?)?);)+) => { $( diff --git a/src/arch/x86_64.rs b/src/arch/x86_64.rs index f71898e..2ff57bb 100644 --- a/src/arch/x86_64.rs +++ b/src/arch/x86_64.rs @@ -4,6 +4,8 @@ use core::ops::{Deref, DerefMut}; use super::error::{Error, Result}; +pub const PAGE_SIZE: usize = 4096; + macro_rules! syscall { ($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, )?)?)?)?)?);)+) => { $( diff --git a/src/call.rs b/src/call.rs index f6eb89c..1e8eac6 100644 --- a/src/call.rs +++ b/src/call.rs @@ -38,11 +38,6 @@ pub fn chmod>(path: T, mode: usize) -> Result { unsafe { syscall3(SYS_CHMOD, path.as_ref().as_ptr() as usize, path.as_ref().len(), mode) } } -/// Produce a fork of the current process, or a new process thread -pub unsafe fn clone(flags: CloneFlags) -> Result { - syscall1(SYS_CLONE, flags.bits()) -} - /// Close a file pub fn close(fd: usize) -> Result { unsafe { syscall1(SYS_CLOSE, fd) } @@ -85,11 +80,6 @@ pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result { unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) } } -/// Replace the current process with a new executable -pub fn fexec(fd: usize, args: &[[usize; 2]], vars: &[[usize; 2]]) -> Result { - unsafe { syscall5(SYS_FEXEC, fd, args.as_ptr() as usize, args.len(), vars.as_ptr() as usize, vars.len()) } -} - /// Map a file into memory, but with the ability to set the address to map into, either as a hint /// or as a requirement of the map. /// diff --git a/src/daemon.rs b/src/daemon.rs deleted file mode 100644 index 6433bcd..0000000 --- a/src/daemon.rs +++ /dev/null @@ -1,62 +0,0 @@ -use core::convert::Infallible; - -use super::{ - clone, - CloneFlags, - close, - EIO, - Error, - exit, - pipe2, - read, - Result, - write, -}; - -#[must_use = "Daemon::ready must be called"] -pub struct Daemon { - write_pipe: usize, -} - -impl Daemon { - pub fn new Infallible>(f: F) -> Result { - let mut pipes = [0; 2]; - pipe2(&mut pipes, 0)?; - - let [read_pipe, write_pipe] = pipes; - - if unsafe { clone(CloneFlags::empty())? } == 0 { - let _ = close(read_pipe); - - f(Daemon { - write_pipe, - }); - // TODO: Replace Infallible with the never type once it is stabilized. - unreachable!(); - } else { - let _ = close(write_pipe); - - let mut data = [0]; - let res = read(read_pipe, &mut data); - let _ = close(read_pipe); - - if res? == 1 { - exit(data[0] as usize)?; - unreachable!(); - } else { - Err(Error::new(EIO)) - } - } - } - - pub fn ready(self) -> Result<()> { - let res = write(self.write_pipe, &[0]); - let _ = close(self.write_pipe); - - if res? == 1 { - Ok(()) - } else { - Err(Error::new(EIO)) - } - } -} diff --git a/src/flag.rs b/src/flag.rs index 9788884..3411048 100644 --- a/src/flag.rs +++ b/src/flag.rs @@ -32,18 +32,6 @@ macro_rules! bitflags { } } -bitflags! { - pub struct CloneFlags: usize { - const CLONE_VM = 0x100; - const CLONE_FS = 0x200; - const CLONE_FILES = 0x400; - const CLONE_SIGHAND = 0x800; - const CLONE_VFORK = 0x4000; - const CLONE_THREAD = 0x10000; - const CLONE_STACK = 0x1000_0000; - } -} - pub const CLOCK_REALTIME: usize = 1; pub const CLOCK_MONOTONIC: usize = 4; @@ -213,8 +201,10 @@ bitflags! { /// If you don't catch this, the child is started as normal. const PTRACE_EVENT_CLONE = 0x0000_0000_0000_0100; - const PTRACE_EVENT_MASK = 0x0000_0000_0000_0F00; + /// Sent when current-addrspace is changed, allowing the tracer to reopen the memory file. + const PTRACE_EVENT_ADDRSPACE_SWITCH = 0x0000_0000_0000_0200; + const PTRACE_EVENT_MASK = 0x0000_0000_0000_0F00; /// Special meaning, depending on the event. Usually, when fired before /// an action, it will skip performing that action. @@ -292,13 +282,6 @@ bitflags! { } } -// Auxiliery vector types -pub const AT_NULL: usize = 0; -pub const AT_PHDR: usize = 3; -pub const AT_PHENT: usize = 4; -pub const AT_PHNUM: usize = 5; -pub const AT_ENTRY: usize = 9; - bitflags! { pub struct WaitFlags: usize { const WNOHANG = 0x01; @@ -307,6 +290,11 @@ bitflags! { } } +pub const ADDRSPACE_OP_MMAP: usize = 0; +pub const ADDRSPACE_OP_MUNMAP: usize = 1; +pub const ADDRSPACE_OP_MPROTECT: usize = 2; +pub const ADDRSPACE_OP_TRANSFER: usize = 3; + /// True if status indicates the child is stopped. pub fn wifstopped(status: usize) -> bool { (status & 0xff) == 0x7f diff --git a/src/io/dma.rs b/src/io/dma.rs index b356c8a..f496a1e 100644 --- a/src/io/dma.rs +++ b/src/io/dma.rs @@ -4,6 +4,7 @@ use core::{ptr, slice}; use crate::Result; use crate::{PartialAllocStrategy, PhysallocFlags}; +use crate::arch::PAGE_SIZE; /// An RAII guard of a physical memory allocation. Currently all physically allocated memory are /// page-aligned and take up at least 4k of space (on x86_64). @@ -13,12 +14,23 @@ pub struct PhysBox { size: usize } +const fn round_up(x: usize) -> usize { + (x + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE +} +fn assert_aligned(x: usize) { + assert_eq!(x % PAGE_SIZE, 0); +} + impl PhysBox { - /// Construct a PhysBox from an address and a size. + /// Construct a PhysBox from an address and a size. The address must be page-aligned, and the + /// size must similarly be a multiple of the page size. /// /// # Safety /// This function is unsafe because when dropping, Self has to a valid allocation. pub unsafe fn from_raw_parts(address: usize, size: usize) -> Self { + assert_aligned(address); + assert_aligned(size); + Self { address, size, @@ -42,12 +54,10 @@ impl PhysBox { pub fn new_with_flags(size: usize, flags: PhysallocFlags) -> Result { assert!(!flags.contains(PhysallocFlags::PARTIAL_ALLOC)); + assert_aligned(size); let address = unsafe { crate::physalloc2(size, flags.bits())? }; - Ok(Self { - address, - size, - }) + Ok(unsafe { Self::from_raw_parts(address, size) }) } /// "Partially" allocate physical memory, in the sense that the allocation may be smaller than @@ -57,21 +67,18 @@ impl PhysBox { /// that first allocation only returns half the size, the driver can do another allocation /// and then let the device use both buffers. pub fn new_partial_allocation(size: usize, flags: PhysallocFlags, strategy: Option, mut min: usize) -> Result { + assert_aligned(size); debug_assert!(!(flags.contains(PhysallocFlags::PARTIAL_ALLOC) && strategy.is_none())); - let address = unsafe { crate::physalloc3(size, flags.bits() | strategy.map(|s| s as usize).unwrap_or(0), &mut min)? }; - Ok(Self { - address, - size: min, - }) + let address = unsafe { crate::physalloc3(size, flags.bits() | strategy.map_or(0, |s| s as usize), &mut min)? }; + Ok(unsafe { Self::from_raw_parts(address, size) }) } pub fn new(size: usize) -> Result { + assert_aligned(size); + let address = unsafe { crate::physalloc(size)? }; - Ok(Self { - address, - size, - }) + Ok(unsafe { Self::from_raw_parts(address, size) }) } } @@ -111,11 +118,11 @@ impl Dma { } pub fn new(value: T) -> Result { - let phys = PhysBox::new(mem::size_of::())?; + let phys = PhysBox::new(round_up(mem::size_of::()))?; Self::from_physbox(phys, value) } pub fn zeroed() -> Result>> { - let phys = PhysBox::new(mem::size_of::())?; + let phys = PhysBox::new(round_up(mem::size_of::()))?; Self::from_physbox_zeroed(phys) } } @@ -163,7 +170,7 @@ impl Dma<[T]> { /// * `T` must be properly aligned. /// * `T` must be valid as zeroed (i.e. no NonNull pointers). pub unsafe fn zeroed_unsized(count: usize) -> Result { - let phys = PhysBox::new(mem::size_of::() * count)?; + let phys = PhysBox::new(round_up(mem::size_of::() * count))?; Ok(Self::from_physbox_zeroed_unsized(phys, count)?.assume_init()) } } @@ -195,6 +202,6 @@ impl DerefMut for Dma { impl Drop for Dma { fn drop(&mut self) { unsafe { ptr::drop_in_place(self.virt) } - let _ = unsafe { crate::physunmap(self.virt as *mut u8 as usize) }; + let _ = unsafe { crate::funmap(self.virt as *mut u8 as usize, self.phys.size) }; } } diff --git a/src/lib.rs b/src/lib.rs index 9c59398..3f6d884 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,6 @@ extern crate core; pub use self::arch::*; pub use self::call::*; -pub use self::daemon::*; pub use self::data::*; pub use self::error::*; pub use self::flag::*; @@ -43,9 +42,6 @@ pub mod call; /// Complex structures that are used for some system calls pub mod data; -/// Wrapper to make daemons easier to write -pub mod daemon; - /// All errors that can be generated by a system call pub mod error; diff --git a/src/number.rs b/src/number.rs index 1f037eb..a35f469 100644 --- a/src/number.rs +++ b/src/number.rs @@ -26,7 +26,6 @@ pub const SYS_FCHMOD: usize = SYS_CLASS_FILE | 94; pub const SYS_FCHOWN: usize = SYS_CLASS_FILE | 207; pub const SYS_FCNTL: usize = SYS_CLASS_FILE | 55; pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927; -pub const SYS_FEXEC: usize = SYS_CLASS_FILE | 11; pub const SYS_FMAP_OLD: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 90; pub const SYS_FMAP: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 900; pub const SYS_FUNMAP_OLD: usize = SYS_CLASS_FILE | 91; @@ -41,7 +40,6 @@ pub const SYS_FUTIMENS: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 320; pub const SYS_CHDIR: usize = 12; pub const SYS_CLOCK_GETTIME: usize = 265; -pub const SYS_CLONE: usize = 120; pub const SYS_EXIT: usize = 1; pub const SYS_FUTEX: usize = 240; pub const SYS_GETCWD: usize = 183;