@@ -827,24 +827,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
827
827
828
828
fn lseek64 (
829
829
& mut self ,
830
- fd_op : & OpTy < ' tcx , Provenance > ,
831
- offset_op : & OpTy < ' tcx , Provenance > ,
832
- whence_op : & OpTy < ' tcx , Provenance > ,
830
+ fd : i32 ,
831
+ offset : i128 ,
832
+ whence : i32 ,
833
833
) -> InterpResult < ' tcx , Scalar < Provenance > > {
834
834
let this = self . eval_context_mut ( ) ;
835
835
836
836
// Isolation check is done via `FileDescriptor` trait.
837
837
838
- let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
839
- let offset = this. read_scalar ( offset_op) ?. to_i64 ( ) ?;
840
- let whence = this. read_scalar ( whence_op) ?. to_i32 ( ) ?;
841
-
842
838
let seek_from = if whence == this. eval_libc_i32 ( "SEEK_SET" ) {
843
839
SeekFrom :: Start ( u64:: try_from ( offset) . unwrap ( ) )
844
840
} else if whence == this. eval_libc_i32 ( "SEEK_CUR" ) {
845
- SeekFrom :: Current ( offset)
841
+ SeekFrom :: Current ( i64 :: try_from ( offset) . unwrap ( ) )
846
842
} else if whence == this. eval_libc_i32 ( "SEEK_END" ) {
847
- SeekFrom :: End ( offset)
843
+ SeekFrom :: End ( i64 :: try_from ( offset) . unwrap ( ) )
848
844
} else {
849
845
let einval = this. eval_libc ( "EINVAL" ) ;
850
846
this. set_last_error ( einval) ?;
@@ -911,13 +907,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
911
907
this. try_unwrap_io_result ( result)
912
908
}
913
909
914
- fn macos_stat (
910
+ fn macos_fbsd_stat (
915
911
& mut self ,
916
912
path_op : & OpTy < ' tcx , Provenance > ,
917
913
buf_op : & OpTy < ' tcx , Provenance > ,
918
914
) -> InterpResult < ' tcx , Scalar < Provenance > > {
919
915
let this = self . eval_context_mut ( ) ;
920
- this. assert_target_os ( "macos" , "stat" ) ;
916
+
917
+ if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
918
+ panic ! ( "`macos_fbsd_stat` should not be called on {}" , this. tcx. sess. target. os) ;
919
+ }
921
920
922
921
let path_scalar = this. read_pointer ( path_op) ?;
923
922
let path = this. read_path_from_c_str ( path_scalar) ?. into_owned ( ) ;
@@ -940,13 +939,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
940
939
}
941
940
942
941
// `lstat` is used to get symlink metadata.
943
- fn macos_lstat (
942
+ fn macos_fbsd_lstat (
944
943
& mut self ,
945
944
path_op : & OpTy < ' tcx , Provenance > ,
946
945
buf_op : & OpTy < ' tcx , Provenance > ,
947
946
) -> InterpResult < ' tcx , Scalar < Provenance > > {
948
947
let this = self . eval_context_mut ( ) ;
949
- this. assert_target_os ( "macos" , "lstat" ) ;
948
+
949
+ if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
950
+ panic ! ( "`macos_fbsd_lstat` should not be called on {}" , this. tcx. sess. target. os) ;
951
+ }
950
952
951
953
let path_scalar = this. read_pointer ( path_op) ?;
952
954
let path = this. read_path_from_c_str ( path_scalar) ?. into_owned ( ) ;
@@ -967,14 +969,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
967
969
Ok ( Scalar :: from_i32 ( this. macos_stat_write_buf ( metadata, buf_op) ?) )
968
970
}
969
971
970
- fn macos_fstat (
972
+ fn macos_fbsd_fstat (
971
973
& mut self ,
972
974
fd_op : & OpTy < ' tcx , Provenance > ,
973
975
buf_op : & OpTy < ' tcx , Provenance > ,
974
976
) -> InterpResult < ' tcx , Scalar < Provenance > > {
975
977
let this = self . eval_context_mut ( ) ;
976
978
977
- this. assert_target_os ( "macos" , "fstat" ) ;
979
+ if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
980
+ panic ! ( "`macos_fbsd_fstat` should not be called on {}" , this. tcx. sess. target. os) ;
981
+ }
978
982
979
983
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
980
984
@@ -1213,7 +1217,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1213
1217
let this = self . eval_context_mut ( ) ;
1214
1218
1215
1219
#[ cfg_attr( not( unix) , allow( unused_variables) ) ]
1216
- let mode = if this. tcx . sess . target . os == "macos" {
1220
+ let mode = if matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
1217
1221
u32:: from ( this. read_scalar ( mode_op) ?. to_u16 ( ) ?)
1218
1222
} else {
1219
1223
this. read_scalar ( mode_op) ?. to_u32 ( ) ?
@@ -1385,15 +1389,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1385
1389
Ok ( Scalar :: from_maybe_pointer ( entry, this) )
1386
1390
}
1387
1391
1388
- fn macos_readdir_r (
1392
+ fn macos_fbsd_readdir_r (
1389
1393
& mut self ,
1390
1394
dirp_op : & OpTy < ' tcx , Provenance > ,
1391
1395
entry_op : & OpTy < ' tcx , Provenance > ,
1392
1396
result_op : & OpTy < ' tcx , Provenance > ,
1393
1397
) -> InterpResult < ' tcx , Scalar < Provenance > > {
1394
1398
let this = self . eval_context_mut ( ) ;
1395
1399
1396
- this. assert_target_os ( "macos" , "readdir_r" ) ;
1400
+ if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
1401
+ panic ! ( "`macos_fbsd_readdir_r` should not be called on {}" , this. tcx. sess. target. os) ;
1402
+ }
1397
1403
1398
1404
let dirp = this. read_target_usize ( dirp_op) ?;
1399
1405
@@ -1424,7 +1430,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1424
1430
// }
1425
1431
1426
1432
let entry_place = this. deref_pointer_as ( entry_op, this. libc_ty_layout ( "dirent" ) ) ?;
1427
- let name_place = this. project_field ( & entry_place, 5 ) ?;
1433
+ let name_place = this. project_field_named ( & entry_place, "d_name" ) ?;
1428
1434
1429
1435
let file_name = dir_entry. file_name ( ) ; // not a Path as there are no separators!
1430
1436
let ( name_fits, file_name_buf_len) = this. write_os_str_to_c_str (
@@ -1448,16 +1454,41 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1448
1454
1449
1455
let file_type = this. file_type_to_d_type ( dir_entry. file_type ( ) ) ?;
1450
1456
1451
- this. write_int_fields_named (
1452
- & [
1453
- ( "d_ino" , ino. into ( ) ) ,
1454
- ( "d_seekoff" , 0 ) ,
1455
- ( "d_reclen" , 0 ) ,
1456
- ( "d_namlen" , file_name_len. into ( ) ) ,
1457
- ( "d_type" , file_type. into ( ) ) ,
1458
- ] ,
1459
- & entry_place,
1460
- ) ?;
1457
+ // macOS offset field is d_seekoff
1458
+ if this. projectable_has_field ( & entry_place, "d_seekoff" ) {
1459
+ this. write_int_fields_named (
1460
+ & [
1461
+ ( "d_ino" , ino. into ( ) ) ,
1462
+ ( "d_seekoff" , 0 ) ,
1463
+ ( "d_reclen" , 0 ) ,
1464
+ ( "d_namlen" , file_name_len. into ( ) ) ,
1465
+ ( "d_type" , file_type. into ( ) ) ,
1466
+ ] ,
1467
+ & entry_place,
1468
+ ) ?;
1469
+ // freebsd 12 and onwards had added the d_off field
1470
+ } else if this. projectable_has_field ( & entry_place, "d_off" ) {
1471
+ this. write_int_fields_named (
1472
+ & [
1473
+ ( "d_fileno" , ino. into ( ) ) ,
1474
+ ( "d_off" , 0 ) ,
1475
+ ( "d_reclen" , 0 ) ,
1476
+ ( "d_type" , file_type. into ( ) ) ,
1477
+ ( "d_namlen" , file_name_len. into ( ) ) ,
1478
+ ] ,
1479
+ & entry_place,
1480
+ ) ?;
1481
+ } else {
1482
+ this. write_int_fields_named (
1483
+ & [
1484
+ ( "d_fileno" , ino. into ( ) ) ,
1485
+ ( "d_reclen" , 0 ) ,
1486
+ ( "d_type" , file_type. into ( ) ) ,
1487
+ ( "d_namlen" , file_name_len. into ( ) ) ,
1488
+ ] ,
1489
+ & entry_place,
1490
+ ) ?;
1491
+ }
1461
1492
1462
1493
let result_place = this. deref_pointer ( result_op) ?;
1463
1494
this. write_scalar ( this. read_scalar ( entry_op) ?, & result_place) ?;
0 commit comments