Skip to content

Commit

Permalink
filesystem support for solarish.
Browse files Browse the repository at this point in the history
  • Loading branch information
devnexen committed Nov 26, 2024
1 parent 82ed49e commit bccec41
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 39 deletions.
4 changes: 2 additions & 2 deletions ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ case $HOST_TARGET in
UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe fs
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe fs
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random sync threadname pthread epoll eventfd
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC wasm
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
Expand Down
8 changes: 4 additions & 4 deletions src/shims/unix/freebsd/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"stat" | "stat@FBSD_1.0" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_stat(path, buf)?;
let result = this.macos_fbsd_solaris_stat(path, buf)?;
this.write_scalar(result, dest)?;
}
"lstat" | "lstat@FBSD_1.0" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_lstat(path, buf)?;
let result = this.macos_fbsd_solaris_lstat(path, buf)?;
this.write_scalar(result, dest)?;
}
"fstat" | "fstat@FBSD_1.0" => {
let [fd, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_fstat(fd, buf)?;
let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
this.write_scalar(result, dest)?;
}
"readdir_r" | "readdir_r@FBSD_1.0" => {
let [dirp, entry, result] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
let result = this.macos_fbsd_solaris_readdir_r(dirp, entry, result)?;
this.write_scalar(result, dest)?;
}

Expand Down
75 changes: 48 additions & 27 deletions src/shims/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,47 +265,59 @@ impl FileDescription for FileHandle {

impl<'tcx> EvalContextExtPrivate<'tcx> for crate::MiriInterpCx<'tcx> {}
trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn macos_stat_write_buf(
fn macos_fbsd_solaris_write_buf(
&mut self,
metadata: FileMetadata,
buf_op: &OpTy<'tcx>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();

let mode: u16 = metadata.mode.to_u16()?;

let (access_sec, access_nsec) = metadata.accessed.unwrap_or((0, 0));
let (created_sec, created_nsec) = metadata.created.unwrap_or((0, 0));
let (modified_sec, modified_nsec) = metadata.modified.unwrap_or((0, 0));
let mode = metadata.mode.to_uint(this.libc_ty_layout("mode_t").size)?;

let buf = this.deref_pointer_as(buf_op, this.libc_ty_layout("stat"))?;

this.write_int_fields_named(
&[
("st_dev", 0),
("st_mode", mode.into()),
("st_mode", mode.try_into().unwrap()),
("st_nlink", 0),
("st_ino", 0),
("st_uid", 0),
("st_gid", 0),
("st_rdev", 0),
("st_atime", access_sec.into()),
("st_atime_nsec", access_nsec.into()),
("st_mtime", modified_sec.into()),
("st_mtime_nsec", modified_nsec.into()),
("st_ctime", 0),
("st_ctime_nsec", 0),
("st_birthtime", created_sec.into()),
("st_birthtime_nsec", created_nsec.into()),
("st_size", metadata.size.into()),
("st_blocks", 0),
("st_blksize", 0),
("st_flags", 0),
("st_gen", 0),
],
&buf,
)?;

if matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
this.write_int_fields_named(
&[
("st_atime_nsec", access_nsec.into()),
("st_mtime_nsec", modified_nsec.into()),
("st_ctime_nsec", 0),
("st_birthtime", created_sec.into()),
("st_birthtime_nsec", created_nsec.into()),
("st_flags", 0),
("st_gen", 0),
],
&buf,
)?;
}

if matches!(&*this.tcx.sess.target.os, "solaris" | "illumos") {
// FIXME: libc crate, update stat struct, as `st_fstype` will be uninitialised
// https://github.com/rust-lang/libc/pull/4145
//this.write_int_fields_named(&[("st_fstype", 0)], &buf)?;
}

interp_ok(0)
}

Expand Down Expand Up @@ -648,15 +660,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
interp_ok(Scalar::from_i32(this.try_unwrap_io_result(result)?))
}

fn macos_fbsd_stat(
fn macos_fbsd_solaris_stat(
&mut self,
path_op: &OpTy<'tcx>,
buf_op: &OpTy<'tcx>,
) -> InterpResult<'tcx, Scalar> {
let this = self.eval_context_mut();

if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
panic!("`macos_fbsd_stat` should not be called on {}", this.tcx.sess.target.os);
if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd" | "solaris" | "illumos") {
panic!("`macos_fbsd_solaris_stat` should not be called on {}", this.tcx.sess.target.os);
}

let path_scalar = this.read_pointer(path_op)?;
Expand All @@ -674,19 +686,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
Err(err) => return this.set_last_error_and_return_i32(err),
};

interp_ok(Scalar::from_i32(this.macos_stat_write_buf(metadata, buf_op)?))
interp_ok(Scalar::from_i32(this.macos_fbsd_solaris_write_buf(metadata, buf_op)?))
}

