@@ -900,14 +900,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
900900 }
901901 }
902902
903- fn linux_solarish_readdir64 (
904- & mut self ,
905- dirent_type : & str ,
906- dirp_op : & OpTy < ' tcx > ,
907- ) -> InterpResult < ' tcx , Scalar > {
903+ fn readdir64 ( & mut self , dirent_type : & str , dirp_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
908904 let this = self . eval_context_mut ( ) ;
909905
910- if !matches ! ( & * this. tcx. sess. target. os, "linux" | "solaris" | "illumos" ) {
906+ if !matches ! (
907+ & * this. tcx. sess. target. os,
908+ "linux" | "solaris" | "illumos" | "macos" | "freebsd"
909+ ) {
911910 panic ! ( "`linux_solaris_readdir64` should not be called on {}" , this. tcx. sess. target. os) ;
912911 }
913912
@@ -947,6 +946,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
947946 // pub d_reclen: c_ushort,
948947 // pub d_name: [c_char; 3],
949948 // }
949+ //
950+ // On FreeBSD:
951+ // pub struct dirent{
952+ // pub d_fileno: uint32_t,
953+ // pub d_reclen: uint16_t,
954+ // pub d_type: uint8_t,
955+ // pub d_namlen: uint8_t,
956+ // pub d_name: [c_char; 256]
957+ // }
958+ //
959+ // On Macos:
960+ // pub struct dirent {
961+ // pub d_ino: u64,
962+ // pub d_seekoff: u64,
963+ // pub d_reclen: u16,
964+ // pub d_namlen: u16,
965+ // pub d_type: u8,
966+ // pub d_name: [c_char; 1024],
967+ // }
950968
951969 let mut name = dir_entry. file_name ( ) ; // not a Path as there are no separators!
952970 name. push ( "\0 " ) ; // Add a NUL terminator
@@ -966,6 +984,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
966984 AllocInit :: Uninit ,
967985 ) ?;
968986 let entry: Pointer = entry. into ( ) ;
987+ let entry_place = & this. ptr_to_mplace ( entry, dirent_layout) ;
969988
970989 // If the host is a Unix system, fill in the inode number with its real value.
971990 // If not, use 0 as a fallback value.
@@ -974,15 +993,42 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
974993 #[ cfg( not( unix) ) ]
975994 let ino = 0u64 ;
976995
977- let file_type = this. file_type_to_d_type ( dir_entry. file_type ( ) ) ?;
996+ // Write common fields
997+ let ino_name =
998+ if this. tcx . sess . target . os == "freebsd" { "d_fileno" } else { "d_ino " } ;
978999 this. write_int_fields_named (
979- & [ ( "d_ino" , ino. into ( ) ) , ( "d_off" , 0 ) , ( "d_reclen" , size. into ( ) ) ] ,
980- & this . ptr_to_mplace ( entry , dirent_layout ) ,
1000+ & [ ( ino_name , ino. into ( ) ) , ( "d_reclen" , size. into ( ) ) ] ,
1001+ entry_place ,
9811002 ) ?;
9821003
983- if let Some ( d_type) = this
984- . try_project_field_named ( & this. ptr_to_mplace ( entry, dirent_layout) , "d_type" ) ?
985- {
1004+ // Hanlde os specific fields
1005+ match & * this. tcx . sess . target . os {
1006+ "macos" => {
1007+ this. write_int_fields_named (
1008+ & [
1009+ ( "d_seekoff" , 0 ) ,
1010+ ( "d_namlen" , ( name_len - 1 ) . into ( ) ) , // Zero Byte not included
1011+ ] ,
1012+ entry_place,
1013+ ) ?;
1014+ }
1015+ "freebsd" => {
1016+ this. write_int_fields_named (
1017+ & [
1018+ ( "d_off" , 0 ) ,
1019+ ( "d_namlen" , ( name_len - 1 ) . into ( ) ) , // Zero Byte not included
1020+ ] ,
1021+ entry_place,
1022+ ) ?;
1023+ }
1024+ "linux" | "solaris" | "illumos" => {
1025+ this. write_int_fields_named ( & [ ( "d_off" , 0 ) ] , entry_place) ?;
1026+ }
1027+ _ => unreachable ! ( ) ,
1028+ }
1029+
1030+ let file_type = this. file_type_to_d_type ( dir_entry. file_type ( ) ) ?;
1031+ if let Some ( d_type) = this. try_project_field_named ( entry_place, "d_type" ) ? {
9861032 this. write_int ( file_type, & d_type) ?;
9871033 }
9881034
0 commit comments