@@ -813,24 +813,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
813
813
814
814
fn lseek64(
815
815
&mut self,
816
- fd_op: &OpTy<'tcx, Provenance> ,
817
- offset_op: &OpTy<'tcx, Provenance> ,
818
- whence_op: &OpTy<'tcx, Provenance> ,
816
+ fd: i32 ,
817
+ offset: i128 ,
818
+ whence: i32 ,
819
819
) -> InterpResult<'tcx, Scalar<Provenance>> {
820
820
let this = self.eval_context_mut();
821
821
822
822
// Isolation check is done via `FileDescriptor` trait.
823
823
824
- let fd = this.read_scalar(fd_op)?.to_i32()?;
825
- let offset = this.read_scalar(offset_op)?.to_i64()?;
826
- let whence = this.read_scalar(whence_op)?.to_i32()?;
827
-
828
824
let seek_from = if whence == this.eval_libc_i32("SEEK_SET") {
829
825
SeekFrom::Start(u64::try_from(offset).unwrap())
830
826
} else if whence == this.eval_libc_i32("SEEK_CUR") {
831
- SeekFrom::Current(offset)
827
+ SeekFrom::Current(i64::try_from( offset).unwrap() )
832
828
} else if whence == this.eval_libc_i32("SEEK_END") {
833
- SeekFrom::End(offset)
829
+ SeekFrom::End(i64::try_from( offset).unwrap() )
834
830
} else {
835
831
let einval = this.eval_libc("EINVAL");
836
832
this.set_last_error(einval)?;
@@ -897,13 +893,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
897
893
this.try_unwrap_io_result(result)
898
894
}
899
895
900
- fn macos_stat (
896
+ fn macos_fbsd_stat (
901
897
&mut self,
902
898
path_op: &OpTy<'tcx, Provenance>,
903
899
buf_op: &OpTy<'tcx, Provenance>,
904
900
) -> InterpResult<'tcx, Scalar<Provenance>> {
905
901
let this = self.eval_context_mut();
906
- this.assert_target_os("macos", "stat");
902
+
903
+ if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
904
+ panic!("`macos_fbsd_stat` should not be called on {}", this.tcx.sess.target.os);
905
+ }
907
906
908
907
let path_scalar = this.read_pointer(path_op)?;
909
908
let path = this.read_path_from_c_str(path_scalar)?.into_owned();
@@ -926,13 +925,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
926
925
}
927
926
928
927
// `lstat` is used to get symlink metadata.
929
- fn macos_lstat (
928
+ fn macos_fbsd_lstat (
930
929
&mut self,
931
930
path_op: &OpTy<'tcx, Provenance>,
932
931
buf_op: &OpTy<'tcx, Provenance>,
933
932
) -> InterpResult<'tcx, Scalar<Provenance>> {
934
933
let this = self.eval_context_mut();
935
- this.assert_target_os("macos", "lstat");
934
+
935
+ if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
936
+ panic!("`macos_fbsd_lstat` should not be called on {}", this.tcx.sess.target.os);
937
+ }
936
938
937
939
let path_scalar = this.read_pointer(path_op)?;
938
940
let path = this.read_path_from_c_str(path_scalar)?.into_owned();
@@ -953,14 +955,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
953
955
Ok(Scalar::from_i32(this.macos_stat_write_buf(metadata, buf_op)?))
954
956
}
955
957
956
- fn macos_fstat (
958
+ fn macos_fbsd_fstat (
957
959
&mut self,
958
960
fd_op: &OpTy<'tcx, Provenance>,
959
961
buf_op: &OpTy<'tcx, Provenance>,
960
962
) -> InterpResult<'tcx, Scalar<Provenance>> {
961
963
let this = self.eval_context_mut();
962
964
963
- this.assert_target_os("macos", "fstat");
965
+ if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
966
+ panic!("`macos_fbsd_fstat` should not be called on {}", this.tcx.sess.target.os);
967
+ }
964
968
965
969
let fd = this.read_scalar(fd_op)?.to_i32()?;
966
970
@@ -1199,7 +1203,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1199
1203
let this = self.eval_context_mut();
1200
1204
1201
1205
#[cfg_attr(not(unix), allow(unused_variables))]
1202
- let mode = if this.tcx.sess.target.os == "macos" {
1206
+ let mode = if matches!(&* this.tcx.sess.target.os, "macos" | "freebsd") {
1203
1207
u32::from(this.read_scalar(mode_op)?.to_u16()?)
1204
1208
} else {
1205
1209
this.read_scalar(mode_op)?.to_u32()?
@@ -1371,15 +1375,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1371
1375
Ok(Scalar::from_maybe_pointer(entry, this))
1372
1376
}
1373
1377
1374
- fn macos_readdir_r (
1378
+ fn macos_fbsd_readdir_r (
1375
1379
&mut self,
1376
1380
dirp_op: &OpTy<'tcx, Provenance>,
1377
1381
entry_op: &OpTy<'tcx, Provenance>,
1378
1382
result_op: &OpTy<'tcx, Provenance>,
1379
1383
) -> InterpResult<'tcx, Scalar<Provenance>> {
1380
1384
let this = self.eval_context_mut();
1381
1385
1382
- this.assert_target_os("macos", "readdir_r");
1386
+ if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
1387
+ panic!("`macos_fbsd_readdir_r` should not be called on {}", this.tcx.sess.target.os);
1388
+ }
1383
1389
1384
1390
let dirp = this.read_target_usize(dirp_op)?;
1385
1391
@@ -1410,7 +1416,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1410
1416
// }
1411
1417
1412
1418
let entry_place = this.deref_pointer_as(entry_op, this.libc_ty_layout("dirent"))?;
1413
- let name_place = this.project_field (&entry_place, 5 )?;
1419
+ let name_place = this.project_field_named (&entry_place, "d_name" )?;
1414
1420
1415
1421
let file_name = dir_entry.file_name(); // not a Path as there are no separators!
1416
1422
let (name_fits, file_name_buf_len) = this.write_os_str_to_c_str(
@@ -1434,16 +1440,41 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1434
1440
1435
1441
let file_type = this.file_type_to_d_type(dir_entry.file_type())?;
1436
1442
1437
- this.write_int_fields_named(
1438
- &[
1439
- ("d_ino", ino.into()),
1440
- ("d_seekoff", 0),
1441
- ("d_reclen", 0),
1442
- ("d_namlen", file_name_len.into()),
1443
- ("d_type", file_type.into()),
1444
- ],
1445
- &entry_place,
1446
- )?;
1443
+ // macOS offset field is d_seekoff
1444
+ if this.projectable_has_field(&entry_place, "d_seekoff") {
1445
+ this.write_int_fields_named(
1446
+ &[
1447
+ ("d_ino", ino.into()),
1448
+ ("d_seekoff", 0),
1449
+ ("d_reclen", 0),
1450
+ ("d_namlen", file_name_len.into()),
1451
+ ("d_type", file_type.into()),
1452
+ ],
1453
+ &entry_place,
1454
+ )?;
1455
+ } else if this.projectable_has_field(&entry_place, "d_off") {
1456
+ // freebsd 12 and onwards had added the d_off field
1457
+ this.write_int_fields_named(
1458
+ &[
1459
+ ("d_fileno", ino.into()),
1460
+ ("d_off", 0),
1461
+ ("d_reclen", 0),
1462
+ ("d_type", file_type.into()),
1463
+ ("d_namlen", file_name_len.into()),
1464
+ ],
1465
+ &entry_place,
1466
+ )?;
1467
+ } else {
1468
+ this.write_int_fields_named(
1469
+ &[
1470
+ ("d_fileno", ino.into()),
1471
+ ("d_reclen", 0),
1472
+ ("d_type", file_type.into()),
1473
+ ("d_namlen", file_name_len.into()),
1474
+ ],
1475
+ &entry_place,
1476
+ )?;
1477
+ }
1447
1478
1448
1479
let result_place = this.deref_pointer(result_op)?;
1449
1480
this.write_scalar(this.read_scalar(entry_op)?, &result_place)?;
0 commit comments