Implement bidirectional SYS_CALL support

This commit is contained in:
Jacob Lorentzon
2025-03-03 23:21:56 +00:00
committed by Jeremy Soller
parent 8f24d894eb
commit 4607576006
7 changed files with 118 additions and 49 deletions
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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),
+6
View File
@@ -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