Skip to content

Commit

Permalink
move linux fs functions to linux/fs module
Browse files Browse the repository at this point in the history
  • Loading branch information
DebugSteven committed Oct 16, 2022
1 parent f325776 commit 3ca89af
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 157 deletions.
165 changes: 8 additions & 157 deletions src/shims/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ use std::time::SystemTime;
use log::trace;

use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::{self, layout::LayoutOf, ScalarInt};
use rustc_middle::ty::{self, layout::LayoutOf};
use rustc_target::abi::{Align, Size};

use crate::shims::os_str::bytes_to_os_str;
use crate::*;
use shims::os_str::os_str_to_bytes;
use shims::time::system_time_to_duration;
use shims::unix::linux::fs::epoll::{Epoll, EpollEvent};
use shims::unix::linux::fs::event::Event;
use shims::unix::linux::fs::socketpair::SocketPair;
use shims::unix::linux::fs::epoll::Epoll;

#[derive(Debug)]
pub struct FileHandle {
Expand Down Expand Up @@ -260,7 +258,7 @@ impl FileDescriptor for DummyOutput {

#[derive(Debug)]
pub struct FileHandler {
handles: BTreeMap<i32, Box<dyn FileDescriptor>>,
pub handles: BTreeMap<i32, Box<dyn FileDescriptor>>,
}

impl VisitTags for FileHandler {
Expand All @@ -283,7 +281,7 @@ impl FileHandler {
FileHandler { handles }
}

fn insert_fd(&mut self, file_handle: Box<dyn FileDescriptor>) -> i32 {
pub fn insert_fd(&mut self, file_handle: Box<dyn FileDescriptor>) -> i32 {
self.insert_fd_with_min_fd(file_handle, 0)
}

Expand Down Expand Up @@ -318,7 +316,9 @@ impl FileHandler {
}

impl<'mir, 'tcx: 'mir> EvalContextExtPrivate<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
pub(super) trait EvalContextExtPrivate<'mir, 'tcx: 'mir>:
crate::MiriInterpCxExt<'mir, 'tcx>
{
fn macos_stat_write_buf(
&mut self,
metadata: FileMetadata,
Expand Down Expand Up @@ -703,155 +703,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
))
}

fn epoll_create1(&mut self, flags: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let flags = this.read_scalar(flags)?.to_i32()?;

let epoll_cloexec = this.eval_libc_i32("EPOLL_CLOEXEC")?;
// TODO actually do the thing
let _fd_cloexec = this.eval_libc_i32("FD_CLOEXEC")?;
if flags == epoll_cloexec {
// set close on exec, FD_CLOEXEC
} else if flags != 0 {
let einval = this.eval_libc("EINVAL")?;
this.set_last_error(einval)?;
return Ok(-1);
}

let fh = &mut this.machine.file_handler;
#[allow(clippy::box_default)]
let fd = fh.insert_fd(Box::new(Epoll::default()));
Ok(fd)
}

fn epoll_ctl(
&mut self,
epfd: &OpTy<'tcx, Provenance>,
op: &OpTy<'tcx, Provenance>,
fd: &OpTy<'tcx, Provenance>,
event: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let values = this.read_scalar(op)?.to_i32()?;
let epfd = this.read_scalar(epfd)?.to_i32()?;
let fd = this.read_scalar(fd)?.to_i32()?;

let epoll_ctl_add = this.eval_libc_i32("EPOLL_CTL_ADD")?;
let epoll_ctl_mod = this.eval_libc_i32("EPOLL_CTL_MOD")?;
let epoll_ctl_del = this.eval_libc_i32("EPOLL_CTL_DEL")?;

if values == epoll_ctl_add || values == epoll_ctl_mod {
let event = this.deref_operand(event)?;

let events = this.mplace_field(&event, 0)?;
let events = this.read_scalar(&events.into())?.to_u32()?;
let data = this.mplace_field(&event, 1)?;
let data = this.read_scalar(&data.into())?.to_u64()?;
let event = EpollEvent { events, data };

if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
let epfd = epfd.as_epoll_handle()?;

epfd.file_descriptors.insert(fd, event);
Ok(0)
} else {
this.handle_not_found()
}
} else if values == epoll_ctl_del {
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
let epfd = epfd.as_epoll_handle()?;

epfd.file_descriptors.remove(&fd);
Ok(0)
} else {
this.handle_not_found()
}
} else {
let einval = this.eval_libc("EINVAL")?;
this.set_last_error(einval)?;
Ok(-1)
}
}

fn epoll_wait(
&mut self,
epfd: &OpTy<'tcx, Provenance>,
events: &OpTy<'tcx, Provenance>,
maxevents: &OpTy<'tcx, Provenance>,
timeout: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let _epfd = this.read_scalar(epfd)?.to_i32()?;
let _events = this.read_scalar(events)?;
let maxevents = this.read_scalar(maxevents)?.to_i32()?;
let _timeout = this.read_scalar(timeout)?.to_i32()?;

if maxevents <= 0 {
throw_ub_format!("maxevents must be greater than 0");
}

throw_ub_format!("closed due to not writing");
}

fn eventfd(
&mut self,
val: &OpTy<'tcx, Provenance>,
flags: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let val = this.read_scalar(val)?.to_u32()?;
let flags = this.read_scalar(flags)?.to_i32()?;

let efd_cloexec = this.eval_libc_i32("EFD_CLOEXEC")?;
let efd_nonblock = this.eval_libc_i32("EFD_NONBLOCK")?;
let efd_semaphore = this.eval_libc_i32("EFD_SEMAPHORE")?;
// TODO actually do the thing
if flags & efd_cloexec != 0 {}
if flags & efd_nonblock != 0 {}
if flags & efd_semaphore != 0 {
throw_unsup_format!("EFD_SEMAPHORE is unsupported");
}

let fh = &mut this.machine.file_handler;
let fd = fh.insert_fd(Box::new(Event { val }));
Ok(fd)
}

fn socketpair(
&mut self,
_domain: &OpTy<'tcx, Provenance>,
type_: &OpTy<'tcx, Provenance>,
_protocol: &OpTy<'tcx, Provenance>,
sv: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let _flags = this.read_scalar(type_)?.to_i32()?;
let sv = this.deref_operand(sv)?;

let fh = &mut this.machine.file_handler;
let sv0 = fh.insert_fd(Box::new(SocketPair));
let sv0 = ScalarInt::try_from_int(sv0, sv.layout.size).unwrap();
let sv1 = fh.insert_fd(Box::new(SocketPair));
let sv1 = ScalarInt::try_from_int(sv1, sv.layout.size).unwrap();

this.write_scalar(sv0, &sv.into())?;
this.write_scalar(sv1, &sv.offset(sv.layout.size, sv.layout, this)?.into())?;

Ok(0)
}

fn libc_current_sigrtmax(&mut self) -> InterpResult<'tcx, i32> {
let _this = self.eval_context_mut();

// TODO return the correct value
Ok(42)
}

