@@ -990,7 +990,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
990
990
// The name is written with write_os_str_to_c_str, while the rest of the
991
991
// dirent struct is written using write_int_fields.
992
992
993
- // For reference:
993
+ // For reference, on macOS this looks like :
994
994
// pub struct dirent {
995
995
// pub d_ino: u64,
996
996
// pub d_seekoff: u64,
@@ -1025,40 +1025,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1025
1025
1026
1026
let file_type = this. file_type_to_d_type ( dir_entry. file_type ( ) ) ?;
1027
1027
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 ! ( ) ,
1062
1060
}
1063
1061
1064
1062
let result_place = this. deref_pointer ( result_op) ?;
0 commit comments