@@ -1048,10 +1048,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10481048 }
10491049 }
10501050
1051- fn linux_readdir64 ( & mut self , dirp_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
1051+ fn linux_solarish_readdir64 ( & mut self , dirp_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
10521052 let this = self . eval_context_mut ( ) ;
10531053
1054- this. assert_target_os ( "linux" , "readdir64" ) ;
1054+ if !matches ! ( & * this. tcx. sess. target. os, "linux" | "solaris" | "illumos" ) {
1055+ panic ! ( "`linux_solaris_readdir64` should not be called on {}" , this. tcx. sess. target. os) ;
1056+ }
10551057
10561058 let dirp = this. read_target_usize ( dirp_op) ?;
10571059
@@ -1086,8 +1088,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10861088 let name_bytes = name. as_encoded_bytes ( ) ;
10871089 let name_len = u64:: try_from ( name_bytes. len ( ) ) . unwrap ( ) ;
10881090
1089- let dirent64_layout = this. libc_ty_layout ( "dirent64" ) ;
1090- let d_name_offset = dirent64_layout. fields . offset ( 4 /* d_name */ ) . bytes ( ) ;
1091+ let is_linux = matches ! ( & * this. tcx. sess. target. os, "linux" ) ;
1092+
1093+ let dirent64_layout = if is_linux {
1094+ this. libc_ty_layout ( "dirent64" )
1095+ } else {
1096+ this. libc_ty_layout ( "dirent" )
1097+ } ;
1098+ let d_name_offset = if is_linux {
1099+ dirent64_layout. fields . offset ( 4 /* d_name */ ) . bytes ( )
1100+ } else {
1101+ dirent64_layout. fields . offset ( 3 /* d_name */ ) . bytes ( )
1102+ } ;
10911103 let size = d_name_offset. strict_add ( name_len) ;
10921104
10931105 let entry = this. allocate_ptr (
@@ -1105,17 +1117,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11051117 let ino = 0u64 ;
11061118
11071119 let file_type = this. file_type_to_d_type ( dir_entry. file_type ( ) ) ?;
1108-
11091120 this. write_int_fields_named (
1110- & [
1111- ( "d_ino" , ino. into ( ) ) ,
1112- ( "d_off" , 0 ) ,
1113- ( "d_reclen" , size. into ( ) ) ,
1114- ( "d_type" , file_type. into ( ) ) ,
1115- ] ,
1121+ & [ ( "d_ino" , ino. into ( ) ) , ( "d_off" , 0 ) , ( "d_reclen" , size. into ( ) ) ] ,
11161122 & this. ptr_to_mplace ( entry, dirent64_layout) ,
11171123 ) ?;
11181124
1125+ if is_linux {
1126+ this. write_int_fields_named (
1127+ & [ ( "d_type" , file_type. into ( ) ) ] ,
1128+ & this. ptr_to_mplace ( entry, dirent64_layout) ,
1129+ ) ?;
1130+ }
1131+
11191132 let name_ptr = entry. wrapping_offset ( Size :: from_bytes ( d_name_offset) , this) ;
11201133 this. write_bytes_ptr ( name_ptr, name_bytes. iter ( ) . copied ( ) ) ?;
11211134
0 commit comments