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