Skip to content

Commit

Permalink
Adds kern_writev for 11.00
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon committed May 11, 2024
1 parent 69da418 commit 77089be
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 1 deletion.
6 changes: 6 additions & 0 deletions korbis-1100/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

use self::file::File;
use self::thread::Thread;
use self::uio::Uio;
use core::ffi::{c_char, c_int};
use korbis::offset;
use korbis::uio::UioSeg;

mod file;
mod thread;
mod uio;

/// Implementation of [`korbis::Kernel`] for 11.00.
#[derive(Clone, Copy)]
Expand All @@ -16,6 +18,7 @@ pub struct Kernel(&'static [u8]);
impl korbis::Kernel for Kernel {
type File = File;
type Thread = Thread;
type Uio = Uio;

unsafe fn new(base: *const u8) -> Self {
Self(Self::get_mapped_elf(base))
Expand Down Expand Up @@ -50,4 +53,7 @@ impl korbis::Kernel for Kernel {

#[offset(0x416920)]
unsafe fn kern_close(self, td: *mut Self::Thread, fd: c_int) -> c_int;

#[offset(0xDD340)]
unsafe fn kern_writev(self, td: *mut Self::Thread, fd: c_int, auio: *mut Self::Uio) -> c_int;
}
54 changes: 54 additions & 0 deletions korbis-1100/src/uio.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::thread::Thread;
use crate::Kernel;
use core::ffi::c_int;
use korbis::uio::{IoVec, UioRw, UioSeg};

/// Implementation of [`korbis::uio::Uio`] for 11.00.
#[repr(C)]
pub struct Uio {
iov: *mut IoVec,
len: c_int,
off: isize,
res: isize,
seg: UioSeg,
op: UioRw,
td: *mut Thread,
}

impl korbis::uio::Uio for Uio {
type Kernel = Kernel;

unsafe fn new(
td: *mut Thread,
op: UioRw,
seg: UioSeg,
iov: *mut IoVec,
len: usize,
) -> Option<Self> {
// Check vec count.
if len > Self::vec_max() {
return None;
}

// Get total length.
let mut res = 0usize;

for i in 0..len {
res = res.checked_add((*iov.add(i)).len)?;
}

if res > Self::io_max() {
return None;
}

Some(Self {
iov,
len: len.try_into().unwrap(),
off: -1,
res: res.try_into().unwrap(),
seg,
op,
td,
})
}
}
8 changes: 7 additions & 1 deletion korbis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use self::elf::ProgramType;
use self::file::{File, OwnedFile};
use self::thread::Thread;
use self::uio::UioSeg;
use self::uio::{Uio, UioSeg};
use core::ffi::{c_char, c_int};
use core::num::NonZeroI32;
use core::ptr::null_mut;
Expand All @@ -23,6 +23,7 @@ pub mod uio;
pub trait Kernel: Copy + Send + Sync + 'static {
type File: File;
type Thread: Thread;
type Uio: Uio;

/// # Safety
/// `base` must point to a valid address of the kernel. Behavior is undefined if format of the
Expand Down Expand Up @@ -73,6 +74,11 @@ pub trait Kernel: Copy + Send + Sync + 'static {
/// `td` cannot be null.
unsafe fn kern_close(self, td: *mut Self::Thread, fd: c_int) -> c_int;

/// # Safety
/// - `td` cannot be null.
/// - `auio` cannot be null.
unsafe fn kern_writev(self, td: *mut Self::Thread, fd: c_int, auio: *mut Self::Uio) -> c_int;

/// # Safety
/// `base` must point to a valid address of the kernel. Behavior is undefined if format of the
/// kernel is unknown.
Expand Down
48 changes: 48 additions & 0 deletions korbis/src/uio/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
use crate::Kernel;

/// Represents `uio` structure.
pub trait Uio: Sized {
type Kernel: Kernel;

/// Returns [`None`] if `len` is geater than [`Uio::vec_max()`] or total length of `iov` is
/// greater than [`Uio::io_max()`].
///
/// # Safety
/// - `td` cannot be null.
/// - `iov` cannot be null and must be valid up to `len`.
unsafe fn new(
td: *mut <Self::Kernel as Kernel>::Thread,
op: UioRw,
seg: UioSeg,
iov: *mut IoVec,
len: usize,
) -> Option<Self>;

/// Returns value of `UIO_MAXIOV`.
fn vec_max() -> usize {
1024
}

/// Returns value of `IOSIZE_MAX`.
fn io_max() -> usize {
0x7fffffff
}
}

/// Represents `uio_seg` enum.
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand All @@ -7,3 +38,20 @@ pub enum UioSeg {
/// UIO_SYSSPACE
Kernel,
}

/// Represents `uio_rw` enum.
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UioRw {
/// UIO_READ
Read,
/// UIO_WRITE
Write,
}

/// Represents `iovec` structure.
#[repr(C)]
pub struct IoVec {
pub ptr: *mut u8,
pub len: usize,
}

0 comments on commit 77089be

Please sign in to comment.