Skip to content

Commit

Permalink
Move some macos functions to writing to dest directly
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Aug 1, 2024
1 parent 39df583 commit 378d324
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 45 deletions.
19 changes: 9 additions & 10 deletions src/shims/unix/freebsd/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.read_scalar(name)?,
max_len,
)?;
Ok(EmulateItemResult::NeedsReturn)
}
"pthread_get_name_np" => {
let [thread, name, len] =
Expand All @@ -40,6 +41,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.read_scalar(name)?,
this.read_scalar(len)?,
)?;
Ok(EmulateItemResult::NeedsReturn)
}

// File related shims
Expand All @@ -48,32 +50,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"stat" | "stat@FBSD_1.0" => {
let [path, buf] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_stat(path, buf)?;
this.write_scalar(result, dest)?;
this.macos_fbsd_stat(path, buf, dest)
}
"lstat" | "lstat@FBSD_1.0" => {
let [path, buf] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_lstat(path, buf)?;
this.write_scalar(result, dest)?;
this.macos_fbsd_lstat(path, buf, dest)
}
"fstat" | "fstat@FBSD_1.0" => {
let [fd, buf] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_fstat(fd, buf)?;
this.write_scalar(result, dest)?;
this.macos_fbsd_fstat(fd, buf, dest)
}
"readdir_r" | "readdir_r@FBSD_1.0" => {
let [dirp, entry, result] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
this.write_scalar(result, dest)?;
this.macos_fbsd_readdir_r(dirp, entry, result, dest)
}

// Miscellaneous
"__error" => {
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let errno_place = this.last_error_place()?;
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
Ok(EmulateItemResult::NeedsReturn)
}

// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
Expand All @@ -82,10 +81,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let [_thread, _attr] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
this.write_null(dest)?;
Ok(EmulateItemResult::NeedsReturn)
}

_ => return Ok(EmulateItemResult::NotSupported),
_ => Ok(EmulateItemResult::NotSupported),
}
Ok(EmulateItemResult::NeedsReturn)
}
}
71 changes: 44 additions & 27 deletions src/shims/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
&mut self,
path_op: &OpTy<'tcx>,
buf_op: &OpTy<'tcx>,
) -> InterpResult<'tcx, Scalar> {
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
let this = self.eval_context_mut();

if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
Expand All @@ -652,26 +653,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Reject if isolation is enabled.
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
this.reject_in_isolation("`stat`", reject_with)?;
let eacc = this.eval_libc("EACCES");
this.set_last_error(eacc)?;
return Ok(Scalar::from_i32(-1));
return this.set_libc_err_and_return_neg1("EACCES", dest);
}

// `stat` always follows symlinks.
let metadata = match FileMetadata::from_path(this, &path, true)? {
Some(metadata) => metadata,
None => return Ok(Scalar::from_i32(-1)), // `FileMetadata` has set errno
None => {
this.write_int(-1, dest)?;
return Ok(EmulateItemResult::NeedsReturn);
}
};

Ok(Scalar::from_i32(this.macos_stat_write_buf(metadata, buf_op)?))
let res = this.macos_stat_write_buf(metadata, buf_op)?;
this.write_int(res, dest)?;
Ok(EmulateItemResult::NeedsReturn)
}

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

if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
Expand All @@ -684,24 +688,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Reject if isolation is enabled.
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
this.reject_in_isolation("`lstat`", reject_with)?;
let eacc = this.eval_libc("EACCES");
this.set_last_error(eacc)?;
return Ok(Scalar::from_i32(-1));
return this.set_libc_err_and_return_neg1("EACCES", dest);
}

let metadata = match FileMetadata::from_path(this, &path, false)? {
Some(metadata) => metadata,
None => return Ok(Scalar::from_i32(-1)), // `FileMetadata` has set errno
None => {
this.write_int(-1, dest)?;
return Ok(EmulateItemResult::NeedsReturn);
}
};

Ok(Scalar::from_i32(this.macos_stat_write_buf(metadata, buf_op)?))
let res = this.macos_stat_write_buf(metadata, buf_op)?;
this.write_int(res, dest)?;
Ok(EmulateItemResult::NeedsReturn)
}

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

