From 538ca49ee2de79c0f53b29782754778210671a9f Mon Sep 17 00:00:00 2001 From: jD91mZM2 <me@krake.one> Date: Fri, 26 Jul 2019 12:23:21 +0200 Subject: [PATCH] Suggestion: Switch to bitflags --- Cargo.lock | 3 +++ src/context/context.rs | 4 ++-- src/event.rs | 23 +++++++++---------- src/ptrace.rs | 28 +++++++++++------------ src/scheme/debug.rs | 6 ++--- src/scheme/irq.rs | 6 ++--- src/scheme/itimer.rs | 6 ++--- src/scheme/memory.rs | 8 +++---- src/scheme/pipe.rs | 6 ++--- src/scheme/proc.rs | 11 +++++----- src/scheme/root.rs | 4 ++-- src/scheme/time.rs | 6 ++--- src/scheme/user.rs | 20 ++++++++--------- src/syscall/driver.rs | 12 +++++----- src/syscall/fs.rs | 4 ++-- src/syscall/mod.rs | 10 +++++---- src/syscall/process.rs | 50 +++++++++++++++++++++--------------------- syscall | 2 +- 18 files changed, 108 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48faff9c..a9cc12c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -278,6 +278,9 @@ dependencies = [ [[package]] name = "redox_syscall" version = "0.1.56" +dependencies = [ + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "regex" diff --git a/src/context/context.rs b/src/context/context.rs index 0a0f1869..216726e5 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -16,7 +16,7 @@ use crate::ipi::{ipi, IpiKind, IpiTarget}; use crate::scheme::{SchemeNamespace, FileHandle}; use crate::sync::WaitMap; use crate::syscall::data::SigAction; -use crate::syscall::flag::SIG_DFL; +use crate::syscall::flag::{SIG_DFL, SigActionFlags}; /// Unique identifier for a context (i.e. `pid`). use ::core::sync::atomic::AtomicUsize; @@ -222,7 +222,7 @@ impl Context { SigAction { sa_handler: unsafe { mem::transmute(SIG_DFL) }, sa_mask: [0; 2], - sa_flags: 0, + sa_flags: SigActionFlags::empty(), }, 0 ); 128])), diff --git a/src/event.rs b/src/event.rs index 7a7d25e0..4eba3be2 100644 --- a/src/event.rs +++ b/src/event.rs @@ -8,6 +8,7 @@ use crate::scheme::{self, SchemeId}; use crate::sync::WaitQueue; use crate::syscall::data::Event; use crate::syscall::error::{Error, Result, EBADF, EINTR, ESRCH}; +use crate::syscall::flag::EventFlags; int_like!(EventQueueId, AtomicEventQueueId, usize, AtomicUsize); @@ -53,7 +54,7 @@ impl EventQueue { ); let flags = sync(RegKey { scheme, number })?; - if flags > 0 { + if !flags.is_empty() { trigger(scheme, number, flags); } } @@ -100,10 +101,10 @@ pub struct RegKey { pub struct QueueKey { pub queue: EventQueueId, pub id: usize, - pub data: usize + pub data: usize, } -type Registry = BTreeMap<RegKey, BTreeMap<QueueKey, usize>>; +type Registry = BTreeMap<RegKey, BTreeMap<QueueKey, EventFlags>>; static REGISTRY: Once<RwLock<Registry>> = Once::new(); @@ -122,28 +123,28 @@ pub fn registry_mut() -> RwLockWriteGuard<'static, Registry> { REGISTRY.call_once(init_registry).write() } -pub fn register(reg_key: RegKey, queue_key: QueueKey, flags: usize) { +pub fn register(reg_key: RegKey, queue_key: QueueKey, flags: EventFlags) { let mut registry = registry_mut(); let entry = registry.entry(reg_key).or_insert_with(|| { BTreeMap::new() }); - if flags == 0 { + if flags.is_empty() { entry.remove(&queue_key); } else { entry.insert(queue_key, flags); } } -pub fn sync(reg_key: RegKey) -> Result<usize> { - let mut flags = 0; +pub fn sync(reg_key: RegKey) -> Result<EventFlags> { + let mut flags = EventFlags::empty(); { let registry = registry(); if let Some(queue_list) = registry.get(®_key) { - for (_queue_key, queue_flags) in queue_list.iter() { + for (_queue_key, &queue_flags) in queue_list.iter() { flags |= queue_flags; } } @@ -169,13 +170,13 @@ pub fn unregister_file(scheme: SchemeId, number: usize) { // // } -pub fn trigger(scheme: SchemeId, number: usize, flags: usize) { +pub fn trigger(scheme: SchemeId, number: usize, flags: EventFlags) { let registry = registry(); if let Some(queue_list) = registry.get(&RegKey { scheme, number }) { - for (queue_key, queue_flags) in queue_list.iter() { + for (queue_key, &queue_flags) in queue_list.iter() { let common_flags = flags & queue_flags; - if common_flags != 0 { + if !common_flags.is_empty() { let queues = queues(); if let Some(queue) = queues.get(&queue_key.queue) { queue.queue.send(Event { diff --git a/src/ptrace.rs b/src/ptrace.rs index 0bf8bf78..0de6b055 100644 --- a/src/ptrace.rs +++ b/src/ptrace.rs @@ -16,7 +16,13 @@ use crate::{ context::{self, signal, Context, ContextId, Status}, event, scheme::proc, - sync::WaitCondition + sync::WaitCondition, + syscall::{ + data::PtraceEvent, + error::*, + flag::*, + ptrace_event + }, }; use alloc::{ @@ -34,12 +40,6 @@ use core::{ sync::atomic::Ordering }; use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; -use syscall::{ - data::PtraceEvent, - error::*, - flag::*, - ptrace_event -}; // ____ _ // / ___| ___ ___ ___(_) ___ _ __ ___ @@ -96,10 +96,10 @@ pub fn is_traced(pid: ContextId) -> bool { } /// Used for getting the flags in fevent -pub fn session_fevent_flags(pid: ContextId) -> Option<usize> { +pub fn session_fevent_flags(pid: ContextId) -> Option<EventFlags> { let sessions = sessions(); let session = sessions.get(&pid)?; - let mut flags = 0; + let mut flags = EventFlags::empty(); if !session.events.is_empty() { flags |= EVENT_READ; } @@ -119,7 +119,7 @@ pub fn close_session(pid: ContextId) { } /// Trigger a notification to the event: scheme -fn proc_trigger_event(file_id: usize, flags: usize) { +fn proc_trigger_event(file_id: usize, flags: EventFlags) { event::trigger(proc::PROC_SCHEME_ID.load(Ordering::SeqCst), file_id, flags); } @@ -175,7 +175,7 @@ pub fn recv_events(pid: ContextId, out: &mut [PtraceEvent]) -> Option<usize> { #[derive(Debug)] struct Breakpoint { reached: bool, - flags: u64 + flags: PtraceFlags } /// Continue the process with the specified ID @@ -195,7 +195,7 @@ pub fn cont(pid: ContextId) { /// Create a new breakpoint for the specified tracee, optionally with /// a sysemu flag. Panics if the session is invalid. -pub fn set_breakpoint(pid: ContextId, flags: u64) { +pub fn set_breakpoint(pid: ContextId, flags: PtraceFlags) { let mut sessions = sessions_mut(); let session = sessions.get_mut(&pid).expect("proc (set_breakpoint): invalid session"); session.breakpoint = Some(Breakpoint { @@ -246,7 +246,7 @@ pub fn wait(pid: ContextId) -> Result<Option<PtraceEvent>> { /// Notify the tracer and await green flag to continue. /// Note: Don't call while holding any locks, this will switch contexts -pub fn breakpoint_callback(match_flags: u64, event: Option<PtraceEvent>) -> Option<u64> { +pub fn breakpoint_callback(match_flags: PtraceFlags, event: Option<PtraceEvent>) -> Option<PtraceFlags> { // Can't hold any locks when executing wait() let (tracee, flags) = { let contexts = context::contexts(); @@ -289,7 +289,7 @@ pub fn breakpoint_callback(match_flags: u64, event: Option<PtraceEvent>) -> Opti /// Obtain the next breakpoint flags for the current process. This is /// used for detecting whether or not the tracer decided to use sysemu /// mode. -pub fn next_breakpoint() -> Option<u64> { +pub fn next_breakpoint() -> Option<PtraceFlags> { let contexts = context::contexts(); let context = contexts.current()?; let context = context.read(); diff --git a/src/scheme/debug.rs b/src/scheme/debug.rs index 4ec00e5a..abcb60c0 100644 --- a/src/scheme/debug.rs +++ b/src/scheme/debug.rs @@ -5,7 +5,7 @@ use crate::arch::debug::Writer; use crate::event; use crate::scheme::*; use crate::sync::WaitQueue; -use crate::syscall::flag::{EVENT_READ, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK}; +use crate::syscall::flag::{EventFlags, EVENT_READ, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK}; use crate::syscall::scheme::Scheme; pub static DEBUG_SCHEME_ID: AtomicSchemeId = ATOMIC_SCHEMEID_INIT; @@ -102,13 +102,13 @@ impl Scheme for DebugScheme { } } - fn fevent(&self, id: usize, _flags: usize) -> Result<usize> { + fn fevent(&self, id: usize, _flags: EventFlags) -> Result<EventFlags> { let _flags = { let handles = handles(); *handles.get(&id).ok_or(Error::new(EBADF))? }; - Ok(0) + Ok(EventFlags::empty()) } fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> { diff --git a/src/scheme/irq.rs b/src/scheme/irq.rs index eb51768b..f7a4e373 100644 --- a/src/scheme/irq.rs +++ b/src/scheme/irq.rs @@ -6,7 +6,7 @@ use crate::event; use crate::interrupt::irq::acknowledge; use crate::scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId}; use crate::syscall::error::*; -use crate::syscall::flag::EVENT_READ; +use crate::syscall::flag::{EventFlags, EVENT_READ}; use crate::syscall::scheme::Scheme; pub static IRQ_SCHEME_ID: AtomicSchemeId = ATOMIC_SCHEMEID_INIT; @@ -87,8 +87,8 @@ impl Scheme for IrqScheme { Ok(0) } - fn fevent(&self, _id: usize, _flags: usize) -> Result<usize> { - Ok(0) + fn fevent(&self, _id: usize, _flags: EventFlags) -> Result<EventFlags> { + Ok(EventFlags::empty()) } fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> { diff --git a/src/scheme/itimer.rs b/src/scheme/itimer.rs index 3a91c3a2..92ca1ab0 100644 --- a/src/scheme/itimer.rs +++ b/src/scheme/itimer.rs @@ -5,7 +5,7 @@ use spin::RwLock; use crate::syscall::data::ITimerSpec; use crate::syscall::error::*; -use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC}; +use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC, EventFlags}; use crate::syscall::scheme::Scheme; pub struct ITimerScheme { @@ -79,9 +79,9 @@ impl Scheme for ITimerScheme { Ok(0) } - fn fevent(&self, id: usize, _flags: usize) -> Result<usize> { + fn fevent(&self, id: usize, _flags: EventFlags) -> Result<EventFlags> { let handles = self.handles.read(); - handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0)) + handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(EventFlags::empty())) } fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> { diff --git a/src/scheme/memory.rs b/src/scheme/memory.rs index fd14ab31..b837f56b 100644 --- a/src/scheme/memory.rs +++ b/src/scheme/memory.rs @@ -5,7 +5,7 @@ use crate::paging::VirtualAddress; use crate::paging::entry::EntryFlags; use crate::syscall::data::{Map, StatVfs}; use crate::syscall::error::*; -use crate::syscall::flag::{PROT_EXEC, PROT_READ, PROT_WRITE}; +use crate::syscall::flag::{ProtFlags, PROT_EXEC, PROT_READ, PROT_WRITE}; use crate::syscall::scheme::Scheme; pub struct MemoryScheme; @@ -47,13 +47,13 @@ impl Scheme for MemoryScheme { let mut to_address = crate::USER_GRANT_OFFSET; let mut entry_flags = EntryFlags::PRESENT | EntryFlags::USER_ACCESSIBLE; - if map.flags & PROT_EXEC == 0 { + if map.flags & PROT_EXEC == ProtFlags::empty() { entry_flags |= EntryFlags::NO_EXECUTE; } - if map.flags & PROT_READ > 0 { + if map.flags & PROT_READ != ProtFlags::empty() { //TODO: PROT_READ } - if map.flags & PROT_WRITE > 0 { + if map.flags & PROT_WRITE != ProtFlags::empty() { entry_flags |= EntryFlags::WRITABLE; } diff --git a/src/scheme/pipe.rs b/src/scheme/pipe.rs index 7c02c077..bfc52321 100644 --- a/src/scheme/pipe.rs +++ b/src/scheme/pipe.rs @@ -7,7 +7,7 @@ use crate::event; use crate::scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId}; use crate::sync::WaitCondition; use crate::syscall::error::{Error, Result, EAGAIN, EBADF, EINTR, EINVAL, EPIPE, ESPIPE}; -use crate::syscall::flag::{EVENT_READ, EVENT_WRITE, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK, MODE_FIFO}; +use crate::syscall::flag::{EventFlags, EVENT_READ, EVENT_WRITE, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK, MODE_FIFO}; use crate::syscall::scheme::Scheme; use crate::syscall::data::Stat; @@ -87,14 +87,14 @@ impl Scheme for PipeScheme { Err(Error::new(EBADF)) } - fn fevent(&self, id: usize, flags: usize) -> Result<usize> { + fn fevent(&self, id: usize, flags: EventFlags) -> Result<EventFlags> { let pipes = pipes(); if let Some(pipe) = pipes.0.get(&id) { if flags == EVENT_READ { // TODO: Return correct flags if pipe.vec.lock().is_empty() { - return Ok(0); + return Ok(EventFlags::empty()); } else { return Ok(EVENT_READ); } diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index fe76c3e9..57d06e0f 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -418,15 +418,16 @@ impl Scheme for ProcScheme { let len = bytes.len(); bytes.copy_from_slice(&buf[0..len]); let op = u64::from_ne_bytes(bytes); + let op = PtraceFlags::from_bits(op).ok_or(Error::new(EINVAL))?; - if op & PTRACE_FLAG_WAIT != PTRACE_FLAG_WAIT || op & PTRACE_STOP_MASK != 0 { + if !op.contains(PTRACE_FLAG_WAIT) || op.intersects(PTRACE_STOP_MASK) { ptrace::cont(info.pid); } - if op & PTRACE_STOP_MASK != 0 { + if op.intersects(PTRACE_STOP_MASK) { ptrace::set_breakpoint(info.pid, op); } - if op & PTRACE_STOP_SINGLESTEP == PTRACE_STOP_SINGLESTEP { + if op.contains(PTRACE_STOP_SINGLESTEP) { // try_stop_context with `false` will // automatically disable ptrace_stop try_stop_context(info.pid, false, |context| { @@ -452,7 +453,7 @@ impl Scheme for ProcScheme { })?; } - if op & PTRACE_FLAG_WAIT == PTRACE_FLAG_WAIT || info.flags & O_NONBLOCK != O_NONBLOCK { + if op.contains(PTRACE_FLAG_WAIT) || info.flags & O_NONBLOCK != O_NONBLOCK { if let Some(event) = ptrace::wait(info.pid)? { if event.cause == PTRACE_EVENT_CLONE { clones.push(ContextId::from(event.a)); @@ -477,7 +478,7 @@ impl Scheme for ProcScheme { } } - fn fevent(&self, id: usize, _flags: usize) -> Result<usize> { + fn fevent(&self, id: usize, _flags: EventFlags) -> Result<EventFlags> { let handles = self.handles.read(); let handle = handles.get(&id).ok_or(Error::new(EBADF))?; let handle = handle.lock(); diff --git a/src/scheme/root.rs b/src/scheme/root.rs index 13f90891..c4315cd4 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -9,7 +9,7 @@ use spin::{Mutex, RwLock}; use crate::context; use crate::syscall::data::Stat; use crate::syscall::error::*; -use crate::syscall::flag::{O_CREAT, MODE_FILE, MODE_DIR, SEEK_SET, SEEK_CUR, SEEK_END}; +use crate::syscall::flag::{EventFlags, O_CREAT, MODE_FILE, MODE_DIR, SEEK_SET, SEEK_CUR, SEEK_END}; use crate::syscall::scheme::Scheme; use crate::scheme::{self, SchemeNamespace, SchemeId}; use crate::scheme::user::{UserInner, UserScheme}; @@ -226,7 +226,7 @@ impl Scheme for RootScheme { } } - fn fevent(&self, file: usize, flags: usize) -> Result<usize> { + fn fevent(&self, file: usize, flags: EventFlags) -> Result<EventFlags> { let handle = { let handles = self.handles.read(); let handle = handles.get(&file).ok_or(Error::new(EBADF))?; diff --git a/src/scheme/time.rs b/src/scheme/time.rs index 8b340fb4..718d14dc 100644 --- a/src/scheme/time.rs +++ b/src/scheme/time.rs @@ -7,7 +7,7 @@ use crate::context::timeout; use crate::scheme::SchemeId; use crate::syscall::data::TimeSpec; use crate::syscall::error::*; -use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC}; +use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC, EventFlags}; use crate::syscall::scheme::Scheme; use crate::time; @@ -90,9 +90,9 @@ impl Scheme for TimeScheme { Ok(0) } - fn fevent(&self, id: usize, _flags: usize) -> Result<usize> { + fn fevent(&self, id: usize, _flags: EventFlags) -> Result<EventFlags> { let handles = self.handles.read(); - handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0)) + handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(EventFlags::empty())) } fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> { diff --git a/src/scheme/user.rs b/src/scheme/user.rs index 11a86200..547c123d 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -16,7 +16,7 @@ use crate::scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId}; use crate::sync::{WaitQueue, WaitMap}; use crate::syscall::data::{Map, Packet, Stat, StatVfs, TimeSpec}; use crate::syscall::error::*; -use crate::syscall::flag::{EVENT_READ, O_NONBLOCK, PROT_EXEC, PROT_READ, PROT_WRITE}; +use crate::syscall::flag::{EventFlags, EVENT_READ, O_NONBLOCK, ProtFlags, PROT_EXEC, PROT_READ, PROT_WRITE}; use crate::syscall::number::*; use crate::syscall::scheme::Scheme; @@ -108,7 +108,7 @@ impl UserInner { UserInner::capture_inner(&self.context, buf.as_mut_ptr() as usize, buf.len(), PROT_WRITE, None) } - fn capture_inner(context_weak: &Weak<RwLock<Context>>, address: usize, size: usize, flags: usize, desc_opt: Option<FileDescriptor>) -> Result<usize> { + fn capture_inner(context_weak: &Weak<RwLock<Context>>, address: usize, size: usize, flags: ProtFlags, desc_opt: Option<FileDescriptor>) -> Result<usize> { //TODO: Abstract with other grant creation if size == 0 { Ok(0) @@ -127,13 +127,13 @@ impl UserInner { let mut to_address = crate::USER_GRANT_OFFSET; let mut entry_flags = EntryFlags::PRESENT | EntryFlags::USER_ACCESSIBLE; - if flags & PROT_EXEC == 0 { + if !flags.contains(PROT_EXEC) { entry_flags |= EntryFlags::NO_EXECUTE; } - if flags & PROT_READ > 0 { + if flags.contains(PROT_READ) { //TODO: PROT_READ } - if flags & PROT_WRITE > 0 { + if flags.contains(PROT_WRITE) { entry_flags |= EntryFlags::WRITABLE; } @@ -232,7 +232,7 @@ impl UserInner { let mut packet = unsafe { *(buf.as_ptr() as *const Packet).offset(i as isize) }; if packet.id == 0 { match packet.a { - SYS_FEVENT => event::trigger(self.scheme_id.load(Ordering::SeqCst), packet.b, packet.c), + SYS_FEVENT => event::trigger(self.scheme_id.load(Ordering::SeqCst), packet.b, EventFlags::from_bits_truncate(packet.c)), _ => println!("Unknown scheme -> kernel message {}", packet.a) } } else { @@ -257,8 +257,8 @@ impl UserInner { Ok(i * packet_size) } - pub fn fevent(&self, _flags: usize) -> Result<usize> { - Ok(0) + pub fn fevent(&self, _flags: EventFlags) -> Result<EventFlags> { + Ok(EventFlags::empty()) } pub fn fsync(&self) -> Result<usize> { @@ -356,9 +356,9 @@ impl Scheme for UserScheme { inner.call(SYS_FCNTL, file, cmd, arg) } - fn fevent(&self, file: usize, flags: usize) -> Result<usize> { + fn fevent(&self, file: usize, flags: EventFlags) -> Result<EventFlags> { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; - inner.call(SYS_FEVENT, file, flags, 0) + inner.call(SYS_FEVENT, file, flags.bits(), 0).map(EventFlags::from_bits_truncate) } fn fmap(&self, file: usize, map: &Map) -> Result<usize> { diff --git a/src/syscall/driver.rs b/src/syscall/driver.rs index 1ab0a4cb..e1655fdb 100644 --- a/src/syscall/driver.rs +++ b/src/syscall/driver.rs @@ -5,7 +5,7 @@ use crate::paging::entry::EntryFlags; use crate::context; use crate::context::memory::Grant; use crate::syscall::error::{Error, EFAULT, EINVAL, ENOMEM, EPERM, ESRCH, Result}; -use crate::syscall::flag::{PHYSMAP_WRITE, PHYSMAP_WRITE_COMBINE, PHYSMAP_NO_CACHE}; +use crate::syscall::flag::{PhysmapFlags, PHYSMAP_WRITE, PHYSMAP_WRITE_COMBINE, PHYSMAP_NO_CACHE}; fn enforce_root() -> Result<()> { let contexts = context::contexts(); @@ -50,7 +50,7 @@ pub fn physfree(physical_address: usize, size: usize) -> Result<usize> { } //TODO: verify exlusive access to physical memory -pub fn inner_physmap(physical_address: usize, size: usize, flags: usize) -> Result<usize> { +pub fn inner_physmap(physical_address: usize, size: usize, flags: PhysmapFlags) -> Result<usize> { //TODO: Abstract with other grant creation if size == 0 { Ok(0) @@ -67,13 +67,13 @@ pub fn inner_physmap(physical_address: usize, size: usize, flags: usize) -> Resu let mut to_address = crate::USER_GRANT_OFFSET; let mut entry_flags = EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::USER_ACCESSIBLE; - if flags & PHYSMAP_WRITE == PHYSMAP_WRITE { + if flags.contains(PHYSMAP_WRITE) { entry_flags |= EntryFlags::WRITABLE; } - if flags & PHYSMAP_WRITE_COMBINE == PHYSMAP_WRITE_COMBINE { + if flags.contains(PHYSMAP_WRITE_COMBINE) { entry_flags |= EntryFlags::HUGE_PAGE; } - if flags & PHYSMAP_NO_CACHE == PHYSMAP_NO_CACHE { + if flags.contains(PHYSMAP_NO_CACHE) { entry_flags |= EntryFlags::NO_CACHE; } @@ -100,7 +100,7 @@ pub fn inner_physmap(physical_address: usize, size: usize, flags: usize) -> Resu Ok(to_address + offset) } } -pub fn physmap(physical_address: usize, size: usize, flags: usize) -> Result<usize> { +pub fn physmap(physical_address: usize, size: usize, flags: PhysmapFlags) -> Result<usize> { enforce_root()?; inner_physmap(physical_address, size, flags) } diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 1746d77a..c4bcc6c9 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -8,7 +8,7 @@ use crate::scheme::{self, FileHandle}; use crate::syscall; use crate::syscall::data::{Packet, Stat}; use crate::syscall::error::*; -use crate::syscall::flag::{F_GETFD, F_SETFD, F_GETFL, F_SETFL, F_DUPFD, O_ACCMODE, O_DIRECTORY, O_RDONLY, O_SYMLINK, O_WRONLY, MODE_DIR, MODE_FILE, O_CLOEXEC}; +use crate::syscall::flag::*; use crate::context::file::{FileDescriptor, FileDescription}; pub fn file_op(a: usize, fd: FileHandle, c: usize, d: usize) -> Result<usize> { @@ -92,7 +92,7 @@ pub fn open(path: &[u8], flags: usize) -> Result<FileHandle> { (context.canonicalize(path), context.euid, context.egid, context.ens, context.umask) }; - let flags = (flags & (!0o777)) | (flags & 0o777) & (!(umask & 0o777)); + let flags = (flags & (!0o777)) | ((flags & 0o777) & (!(umask & 0o777))); //println!("open {}", unsafe { ::core::str::from_utf8_unchecked(&path_canon) }); diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index 33ac677a..50cacdcb 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -16,6 +16,7 @@ pub use self::validate::*; use self::data::{SigAction, TimeSpec}; use self::error::{Error, Result, ENOSYS}; +use self::flag::{CloneFlags, PhysmapFlags, ProtFlags, WaitFlags}; use self::number::*; use crate::context::ContextId; @@ -94,8 +95,9 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u SYS_GETPGID => getpgid(ContextId::from(b)).map(ContextId::into), SYS_GETPPID => getppid().map(ContextId::into), SYS_CLONE => { + let b = CloneFlags::from_bits_truncate(b); let old_rsp = stack.iret.rsp; - if b & flag::CLONE_STACK == flag::CLONE_STACK { + if b.contains(flag::CLONE_STACK) { stack.iret.rsp = c; } let ret = clone(b, bp).map(ContextId::into); @@ -104,7 +106,7 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u }, SYS_EXIT => exit((b & 0xFF) << 8), SYS_KILL => kill(ContextId::from(b), c), - SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into), + SYS_WAITPID => waitpid(ContextId::from(b), c, WaitFlags::from_bits_truncate(d)).map(ContextId::into), SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?), SYS_IOPL => iopl(b, stack), SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), @@ -114,7 +116,7 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u SYS_GETGID => getgid(), SYS_GETNS => getns(), SYS_GETUID => getuid(), - SYS_MPROTECT => mprotect(b, c, d), + SYS_MPROTECT => mprotect(b, c, ProtFlags::from_bits_truncate(d)), SYS_MKNS => mkns(validate_slice(b as *const [usize; 2], c)?), SYS_SETPGID => setpgid(ContextId::from(b), ContextId::from(c)), SYS_SETREUID => setreuid(b as u32, c as u32), @@ -151,7 +153,7 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u SYS_PIPE2 => pipe2(validate_slice_mut(b as *mut usize, 2)?, c), SYS_PHYSALLOC => physalloc(b), SYS_PHYSFREE => physfree(b, c), - SYS_PHYSMAP => physmap(b, c, d), + SYS_PHYSMAP => physmap(b, c, PhysmapFlags::from_bits_truncate(d)), SYS_PHYSUNMAP => physunmap(b), SYS_UMASK => umask(b), SYS_VIRTTOPHYS => virttophys(b), diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 9c9aa268..4f80b775 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -23,10 +23,10 @@ use crate::scheme::FileHandle; use crate::start::usermode; use crate::syscall::data::{PtraceEvent, SigAction, Stat}; use crate::syscall::error::*; -use crate::syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, CLONE_STACK, - PROT_EXEC, PROT_READ, PROT_WRITE, PTRACE_EVENT_CLONE, - SIG_DFL, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK, SIGCONT, SIGTERM, - WCONTINUED, WNOHANG, WUNTRACED, wifcontinued, wifstopped}; +use crate::syscall::flag::{CloneFlags, CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, + CLONE_STACK, ProtFlags, PROT_EXEC, PROT_READ, PROT_WRITE, PTRACE_EVENT_CLONE, + SigActionFlags, SIG_DFL, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK, SIGCONT, SIGTERM, + WaitFlags, WCONTINUED, WNOHANG, WUNTRACED, wifcontinued, wifstopped}; use crate::syscall::ptrace_event; use crate::syscall::validate::{validate_slice, validate_slice_mut}; @@ -67,7 +67,7 @@ pub fn brk(address: usize) -> Result<usize> { } } -pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { +pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> { let ppid; let pid; { @@ -114,7 +114,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { sigmask = context.sigmask; umask = context.umask; - if flags & CLONE_VM == CLONE_VM { + if flags.contains(CLONE_VM) { cpu_id = context.cpu_id; } @@ -155,7 +155,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { kstack_option = Some(new_stack); } - if flags & CLONE_VM == CLONE_VM { + if flags.contains(CLONE_VM) { for memory_shared in context.image.iter() { image.push(memory_shared.clone()); } @@ -206,7 +206,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { } if let Some(ref stack_shared) = context.stack { - if flags & CLONE_STACK == CLONE_STACK { + if flags.contains(CLONE_STACK) { stack_option = Some(stack_shared.clone()); } else { stack_shared.with(|stack| { @@ -261,7 +261,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { }; - if flags & CLONE_VM == CLONE_VM { + if flags.contains(CLONE_VM) { unsafe { new_tls.load(); } @@ -277,7 +277,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { tls_option = Some(new_tls); } - if flags & CLONE_VM == CLONE_VM { + if flags.contains(CLONE_VM) { grants = Arc::clone(&context.grants); } else { let mut grants_vec = Vec::new(); @@ -288,25 +288,25 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { grants = Arc::new(Mutex::new(grants_vec)); } - if flags & CLONE_VM == CLONE_VM { + if flags.contains(CLONE_VM) { name = Arc::clone(&context.name); } else { name = Arc::new(Mutex::new(context.name.lock().clone())); } - if flags & CLONE_FS == CLONE_FS { + if flags.contains(CLONE_FS) { cwd = Arc::clone(&context.cwd); } else { cwd = Arc::new(Mutex::new(context.cwd.lock().clone())); } - if flags & CLONE_FILES == CLONE_FILES { + if flags.contains(CLONE_FILES) { files = Arc::clone(&context.files); } else { files = Arc::new(Mutex::new(context.files.lock().clone())); } - if flags & CLONE_SIGHAND == CLONE_SIGHAND { + if flags.contains(CLONE_SIGHAND) { actions = Arc::clone(&context.actions); } else { actions = Arc::new(Mutex::new(context.actions.lock().clone())); @@ -315,7 +315,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { // If not cloning files, dup to get a new number from scheme // This has to be done outside the context lock to prevent deadlocks - if flags & CLONE_FILES == 0 { + if !flags.contains(CLONE_FILES) { for (_fd, file_option) in files.lock().iter_mut().enumerate() { let new_file_option = if let Some(ref file) = *file_option { Some(FileDescriptor { @@ -331,7 +331,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { } // If not cloning virtual memory, use fmap to re-obtain every grant where possible - if flags & CLONE_VM == 0 { + if !flags.contains(CLONE_VM) { let mut i = 0; while i < grants.lock().len() { let remove = false; @@ -350,7 +350,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { // If vfork, block the current process // This has to be done after the operations that may require context switches - if flags & CLONE_VFORK == CLONE_VFORK { + if flags.contains(CLONE_VFORK) { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let mut context = context_lock.write(); @@ -430,7 +430,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { // TODO: Clone ksig? // Setup image, heap, and grants - if flags & CLONE_VM == CLONE_VM { + if flags.contains(CLONE_VM) { // Copy user image mapping, if found if ! image.is_empty() { let frame = active_table.p4()[crate::USER_PML4].pointed_frame().expect("user image not mapped"); @@ -514,7 +514,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> { // Setup user stack if let Some(stack_shared) = stack_option { - if flags & CLONE_STACK == CLONE_STACK { + if flags.contains(CLONE_STACK) { let frame = active_table.p4()[crate::USER_STACK_PML4].pointed_frame().expect("user stack not mapped"); let flags = active_table.p4()[crate::USER_STACK_PML4].flags(); active_table.with(&mut new_table, &mut temporary_page, |mapper| { @@ -853,7 +853,7 @@ fn fexec_noreturn( SigAction { sa_handler: unsafe { mem::transmute(SIG_DFL) }, sa_mask: [0; 2], - sa_flags: 0, + sa_flags: SigActionFlags::empty(), }, 0 ); 128])); @@ -1290,7 +1290,7 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> { } } -pub fn mprotect(address: usize, size: usize, flags: usize) -> Result<usize> { +pub fn mprotect(address: usize, size: usize, flags: ProtFlags) -> Result<usize> { println!("mprotect {:#X}, {}, {:#X}", address, size, flags); let end_offset = size.checked_sub(1).ok_or(Error::new(EFAULT))?; @@ -1304,19 +1304,19 @@ pub fn mprotect(address: usize, size: usize, flags: usize) -> Result<usize> { let end_page = Page::containing_address(VirtualAddress::new(end_address)); for page in Page::range_inclusive(start_page, end_page) { if let Some(mut page_flags) = active_table.translate_page_flags(page) { - if flags & PROT_EXEC > 0 { + if flags.contains(PROT_EXEC) { page_flags.remove(EntryFlags::NO_EXECUTE); } else { page_flags.insert(EntryFlags::NO_EXECUTE); } - if flags & PROT_WRITE > 0 { + if flags.contains(PROT_WRITE) { //TODO: Not allowing gain of write privileges } else { page_flags.remove(EntryFlags::WRITABLE); } - if flags & PROT_READ > 0 { + if flags.contains(PROT_READ) { //TODO: No flags for readable pages } else { //TODO: No flags for readable pages @@ -1468,7 +1468,7 @@ fn reap(pid: ContextId) -> Result<ContextId> { Ok(pid) } -pub fn waitpid(pid: ContextId, status_ptr: usize, flags: usize) -> Result<ContextId> { +pub fn waitpid(pid: ContextId, status_ptr: usize, flags: WaitFlags) -> Result<ContextId> { let (ppid, waitpid) = { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; diff --git a/syscall b/syscall index edf3c008..9a7bd554 160000 --- a/syscall +++ b/syscall @@ -1 +1 @@ -Subproject commit edf3c008dc0a68245a255945d9a70b02c71991a5 +Subproject commit 9a7bd554d57f78214b70f9f0fb0b961e20a6dff7 -- GitLab