@@ -990,7 +990,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
990990                // The name is written with write_os_str_to_c_str, while the rest of the 
991991                // dirent struct is written using write_int_fields. 
992992
993-                 // For reference: 
993+                 // For reference, on macOS this looks like : 
994994                // pub struct dirent { 
995995                //     pub d_ino: u64, 
996996                //     pub d_seekoff: u64, 
@@ -1025,40 +1025,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10251025
10261026                let  file_type = this. file_type_to_d_type ( dir_entry. file_type ( ) ) ?; 
10271027
1028-                 // macOS offset field is d_seekoff 
1029-                 if  this. projectable_has_field ( & entry_place,  "d_seekoff" )  { 
1030-                     this. write_int_fields_named ( 
1031-                         & [ 
1032-                             ( "d_ino" ,  ino. into ( ) ) , 
1033-                             ( "d_seekoff" ,  0 ) , 
1034-                             ( "d_reclen" ,  0 ) , 
1035-                             ( "d_namlen" ,  file_name_len. into ( ) ) , 
1036-                             ( "d_type" ,  file_type. into ( ) ) , 
1037-                         ] , 
1038-                         & entry_place, 
1039-                     ) ?; 
1040-                 }  else  if  this. projectable_has_field ( & entry_place,  "d_off" )  { 
1041-                     // freebsd 12 and onwards had added the d_off field 
1042-                     this. write_int_fields_named ( 
1043-                         & [ 
1044-                             ( "d_fileno" ,  ino. into ( ) ) , 
1045-                             ( "d_off" ,  0 ) , 
1046-                             ( "d_reclen" ,  0 ) , 
1047-                             ( "d_type" ,  file_type. into ( ) ) , 
1048-                             ( "d_namlen" ,  file_name_len. into ( ) ) , 
1049-                         ] , 
1050-                         & entry_place, 
1051-                     ) ?; 
1052-                 }  else  { 
1053-                     this. write_int_fields_named ( 
1054-                         & [ 
1055-                             ( "d_fileno" ,  ino. into ( ) ) , 
1056-                             ( "d_reclen" ,  0 ) , 
1057-                             ( "d_type" ,  file_type. into ( ) ) , 
1058-                             ( "d_namlen" ,  file_name_len. into ( ) ) , 
1059-                         ] , 
1060-                         & entry_place, 
1061-                     ) ?; 
1028+                 // Common fields. 
1029+                 this. write_int_fields_named ( 
1030+                     & [ 
1031+                         ( "d_reclen" ,  0 ) , 
1032+                         ( "d_namlen" ,  file_name_len. into ( ) ) , 
1033+                         ( "d_type" ,  file_type. into ( ) ) , 
1034+                     ] , 
1035+                     & entry_place, 
1036+                 ) ?; 
1037+                 // Special fields. 
1038+                 match  & * this. tcx . sess . target . os  { 
1039+                     "macos"  => { 
1040+                         #[ rustfmt:: skip]  
1041+                         this. write_int_fields_named ( 
1042+                             & [ 
1043+                                 ( "d_ino" ,  ino. into ( ) ) , 
1044+                                 ( "d_seekoff" ,  0 ) , 
1045+                             ] , 
1046+                             & entry_place, 
1047+                         ) ?; 
1048+                     } 
1049+                     "freebsd"  => { 
1050+                         this. write_int ( ino,  & this. project_field_named ( & entry_place,  "d_fileno" ) ?) ?; 
1051+                         // `d_off` only exists on FreeBSD 12+, but we support v11 as well. 
1052+                         // `libc` uses a build script to determine which version of the API to use, 
1053+                         // and cross-builds always end up using v11. 
1054+                         // To support both v11 and v12+, we dynamically check whether the field exists. 
1055+                         if  this. projectable_has_field ( & entry_place,  "d_off" )  { 
1056+                             this. write_int ( 0 ,  & this. project_field_named ( & entry_place,  "d_off" ) ?) ?; 
1057+                         } 
1058+                     } 
1059+                     _ => unreachable ! ( ) , 
10621060                } 
10631061
10641062                let  result_place = this. deref_pointer ( result_op) ?; 
0 commit comments