@@ -813,24 +813,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
813813
814814 fn lseek64 (
815815 & mut self ,
816- fd_op : & OpTy < ' tcx , Provenance > ,
817- offset_op : & OpTy < ' tcx , Provenance > ,
818- whence_op : & OpTy < ' tcx , Provenance > ,
816+ fd : i32 ,
817+ offset : i128 ,
818+ whence : i32 ,
819819 ) -> InterpResult < ' tcx , Scalar < Provenance > > {
820820 let this = self . eval_context_mut ( ) ;
821821
822822 // Isolation check is done via `FileDescriptor` trait.
823823
824- let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
825- let offset = this. read_scalar ( offset_op) ?. to_i64 ( ) ?;
826- let whence = this. read_scalar ( whence_op) ?. to_i32 ( ) ?;
827-
828824 let seek_from = if whence == this. eval_libc_i32 ( "SEEK_SET" ) {
829825 SeekFrom :: Start ( u64:: try_from ( offset) . unwrap ( ) )
830826 } else if whence == this. eval_libc_i32 ( "SEEK_CUR" ) {
831- SeekFrom :: Current ( offset)
827+ SeekFrom :: Current ( i64 :: try_from ( offset) . unwrap ( ) )
832828 } else if whence == this. eval_libc_i32 ( "SEEK_END" ) {
833- SeekFrom :: End ( offset)
829+ SeekFrom :: End ( i64 :: try_from ( offset) . unwrap ( ) )
834830 } else {
835831 let einval = this. eval_libc ( "EINVAL" ) ;
836832 this. set_last_error ( einval) ?;
@@ -897,13 +893,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
897893 this. try_unwrap_io_result ( result)
898894 }
899895
900- fn macos_stat (
896+ fn macos_fbsd_stat (
901897 & mut self ,
902898 path_op : & OpTy < ' tcx , Provenance > ,
903899 buf_op : & OpTy < ' tcx , Provenance > ,
904900 ) -> InterpResult < ' tcx , Scalar < Provenance > > {
905901 let this = self . eval_context_mut ( ) ;
906- this. assert_target_os ( "macos" , "stat" ) ;
902+
903+ if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
904+ panic ! ( "`macos_fbsd_stat` should not be called on {}" , this. tcx. sess. target. os) ;
905+ }
907906
908907 let path_scalar = this. read_pointer ( path_op) ?;
909908 let path = this. read_path_from_c_str ( path_scalar) ?. into_owned ( ) ;
@@ -926,13 +925,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
926925 }
927926
928927 // `lstat` is used to get symlink metadata.
929- fn macos_lstat (
928+ fn macos_fbsd_lstat (
930929 & mut self ,
931930 path_op : & OpTy < ' tcx , Provenance > ,
932931 buf_op : & OpTy < ' tcx , Provenance > ,
933932 ) -> InterpResult < ' tcx , Scalar < Provenance > > {
934933 let this = self . eval_context_mut ( ) ;
935- this. assert_target_os ( "macos" , "lstat" ) ;
934+
935+ if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
936+ panic ! ( "`macos_fbsd_lstat` should not be called on {}" , this. tcx. sess. target. os) ;
937+ }
936938
937939 let path_scalar = this. read_pointer ( path_op) ?;
938940 let path = this. read_path_from_c_str ( path_scalar) ?. into_owned ( ) ;
@@ -953,14 +955,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
953955 Ok ( Scalar :: from_i32 ( this. macos_stat_write_buf ( metadata, buf_op) ?) )
954956 }
955957
956- fn macos_fstat (
958+ fn macos_fbsd_fstat (
957959 & mut self ,
958960 fd_op : & OpTy < ' tcx , Provenance > ,
959961 buf_op : & OpTy < ' tcx , Provenance > ,
960962 ) -> InterpResult < ' tcx , Scalar < Provenance > > {
961963 let this = self . eval_context_mut ( ) ;
962964
963- this. assert_target_os ( "macos" , "fstat" ) ;
965+ if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
966+ panic ! ( "`macos_fbsd_fstat` should not be called on {}" , this. tcx. sess. target. os) ;
967+ }
964968
965969 let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
966970
@@ -1199,7 +1203,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
11991203 let this = self . eval_context_mut ( ) ;
12001204
12011205 #[ cfg_attr( not( unix) , allow( unused_variables) ) ]
1202- let mode = if this. tcx . sess . target . os == "macos" {
1206+ let mode = if matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
12031207 u32:: from ( this. read_scalar ( mode_op) ?. to_u16 ( ) ?)
12041208 } else {
12051209 this. read_scalar ( mode_op) ?. to_u32 ( ) ?
@@ -1371,15 +1375,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
13711375 Ok ( Scalar :: from_maybe_pointer ( entry, this) )
13721376 }
13731377
1374- fn macos_readdir_r (
1378+ fn macos_fbsd_readdir_r (
13751379 & mut self ,
13761380 dirp_op : & OpTy < ' tcx , Provenance > ,
13771381 entry_op : & OpTy < ' tcx , Provenance > ,
13781382 result_op : & OpTy < ' tcx , Provenance > ,
13791383 ) -> InterpResult < ' tcx , Scalar < Provenance > > {
13801384 let this = self . eval_context_mut ( ) ;
13811385
1382- this. assert_target_os ( "macos" , "readdir_r" ) ;
1386+ if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
1387+ panic ! ( "`macos_fbsd_readdir_r` should not be called on {}" , this. tcx. sess. target. os) ;
1388+ }
13831389
13841390 let dirp = this. read_target_usize ( dirp_op) ?;
13851391
@@ -1410,7 +1416,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
14101416 // }
14111417
14121418 let entry_place = this. deref_pointer_as ( entry_op, this. libc_ty_layout ( "dirent" ) ) ?;
1413- let name_place = this. project_field ( & entry_place, 5 ) ?;
1419+ let name_place = this. project_field_named ( & entry_place, "d_name" ) ?;
14141420
14151421 let file_name = dir_entry. file_name ( ) ; // not a Path as there are no separators!
14161422 let ( name_fits, file_name_buf_len) = this. write_os_str_to_c_str (
@@ -1434,16 +1440,41 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
14341440
14351441 let file_type = this. file_type_to_d_type ( dir_entry. file_type ( ) ) ?;
14361442
1437- this. write_int_fields_named (
1438- & [
1439- ( "d_ino" , ino. into ( ) ) ,
1440- ( "d_seekoff" , 0 ) ,
1441- ( "d_reclen" , 0 ) ,
1442- ( "d_namlen" , file_name_len. into ( ) ) ,
1443- ( "d_type" , file_type. into ( ) ) ,
1444- ] ,
1445- & entry_place,
1446- ) ?;
1443+ // macOS offset field is d_seekoff
1444+ if this. projectable_has_field ( & entry_place, "d_seekoff" ) {
1445+ this. write_int_fields_named (
1446+ & [
1447+ ( "d_ino" , ino. into ( ) ) ,
1448+ ( "d_seekoff" , 0 ) ,
1449+ ( "d_reclen" , 0 ) ,
1450+ ( "d_namlen" , file_name_len. into ( ) ) ,
1451+ ( "d_type" , file_type. into ( ) ) ,
1452+ ] ,
1453+ & entry_place,
1454+ ) ?;
1455+ } else if this. projectable_has_field ( & entry_place, "d_off" ) {
1456+ // freebsd 12 and onwards had added the d_off field
1457+ this. write_int_fields_named (
1458+ & [
1459+ ( "d_fileno" , ino. into ( ) ) ,
1460+ ( "d_off" , 0 ) ,
1461+ ( "d_reclen" , 0 ) ,
1462+ ( "d_type" , file_type. into ( ) ) ,
1463+ ( "d_namlen" , file_name_len. into ( ) ) ,
1464+ ] ,
1465+ & entry_place,
1466+ ) ?;
1467+ } else {
1468+ this. write_int_fields_named (
1469+ & [
1470+ ( "d_fileno" , ino. into ( ) ) ,
1471+ ( "d_reclen" , 0 ) ,
1472+ ( "d_type" , file_type. into ( ) ) ,
1473+ ( "d_namlen" , file_name_len. into ( ) ) ,
1474+ ] ,
1475+ & entry_place,
1476+ ) ?;
1477+ }
14471478
14481479 let result_place = this. deref_pointer ( result_op) ?;
14491480 this. write_scalar ( this. read_scalar ( entry_op) ?, & result_place) ?;
0 commit comments