// `lstat` is used to get symlink metadata.
fn macos_fbsd_lstat(
fn macos_fbsd_solaris_lstat(
&mut self,
path_op: &OpTy<'tcx>,
buf_op: &OpTy<'tcx>,
) -> InterpResult<'tcx, Scalar> {
let this = self.eval_context_mut();

if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
panic!("`macos_fbsd_lstat` should not be called on {}", this.tcx.sess.target.os);
if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd" | "solaris" | "illumos") {
panic!(
"`macos_fbsd_solaris_lstat` should not be called on {}",
this.tcx.sess.target.os
);
}

let path_scalar = this.read_pointer(path_op)?;
Expand All @@ -703,18 +718,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
Err(err) => return this.set_last_error_and_return_i32(err),
};

interp_ok(Scalar::from_i32(this.macos_stat_write_buf(metadata, buf_op)?))
interp_ok(Scalar::from_i32(this.macos_fbsd_solaris_write_buf(metadata, buf_op)?))
}

fn macos_fbsd_fstat(
fn macos_fbsd_solaris_fstat(
&mut self,
fd_op: &OpTy<'tcx>,
buf_op: &OpTy<'tcx>,
) -> InterpResult<'tcx, Scalar> {
let this = self.eval_context_mut();

if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
panic!("`macos_fbsd_fstat` should not be called on {}", this.tcx.sess.target.os);
if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd" | "solaris" | "illumos") {
panic!(
"`macos_fbsd_solaris_fstat` should not be called on {}",
this.tcx.sess.target.os
);
}

let fd = this.read_scalar(fd_op)?.to_i32()?;
Expand All @@ -730,7 +748,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
Ok(metadata) => metadata,
Err(err) => return this.set_last_error_and_return_i32(err),
};
interp_ok(Scalar::from_i32(this.macos_stat_write_buf(metadata, buf_op)?))
interp_ok(Scalar::from_i32(this.macos_fbsd_solaris_write_buf(metadata, buf_op)?))
}

fn linux_statx(
Expand Down Expand Up @@ -1112,16 +1130,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
interp_ok(Scalar::from_maybe_pointer(entry.unwrap_or_else(Pointer::null), this))
}

fn macos_fbsd_readdir_r(
fn macos_fbsd_solaris_readdir_r(
&mut self,
dirp_op: &OpTy<'tcx>,
entry_op: &OpTy<'tcx>,
result_op: &OpTy<'tcx>,
) -> InterpResult<'tcx, Scalar> {
let this = self.eval_context_mut();

if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
panic!("`macos_fbsd_readdir_r` should not be called on {}", this.tcx.sess.target.os);
if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd" | "solaris" | "illumos") {
panic!(
"`macos_fbsd_solaris_readdir_r` should not be called on {}",
this.tcx.sess.target.os
);
}

let dirp = this.read_target_usize(dirp_op)?;
Expand Down
8 changes: 4 additions & 4 deletions src/shims/unix/macos/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"stat" | "stat64" | "stat$INODE64" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_stat(path, buf)?;
let result = this.macos_fbsd_solaris_stat(path, buf)?;
this.write_scalar(result, dest)?;
}
"lstat" | "lstat64" | "lstat$INODE64" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_lstat(path, buf)?;
let result = this.macos_fbsd_solaris_lstat(path, buf)?;
this.write_scalar(result, dest)?;
}
"fstat" | "fstat64" | "fstat$INODE64" => {
let [fd, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_fstat(fd, buf)?;
let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
this.write_scalar(result, dest)?;
}
"opendir$INODE64" => {
Expand All @@ -64,7 +64,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"readdir_r" | "readdir_r$INODE64" => {
let [dirp, entry, result] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
let result = this.macos_fbsd_solaris_readdir_r(dirp, entry, result)?;
this.write_scalar(result, dest)?;
}
"realpath$DARWIN_EXTSN" => {
Expand Down
26 changes: 26 additions & 0 deletions src/shims/unix/solarish/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_scalar(res, dest)?;
}

// File related shims
"stat" | "stat64" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_solaris_stat(path, buf)?;
this.write_scalar(result, dest)?;
}
"lstat" | "lstat64" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_solaris_lstat(path, buf)?;
this.write_scalar(result, dest)?;
}
"fstat" | "fstat64" => {
let [fd, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
this.write_scalar(result, dest)?;
}
"readdir_r" => {
let [dirp, entry, result] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_solaris_readdir_r(dirp, entry, result)?;
this.write_scalar(result, dest)?;
}

// Miscellaneous
"___errno" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
Expand Down
7 changes: 5 additions & 2 deletions tests/pass/shims/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ fn main() {
test_file_sync();
test_errors();
test_rename();
test_directory();
test_canonicalize();
// solarish needs to support readdir/readdir64 for these tests.
if cfg!(not(any(target_os = "solaris", target_os = "illumos"))) {
test_directory();
test_canonicalize();
}
test_from_raw_os_error();
#[cfg(unix)]
test_pread_pwrite();
Expand Down

0 comments on commit bccec41

Please sign in to comment.