Implement bidirectional SYS_CALL support
This commit is contained in:
committed by
Jeremy Soller
parent
8f24d894eb
commit
4607576006
@@ -145,6 +145,13 @@ pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -
|
||||
Ok(times)
|
||||
}),
|
||||
),
|
||||
SYS_CALL => format!(
|
||||
"call({b}, {c:x}+{d}, {:?}, {:0x?}",
|
||||
CallFlags::from_bits_retain(e & !0xff),
|
||||
// TODO: u64
|
||||
UserSlice::ro(f, (e & 0xff) * 8)
|
||||
.and_then(|buf| buf.usizes().collect::<Result<Vec<usize>>>()),
|
||||
),
|
||||
|
||||
SYS_CLOCK_GETTIME => format!("clock_gettime({}, {:?})", b, unsafe {
|
||||
read_struct::<TimeSpec>(c)
|
||||
|
||||
+20
-2
@@ -1,5 +1,5 @@
|
||||
//! Filesystem syscalls
|
||||
use core::num::NonZeroUsize;
|
||||
use core::{mem::size_of, num::NonZeroUsize};
|
||||
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use redox_path::RedoxPath;
|
||||
@@ -17,7 +17,7 @@ use crate::{
|
||||
syscall::{data::Stat, error::*, flag::*},
|
||||
};
|
||||
|
||||
use super::usercopy::{UserSlice, UserSliceRo, UserSliceWo};
|
||||
use super::usercopy::{UserSlice, UserSliceRo, UserSliceRw, UserSliceWo};
|
||||
|
||||
pub fn file_op_generic<T>(
|
||||
fd: FileHandle,
|
||||
@@ -248,6 +248,24 @@ pub fn dup2(fd: FileHandle, new_fd: FileHandle, buf: UserSliceRo) -> Result<File
|
||||
.ok_or(Error::new(EMFILE))
|
||||
}
|
||||
}
|
||||
pub fn call(
|
||||
fd: FileHandle,
|
||||
payload: UserSliceRw,
|
||||
flags: CallFlags,
|
||||
metadata: UserSliceRo,
|
||||
) -> Result<usize> {
|
||||
let mut meta = [0_u64; 3];
|
||||
|
||||
// TODO: bytemuck/plain
|
||||
let copied = metadata.copy_common_bytes_to_slice(unsafe {
|
||||
core::slice::from_raw_parts_mut(meta.as_mut_ptr().cast(), meta.len() * 8)
|
||||
})?;
|
||||
|
||||
file_op_generic(fd, |scheme, number| {
|
||||
scheme.kcall(number, payload, flags, &meta[..copied / 8])
|
||||
})
|
||||
}
|
||||
|
||||
pub fn sendfd(socket: FileHandle, fd: FileHandle, flags_raw: usize, arg: u64) -> Result<usize> {
|
||||
let requested_flags = SendFdFlags::from_bits(flags_raw).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
|
||||
+7
-1
@@ -6,7 +6,7 @@ extern crate syscall;
|
||||
|
||||
use core::mem::size_of;
|
||||
|
||||
use syscall::{dirent::DirentHeader, RtSigInfo, RwFlags, EINVAL, SIGKILL};
|
||||
use syscall::{dirent::DirentHeader, CallFlags, RtSigInfo, RwFlags, EINVAL, SIGKILL};
|
||||
|
||||
pub use self::syscall::{
|
||||
data, error, flag, io, number, ptrace_event, EnvRegisters, FloatRegisters, IntRegisters,
|
||||
@@ -174,6 +174,12 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> us
|
||||
}
|
||||
|
||||
SYS_CLOSE => close(fd).map(|()| 0),
|
||||
SYS_CALL => call(
|
||||
fd,
|
||||
UserSlice::rw(c, d)?,
|
||||
CallFlags::from_bits(e & !0xff).ok_or(Error::new(EINVAL))?,
|
||||
UserSlice::ro(f, (e & 0xff) * 8)?,
|
||||
),
|
||||
|
||||
SYS_OPEN => open(UserSlice::ro(b, c)?, d).map(FileHandle::into),
|
||||
SYS_RMDIR => rmdir(UserSlice::ro(b, c)?).map(|()| 0),
|
||||
|
||||
@@ -17,6 +17,7 @@ pub struct UserSlice<const READ: bool, const WRITE: bool> {
|
||||
}
|
||||
pub type UserSliceRo = UserSlice<true, false>;
|
||||
pub type UserSliceWo = UserSlice<false, true>;
|
||||
pub type UserSliceRw = UserSlice<true, true>;
|
||||
|
||||
impl<const READ: bool, const WRITE: bool> UserSlice<READ, WRITE> {
|
||||
pub fn empty() -> Self {
|
||||
@@ -207,6 +208,11 @@ impl UserSliceWo {
|
||||
Self::new(base, size)
|
||||
}
|
||||
}
|
||||
impl UserSliceRw {
|
||||
pub fn rw(base: usize, size: usize) -> Result<Self> {
|
||||
Self::new(base, size)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_kernel_mem(slice: &[u8]) -> bool {
|
||||
(slice.as_ptr() as usize) >= crate::USER_END_OFFSET
|
||||
|
||||
Reference in New Issue
Block a user