Skip to content

Commit 90f3aae

Browse files
committed
Add fstat shim for OSX
1 parent d94b88e commit 90f3aae

File tree

2 files changed

+89
-56
lines changed

2 files changed

+89
-56
lines changed

src/shims/foreign_items.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
509509
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
510510
}
511511

512+
"fstat$INODE64" => {
513+
let result = this.fstat(args[0], args[1])?;
514+
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
515+
}
516+
512517
"clock_gettime" => {
513518
let result = this.clock_gettime(args[0], args[1])?;
514519
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;

src/shims/fs.rs

Lines changed: 84 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
328328
this.stat_or_lstat(false, path_op, buf_op)
329329
}
330330

331+
fn fstat(
332+
&mut self,
333+
fd_op: OpTy<'tcx, Tag>,
334+
buf_op: OpTy<'tcx, Tag>,
335+
) -> InterpResult<'tcx, i32> {
336+
let this = self.eval_context_mut();
337+
338+
this.check_no_isolation("fstat")?;
339+
340+
if this.tcx.sess.target.target.target_os.to_lowercase() != "macos" {
341+
throw_unsup_format!("The `fstat` shim is only available for `macos` targets.")
342+
}
343+
344+
let fd = this.read_scalar(fd_op)?.to_i32()?;
345+
346+
let metadata = match FileMetadata::from_fd(this, fd)? {
347+
Some(metadata) => metadata,
348+
None => return Ok(-1),
349+
};
350+
stat_write_buf(this, metadata, buf_op)
351+
}
352+
331353
fn stat_or_lstat(
332354
&mut self,
333355
follow_symlink: bool,
@@ -343,66 +365,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
343365
let path_scalar = this.read_scalar(path_op)?.not_undef()?;
344366
let path: PathBuf = this.read_os_str_from_c_str(path_scalar)?.into();
345367

346-
let buf = this.deref_operand(buf_op)?;
347-
348368
let metadata = match FileMetadata::from_path(this, path, follow_symlink)? {
349369
Some(metadata) => metadata,
350370
None => return Ok(-1),
351371
};
352-
353-
let mode: u16 = metadata.mode.to_u16()?;
354-
355-
let (access_sec, access_nsec) = metadata.accessed.unwrap_or((0, 0));
356-
let (created_sec, created_nsec) = metadata.created.unwrap_or((0, 0));
357-
let (modified_sec, modified_nsec) = metadata.modified.unwrap_or((0, 0));
358-
359-
let dev_t_layout = this.libc_ty_layout("dev_t")?;
360-
let mode_t_layout = this.libc_ty_layout("mode_t")?;
361-
let nlink_t_layout = this.libc_ty_layout("nlink_t")?;
362-
let ino_t_layout = this.libc_ty_layout("ino_t")?;
363-
let uid_t_layout = this.libc_ty_layout("uid_t")?;
364-
let gid_t_layout = this.libc_ty_layout("gid_t")?;
365-
let time_t_layout = this.libc_ty_layout("time_t")?;
366-
let long_layout = this.libc_ty_layout("c_long")?;
367-
let off_t_layout = this.libc_ty_layout("off_t")?;
368-
let blkcnt_t_layout = this.libc_ty_layout("blkcnt_t")?;
369-
let blksize_t_layout = this.libc_ty_layout("blksize_t")?;
370-
let uint32_t_layout = this.libc_ty_layout("uint32_t")?;
371-
372-
// We need to add 32 bits of padding after `st_rdev` if we are on a 64-bit platform.
373-
let pad_layout = if this.tcx.sess.target.ptr_width == 64 {
374-
uint32_t_layout
375-
} else {
376-
this.layout_of(this.tcx.mk_unit())?
377-
};
378-
379-
let imms = [
380-
immty_from_uint_checked(0u128, dev_t_layout)?, // st_dev
381-
immty_from_uint_checked(mode, mode_t_layout)?, // st_mode
382-
immty_from_uint_checked(0u128, nlink_t_layout)?, // st_nlink
383-
immty_from_uint_checked(0u128, ino_t_layout)?, // st_ino
384-
immty_from_uint_checked(0u128, uid_t_layout)?, // st_uid
385-
immty_from_uint_checked(0u128, gid_t_layout)?, // st_gid
386-
immty_from_uint_checked(0u128, dev_t_layout)?, // st_rdev
387-
immty_from_uint_checked(0u128, pad_layout)?, // padding for 64-bit targets
388-
immty_from_uint_checked(access_sec, time_t_layout)?, // st_atime
389-
immty_from_uint_checked(access_nsec, long_layout)?, // st_atime_nsec
390-
immty_from_uint_checked(modified_sec, time_t_layout)?, // st_mtime
391-
immty_from_uint_checked(modified_nsec, long_layout)?, // st_mtime_nsec
392-
immty_from_uint_checked(0u128, time_t_layout)?, // st_ctime
393-
immty_from_uint_checked(0u128, long_layout)?, // st_ctime_nsec
394-
immty_from_uint_checked(created_sec, time_t_layout)?, // st_birthtime
395-
immty_from_uint_checked(created_nsec, long_layout)?, // st_birthtime_nsec
396-
immty_from_uint_checked(metadata.size, off_t_layout)?, // st_size
397-
immty_from_uint_checked(0u128, blkcnt_t_layout)?, // st_blocks
398-
immty_from_uint_checked(0u128, blksize_t_layout)?, // st_blksize
399-
immty_from_uint_checked(0u128, uint32_t_layout)?, // st_flags
400-
immty_from_uint_checked(0u128, uint32_t_layout)?, // st_gen
401-
];
402-
403-
this.write_packed_immediates(&buf, &imms)?;
404-
405-
Ok(0)
372+
stat_write_buf(this, metadata, buf_op)
406373
}
407374

