@@ -328,6 +328,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
328
328
this. stat_or_lstat ( false , path_op, buf_op)
329
329
}
330
330
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
+
331
353
fn stat_or_lstat (
332
354
& mut self ,
333
355
follow_symlink : bool ,
@@ -343,66 +365,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
343
365
let path_scalar = this. read_scalar ( path_op) ?. not_undef ( ) ?;
344
366
let path: PathBuf = this. read_os_str_from_c_str ( path_scalar) ?. into ( ) ;
345
367
346
- let buf = this. deref_operand ( buf_op) ?;
347
-
348
368
let metadata = match FileMetadata :: from_path ( this, path, follow_symlink) ? {
349
369
Some ( metadata) => metadata,
350
370
None => return Ok ( -1 ) ,
351
371
} ;
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)
406
373
}
407
374
408
375
fn statx (
@@ -663,3 +630,64 @@ impl FileMetadata {
663
630
Ok ( Some ( FileMetadata { mode, size, created, accessed, modified } ) )
664
631
}
665
632
}
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