fn read(
&mut self,
fd: i32,
Expand Down Expand Up @@ -2054,7 +1905,7 @@ fn extract_sec_and_nsec<'tcx>(

/// Stores a file's metadata in order to avoid code duplication in the different metadata related
/// shims.
struct FileMetadata {
pub(super) struct FileMetadata {
mode: Scalar<Provenance>,
size: u64,
created: Option<(u64, u32)>,
Expand Down
1 change: 1 addition & 0 deletions src/shims/unix/linux/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use rustc_target::spec::abi::Abi;
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::unix::fs::EvalContextExt as _;
use shims::unix::linux::fs::EvalContextExt as _;
use shims::unix::linux::sync::futex;
use shims::unix::sync::EvalContextExt as _;
use shims::unix::thread::EvalContextExt as _;
Expand Down
161 changes: 161 additions & 0 deletions src/shims/unix/linux/fs.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,164 @@
use rustc_middle::ty::ScalarInt;

use crate::*;
use epoll::{Epoll, EpollEvent};
use event::Event;
use socketpair::SocketPair;

use shims::unix::fs::EvalContextExtPrivate;

pub mod epoll;
pub mod event;
pub mod socketpair;

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
fn epoll_create1(&mut self, flags: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let flags = this.read_scalar(flags)?.to_i32()?;

let epoll_cloexec = this.eval_libc_i32("EPOLL_CLOEXEC")?;
// TODO actually do the thing
let _fd_cloexec = this.eval_libc_i32("FD_CLOEXEC")?;
if flags == epoll_cloexec {
// set close on exec, FD_CLOEXEC
} else if flags != 0 {
let einval = this.eval_libc("EINVAL")?;
this.set_last_error(einval)?;
return Ok(-1);
}

let fh = &mut this.machine.file_handler;
#[allow(clippy::box_default)]
let fd = fh.insert_fd(Box::new(Epoll::default()));
Ok(fd)
}

fn epoll_ctl(
&mut self,
epfd: &OpTy<'tcx, Provenance>,
op: &OpTy<'tcx, Provenance>,
fd: &OpTy<'tcx, Provenance>,
event: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let values = this.read_scalar(op)?.to_i32()?;
let epfd = this.read_scalar(epfd)?.to_i32()?;
let fd = this.read_scalar(fd)?.to_i32()?;

let epoll_ctl_add = this.eval_libc_i32("EPOLL_CTL_ADD")?;
let epoll_ctl_mod = this.eval_libc_i32("EPOLL_CTL_MOD")?;
let epoll_ctl_del = this.eval_libc_i32("EPOLL_CTL_DEL")?;

if values == epoll_ctl_add || values == epoll_ctl_mod {
let event = this.deref_operand(event)?;

let events = this.mplace_field(&event, 0)?;
let events = this.read_scalar(&events.into())?.to_u32()?;
let data = this.mplace_field(&event, 1)?;
let data = this.read_scalar(&data.into())?.to_u64()?;
let event = EpollEvent { events, data };

if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
let epfd = epfd.as_epoll_handle()?;

epfd.file_descriptors.insert(fd, event);
Ok(0)
} else {
this.handle_not_found()
}
} else if values == epoll_ctl_del {
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
let epfd = epfd.as_epoll_handle()?;

epfd.file_descriptors.remove(&fd);
Ok(0)
} else {
this.handle_not_found()
}
} else {
let einval = this.eval_libc("EINVAL")?;
this.set_last_error(einval)?;
Ok(-1)
}
}

fn epoll_wait(
&mut self,
epfd: &OpTy<'tcx, Provenance>,
events: &OpTy<'tcx, Provenance>,
maxevents: &OpTy<'tcx, Provenance>,
timeout: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let _epfd = this.read_scalar(epfd)?.to_i32()?;
let _events = this.read_scalar(events)?;
let maxevents = this.read_scalar(maxevents)?.to_i32()?;
let _timeout = this.read_scalar(timeout)?.to_i32()?;

if maxevents <= 0 {
throw_ub_format!("maxevents must be greater than 0");
}

throw_ub_format!("closed due to not writing");
}

fn eventfd(
&mut self,
val: &OpTy<'tcx, Provenance>,
flags: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let val = this.read_scalar(val)?.to_u32()?;
let flags = this.read_scalar(flags)?.to_i32()?;

let efd_cloexec = this.eval_libc_i32("EFD_CLOEXEC")?;
let efd_nonblock = this.eval_libc_i32("EFD_NONBLOCK")?;
let efd_semaphore = this.eval_libc_i32("EFD_SEMAPHORE")?;
// TODO actually do the thing
if flags & efd_cloexec != 0 {}
if flags & efd_nonblock != 0 {}
if flags & efd_semaphore != 0 {
throw_unsup_format!("EFD_SEMAPHORE is unsupported");
}

let fh = &mut this.machine.file_handler;
let fd = fh.insert_fd(Box::new(Event { val }));
Ok(fd)
}

fn socketpair(
&mut self,
_domain: &OpTy<'tcx, Provenance>,
type_: &OpTy<'tcx, Provenance>,
_protocol: &OpTy<'tcx, Provenance>,
sv: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let _flags = this.read_scalar(type_)?.to_i32()?;
let sv = this.deref_operand(sv)?;

let fh = &mut this.machine.file_handler;
let sv0 = fh.insert_fd(Box::new(SocketPair));
let sv0 = ScalarInt::try_from_int(sv0, sv.layout.size).unwrap();
let sv1 = fh.insert_fd(Box::new(SocketPair));
let sv1 = ScalarInt::try_from_int(sv1, sv.layout.size).unwrap();

this.write_scalar(sv0, &sv.into())?;
this.write_scalar(sv1, &sv.offset(sv.layout.size, sv.layout, this)?.into())?;

Ok(0)
}

fn libc_current_sigrtmax(&mut self) -> InterpResult<'tcx, i32> {
let _this = self.eval_context_mut();

// TODO return the correct value
Ok(42)
}
}

0 comments on commit 3ca89af

Please sign in to comment.