@@ -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