408375
fn statx(
@@ -663,3 +630,64 @@ impl FileMetadata {
663630
Ok(Some(FileMetadata { mode, size, created, accessed, modified }))
664631
}
665632
}
633+
634+
fn stat_write_buf<'tcx, 'mir>(
635+
ecx: &mut MiriEvalContext<'mir, 'tcx>,
636+
metadata: FileMetadata,
637+
buf_op: OpTy<'tcx, Tag>,
638+
) -> InterpResult<'tcx, i32> {
639+
let mode: u16 = metadata.mode.to_u16()?;
640+
641+
let (access_sec, access_nsec) = metadata.accessed.unwrap_or((0, 0));
642+
let (created_sec, created_nsec) = metadata.created.unwrap_or((0, 0));
643+
let (modified_sec, modified_nsec) = metadata.modified.unwrap_or((0, 0));
644+
645+
let dev_t_layout = ecx.libc_ty_layout("dev_t")?;
646+
let mode_t_layout = ecx.libc_ty_layout("mode_t")?;
647+
let nlink_t_layout = ecx.libc_ty_layout("nlink_t")?;
648+
let ino_t_layout = ecx.libc_ty_layout("ino_t")?;
649+
let uid_t_layout = ecx.libc_ty_layout("uid_t")?;
650+
let gid_t_layout = ecx.libc_ty_layout("gid_t")?;
651+
let time_t_layout = ecx.libc_ty_layout("time_t")?;
652+
let long_layout = ecx.libc_ty_layout("c_long")?;
653+
let off_t_layout = ecx.libc_ty_layout("off_t")?;
654+
let blkcnt_t_layout = ecx.libc_ty_layout("blkcnt_t")?;
655+
let blksize_t_layout = ecx.libc_ty_layout("blksize_t")?;
656+
let uint32_t_layout = ecx.libc_ty_layout("uint32_t")?;
657+
658+
// We need to add 32 bits of padding after `st_rdev` if we are on a 64-bit platform.
659+
let pad_layout = if ecx.tcx.sess.target.ptr_width == 64 {
660+
uint32_t_layout
661+
} else {
662+
ecx.layout_of(ecx.tcx.mk_unit())?
663+
};
664+
665+
let imms = [
666+
immty_from_uint_checked(0u128, dev_t_layout)?, // st_dev
667+
immty_from_uint_checked(mode, mode_t_layout)?, // st_mode
668+
immty_from_uint_checked(0u128, nlink_t_layout)?, // st_nlink
669+
immty_from_uint_checked(0u128, ino_t_layout)?, // st_ino
670+
immty_from_uint_checked(0u128, uid_t_layout)?, // st_uid
671+
immty_from_uint_checked(0u128, gid_t_layout)?, // st_gid
672+
immty_from_uint_checked(0u128, dev_t_layout)?, // st_rdev
673+
immty_from_uint_checked(0u128, pad_layout)?, // padding for 64-bit targets
674+
immty_from_uint_checked(access_sec, time_t_layout)?, // st_atime
675+
immty_from_uint_checked(access_nsec, long_layout)?, // st_atime_nsec
676+
immty_from_uint_checked(modified_sec, time_t_layout)?, // st_mtime
677+
immty_from_uint_checked(modified_nsec, long_layout)?, // st_mtime_nsec
678+
immty_from_uint_checked(0u128, time_t_layout)?, // st_ctime
679+
immty_from_uint_checked(0u128, long_layout)?, // st_ctime_nsec
680+
immty_from_uint_checked(created_sec, time_t_layout)?, // st_birthtime
681+
immty_from_uint_checked(created_nsec, long_layout)?, // st_birthtime_nsec
682+
immty_from_uint_checked(metadata.size, off_t_layout)?, // st_size
683+
immty_from_uint_checked(0u128, blkcnt_t_layout)?, // st_blocks
684+
immty_from_uint_checked(0u128, blksize_t_layout)?, // st_blksize
685+
immty_from_uint_checked(0u128, uint32_t_layout)?, // st_flags
686+
immty_from_uint_checked(0u128, uint32_t_layout)?, // st_gen
687+
];
688+
689+
let buf = ecx.deref_operand(buf_op)?;
690+
ecx.write_packed_immediates(&buf, &imms)?;
691+
692+
Ok(0)
693+
}

0 commit comments

Comments
 (0)