if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
Expand All @@ -714,14 +721,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
this.reject_in_isolation("`fstat`", reject_with)?;
// Set error code as "EBADF" (bad fd)
return Ok(Scalar::from_i32(this.fd_not_found()?));
return this.set_fd_not_found_and_return_neg1(dest);
}

let metadata = match FileMetadata::from_fd(this, fd)? {
Some(metadata) => metadata,
None => return Ok(Scalar::from_i32(-1)),
None => {
this.write_int(-1, dest)?;
return Ok(EmulateItemResult::NeedsReturn);
}
};
Ok(Scalar::from_i32(this.macos_stat_write_buf(metadata, buf_op)?))
let res = this.macos_stat_write_buf(metadata, buf_op)?;
this.write_int(res, dest)?;
Ok(EmulateItemResult::NeedsReturn)
}

fn linux_statx(
Expand Down Expand Up @@ -1129,7 +1141,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
dirp_op: &OpTy<'tcx>,
entry_op: &OpTy<'tcx>,
result_op: &OpTy<'tcx>,
) -> InterpResult<'tcx, Scalar> {
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
let this = self.eval_context_mut();

if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
Expand All @@ -1141,14 +1154,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Reject if isolation is enabled.
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
this.reject_in_isolation("`readdir_r`", reject_with)?;
// Set error code as "EBADF" (bad fd)
return Ok(Scalar::from_i32(this.fd_not_found()?));
// TODO: why does this set the global error code and returns -1?
// at the end of this function we don't set the code, we just return it.
let i: i32 = this.fd_not_found()?;
this.write_int(i, dest)?;
return Ok(EmulateItemResult::NeedsReturn);
}

let open_dir = this.machine.dirs.streams.get_mut(&dirp).ok_or_else(|| {
err_unsup_format!("the DIR pointer passed to readdir_r did not come from opendir")
})?;
Ok(Scalar::from_i32(match open_dir.read_dir.next() {
match open_dir.read_dir.next() {
Some(Ok(dir_entry)) => {
// Write into entry, write pointer to result, return 0 on success.
// The name is written with write_os_str_to_c_str, while the rest of the
Expand Down Expand Up @@ -1225,26 +1241,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

let result_place = this.deref_pointer(result_op)?;
this.write_scalar(this.read_scalar(entry_op)?, &result_place)?;

0
this.write_null(dest)?;
}
None => {
// end of stream: return 0, assign *result=NULL
this.write_null(&this.deref_pointer(result_op)?)?;
0
this.write_null(dest)?;
}
Some(Err(e)) =>
match e.raw_os_error() {
// return positive error number on error
Some(error) => error,
Some(error) => this.write_int(error, dest)?,
None => {
throw_unsup_format!(
"the error {} couldn't be converted to a return value",
e
)
}
},
}))
}

Ok(EmulateItemResult::NeedsReturn)
}

fn closedir(&mut self, dirp_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
Expand Down
12 changes: 4 additions & 8 deletions src/shims/unix/macos/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"stat" | "stat64" | "stat$INODE64" => {
let [path, buf] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_stat(path, buf)?;
this.write_scalar(result, dest)?;
return this.macos_fbsd_stat(path, buf, dest);
}
"lstat" | "lstat64" | "lstat$INODE64" => {
let [path, buf] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_lstat(path, buf)?;
this.write_scalar(result, dest)?;
return this.macos_fbsd_lstat(path, buf, dest);
}
"fstat" | "fstat64" | "fstat$INODE64" => {
let [fd, buf] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_fstat(fd, buf)?;
this.write_scalar(result, dest)?;
return this.macos_fbsd_fstat(fd, buf, dest);
}
"opendir$INODE64" => {
let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
Expand All @@ -61,8 +58,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"readdir_r" | "readdir_r$INODE64" => {
let [dirp, entry, result] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
this.write_scalar(result, dest)?;
return this.macos_fbsd_readdir_r(dirp, entry, result, dest);
}
"realpath$DARWIN_EXTSN" => {
let [path, resolved_path] =
Expand Down

0 comments on commit 378d324

Please sign in to comment.