@@ -47,7 +47,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
47
47
let min_align = match this.tcx.sess.target.arch.as_ref() {
48
48
"x86" | "arm" | "mips" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8,
49
49
"x86_64" | "aarch64" | "mips64" | "s390x" | "sparc64" => 16,
50
- arch => bug!("Unsupported target architecture: {} ", arch),
50
+ arch => bug!("unsupported target architecture for malloc: `{}` ", arch),
51
51
};
52
52
// Windows always aligns, even small allocations.
53
53
// Source: <https://support.microsoft.com/en-us/help/286470/how-to-use-pageheap-exe-in-windows-xp-windows-2000-and-windows-server>
@@ -320,7 +320,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
320
320
return Ok(Some(body));
321
321
}
322
322
323
- this.handle_unsupported(format!("can't call foreign function: {link_name}"))?;
323
+ this.handle_unsupported(format!(
324
+ "can't call foreign function `{link_name}` on OS `{os}`",
325
+ os = this.tcx.sess.target.os,
326
+ ))?;
324
327
return Ok(None);
325
328
}
326
329
}
@@ -336,9 +339,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
336
339
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
337
340
let this = self.eval_context_mut();
338
341
339
- let allocator_kind = if let Some(allocator_kind) = this.tcx.allocator_kind(()) {
340
- allocator_kind
341
- } else {
342
+ let Some(allocator_kind) = this.tcx.allocator_kind(()) else {
342
343
// in real code, this symbol does not exist without an allocator
343
344
return Ok(EmulateByNameResult::NotSupported);
344
345
};
@@ -420,9 +421,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
420
421
let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
421
422
let ptr = this.read_pointer(ptr)?;
422
423
let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr).map_err(|_e| {
423
- err_machine_stop!(TerminationInfo::Abort(
424
- format!( "pointer passed to miri_get_alloc_id must not be dangling, got {ptr:?}")
425
- ))
424
+ err_machine_stop!(TerminationInfo::Abort(format!(
425
+ "pointer passed to miri_get_alloc_id must not be dangling, got {ptr:?}"
426
+ )))
426
427
})?;
427
428
this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?;
428
429
}
@@ -438,7 +439,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
438
439
let ptr = this.read_pointer(ptr)?;
439
440
let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr)?;
440
441
if offset != Size::ZERO {
441
- throw_unsup_format!("pointer passed to miri_static_root must point to beginning of an allocated block");
442
+ throw_unsup_format!(
443
+ "pointer passed to miri_static_root must point to beginning of an allocated block"
444
+ );
442
445
}
443
446
this.machine.static_roots.push(alloc_id);
444
447
}
@@ -453,7 +456,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
453
456
454
457
// We read this as a plain OsStr and write it as a path, which will convert it to the target.
455
458
let path = this.read_os_str_from_c_str(ptr)?.to_owned();
456
- let (success, needed_size) = this.write_path_to_c_str(Path::new(&path), out, out_size)?;
459
+ let (success, needed_size) =
460
+ this.write_path_to_c_str(Path::new(&path), out, out_size)?;
457
461
// Return value: 0 on success, otherwise the size it would have needed.
458
462
this.write_int(if success { 0 } else { needed_size }, dest)?;
459
463
}
@@ -505,11 +509,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
505
509
this.write_pointer(res, dest)?;
506
510
}
507
511
"calloc" => {
508
- let [items, len] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
512
+ let [items, len] =
513
+ this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
509
514
let items = this.read_machine_usize(items)?;
510
515
let len = this.read_machine_usize(len)?;
511
- let size =
512
- items.checked_mul(len).ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?;
516
+ let size = items
517
+ .checked_mul(len)
518
+ .ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?;
513
519
let res = this.malloc(size, /*zero_init:*/ true, MiriMemoryKind::C)?;
514
520
this.write_pointer(res, dest)?;
515
521
}
@@ -519,7 +525,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
519
525
this.free(ptr, MiriMemoryKind::C)?;
520
526
}
521
527
"realloc" => {
522
- let [old_ptr, new_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
528
+ let [old_ptr, new_size] =
529
+ this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
523
530
let old_ptr = this.read_pointer(old_ptr)?;
524
531
let new_size = this.read_machine_usize(new_size)?;
525
532
let res = this.realloc(old_ptr, new_size, MiriMemoryKind::C)?;
@@ -551,11 +558,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
551
558
};
552
559
553
560
match link_name.as_str() {
554
- "__rust_alloc" => return this.emulate_allocator(Symbol::intern("__rg_alloc"), default),
561
+ "__rust_alloc" =>
562
+ return this.emulate_allocator(Symbol::intern("__rg_alloc"), default),
555
563
"miri_alloc" => {
556
564
default(this)?;
557
565
return Ok(EmulateByNameResult::NeedsJumping);
558
- },
566
+ }
559
567
_ => unreachable!(),
560
568
}
561
569
}
@@ -574,7 +582,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
574
582
)?;
575
583
576
584
// We just allocated this, the access is definitely in-bounds.
577
- this.write_bytes_ptr(ptr.into(), iter::repeat(0u8).take(usize::try_from(size).unwrap())).unwrap();
585
+ this.write_bytes_ptr(
586
+ ptr.into(),
587
+ iter::repeat(0u8).take(usize::try_from(size).unwrap()),
588
+ )
589
+ .unwrap();
578
590
this.write_pointer(ptr, dest)
579
591
});
580
592
}
@@ -600,7 +612,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
600
612
};
601
613
602
614
match link_name.as_str() {
603
- "__rust_dealloc" => return this.emulate_allocator(Symbol::intern("__rg_dealloc"), default),
615
+ "__rust_dealloc" =>
616
+ return this.emulate_allocator(Symbol::intern("__rg_dealloc"), default),
604
617
"miri_dealloc" => {
605
618
default(this)?;
606
619
return Ok(EmulateByNameResult::NeedsJumping);
@@ -609,7 +622,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
609
622
}
610
623
}
611
624
"__rust_realloc" => {
612
- let [ptr, old_size, align, new_size] = this.check_shim(abi, Abi::Rust, link_name, args)?;
625
+ let [ptr, old_size, align, new_size] =
626
+ this.check_shim(abi, Abi::Rust, link_name, args)?;
613
627
let ptr = this.read_pointer(ptr)?;
614
628
let old_size = this.read_machine_usize(old_size)?;
615
629
let align = this.read_machine_usize(align)?;
@@ -633,7 +647,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
633
647
634
648
// C memory handling functions
635
649
"memcmp" => {
636
- let [left, right, n] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
650
+ let [left, right, n] =
651
+ this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
637
652
let left = this.read_pointer(left)?;
638
653
let right = this.read_pointer(right)?;
639
654
let n = Size::from_bytes(this.read_machine_usize(n)?);
@@ -653,7 +668,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
653
668
this.write_scalar(Scalar::from_i32(result), dest)?;
654
669
}
655
670
"memrchr" => {
656
- let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
671
+ let [ptr, val, num] =
672
+ this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
657
673
let ptr = this.read_pointer(ptr)?;
658
674
let val = this.read_scalar(val)?.to_i32()?;
659
675
let num = this.read_machine_usize(num)?;
@@ -676,7 +692,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
676
692
}
677
693
}
678
694
"memchr" => {
679
- let [ptr, val, num] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
695
+ let [ptr, val, num] =
696
+ this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
680
697
let ptr = this.read_pointer(ptr)?;
681
698
let val = this.read_scalar(val)?.to_i32()?;
682
699
let num = this.read_machine_usize(num)?;
@@ -699,7 +716,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
699
716
let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
700
717
let ptr = this.read_pointer(ptr)?;
701
718
let n = this.read_c_str(ptr)?.len();
702
- this.write_scalar(Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), dest)?;
719
+ this.write_scalar(
720
+ Scalar::from_machine_usize(u64::try_from(n).unwrap(), this),
721
+ dest,
722
+ )?;
703
723
}
704
724
705
725
// math functions (note that there are also intrinsics for some other functions)
@@ -835,7 +855,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
835
855
let a = this.read_scalar(a)?.to_u64()?;
836
856
let b = this.read_scalar(b)?.to_u64()?;
837
857
838
- #[allow(clippy::integer_arithmetic)] // adding two u64 and a u8 cannot wrap in a u128
858
+ #[allow(clippy::integer_arithmetic)]
859
+ // adding two u64 and a u8 cannot wrap in a u128
839
860
let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b);
840
861
#[allow(clippy::integer_arithmetic)] // it's a u128, we can shift by 64
841
862
let (c_out, sum) = ((wide_sum >> 64).truncate::<u8>(), wide_sum.truncate::<u64>());
@@ -845,15 +866,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
845
866
let sum_field = this.place_field(dest, 1)?;
846
867
this.write_scalar(Scalar::from_u64(sum), &sum_field)?;
847
868
}
848
- "llvm.x86.sse2.pause" if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" => {
869
+ "llvm.x86.sse2.pause"
870
+ if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" =>
871
+ {
849
872
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
850
873
this.yield_active_thread();
851
874
}
852
875
"llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => {
853
876
let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
854
877
let arg = this.read_scalar(arg)?.to_i32()?;
855
878
match arg {
856
- 15 => { // SY ("full system scope")
879
+ // SY ("full system scope")
880
+ 15 => {
857
881
this.yield_active_thread();
858
882
}
859
883
_ => {
@@ -863,11 +887,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
863
887
}
864
888
865
889
// Platform-specific shims
866
- _ => match this.tcx.sess.target.os.as_ref() {
867
- target if target_os_is_unix(target) => return shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
868
- "windows" => return shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
869
- target => throw_unsup_format!("the target `{}` is not supported", target),
870
- }
890
+ _ =>
891
+ return match this.tcx.sess.target.os.as_ref() {
892
+ target_os if target_os_is_unix(target_os) =>
893
+ shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(
894
+ this, link_name, abi, args, dest,
895
+ ),
896
+ "windows" =>
897
+ shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name(
898
+ this, link_name, abi, args, dest,
899
+ ),
900
+ _ => Ok(EmulateByNameResult::NotSupported),
901
+ },
871
902
};
872
903
// We only fall through to here if we did *not* hit the `_` arm above,
873
904
// i.e., if we actually emulated the function with one of the shims.
0 commit comments