Skip to content

Commit 6a563c9

Browse files
committed
Revert some miri changes
1 parent 48ec50d commit 6a563c9

28 files changed

+309
-350
lines changed

src/tools/miri/src/helpers.rs

+15
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
960960
return interp_ok(());
961961
}
962962

963+
if ["__rust_alloc", "__rust_alloc_zeroed", "__rust_realloc", "__rust_dealloc"]
964+
.contains(&link_name.as_str())
965+
{
966+
let attrs = self.eval_context_ref().tcx.codegen_fn_attrs(instance.def_id());
967+
if attrs
968+
.linkage
969+
.map_or(false, |linkage| linkage == rustc_middle::mir::mono::Linkage::WeakAny)
970+
&& attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
971+
{
972+
// We intentionally intercept the allocator methods even though libstd provides
973+
// default implementations.
974+
return interp_ok(());
975+
}
976+
}
977+
963978
throw_machine_stop!(TerminationInfo::SymbolShimClashing {
964979
link_name,
965980
span: body.span.data(),

src/tools/miri/src/shims/alloc.rs

+29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::iter;
22

33
use rustc_abi::{Align, Size};
4+
use rustc_ast::expand::allocator::AllocatorKind;
45

56
use crate::*;
67

@@ -51,6 +52,34 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
5152
Align::from_bytes(prev_power_of_two(size)).unwrap()
5253
}
5354

55+
/// Emulates calling the internal __rust_* allocator functions
56+
fn emulate_allocator(
57+
&mut self,
58+
default: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx>,
59+
) -> InterpResult<'tcx, EmulateItemResult> {
60+
let this = self.eval_context_mut();
61+
62+
let Some(allocator_kind) = this.tcx.allocator_kind(()) else {
63+
// in real code, this symbol does not exist without an allocator
64+
return interp_ok(EmulateItemResult::NotSupported);
65+
};
66+
67+
match allocator_kind {
68+
AllocatorKind::Global => {
69+
// When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion
70+
// of this attribute. As such we have to call an exported Rust function,
71+
// and not execute any Miri shim. Somewhat unintuitively doing so is done
72+
// by returning `NotSupported`, which triggers the `lookup_exported_symbol`
73+
// fallback case in `emulate_foreign_item`.
74+
interp_ok(EmulateItemResult::NotSupported)
75+
}
76+
AllocatorKind::Default => {
77+
default(this)?;
78+
interp_ok(EmulateItemResult::NeedsReturn)
79+
}
80+
}
81+
}
82+
5483
fn malloc(&mut self, size: u64, zero_init: bool) -> InterpResult<'tcx, Pointer> {
5584
let this = self.eval_context_mut();
5685
let align = this.malloc_align(size);

src/tools/miri/src/shims/foreign_items.rs

+114-22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::collections::hash_map::Entry;
22
use std::io::Write;
3+
use std::iter;
34
use std::path::Path;
45

56
use rustc_abi::{Align, AlignFromBytesError, Size};
@@ -501,33 +502,124 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
501502
}
502503

503504
// Rust allocation
504-
"miri_alloc" => {
505-
let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?;
506-
let size = this.read_target_usize(size)?;
507-
let align = this.read_target_usize(align)?;
505+
"__rust_alloc" | "miri_alloc" => {
506+
let default = |ecx: &mut MiriInterpCx<'tcx>| {
507+
// Only call `check_shim` when `#[global_allocator]` isn't used. When that
508+
// macro is used, we act like no shim exists, so that the exported function can run.
509+
let [size, align] = ecx.check_shim(abi, Conv::Rust, link_name, args)?;
510+
let size = ecx.read_target_usize(size)?;
511+
let align = ecx.read_target_usize(align)?;
512+
513+
ecx.check_rustc_alloc_request(size, align)?;
514+
515+
let memory_kind = match link_name.as_str() {
516+
"__rust_alloc" => MiriMemoryKind::Rust,
517+
"miri_alloc" => MiriMemoryKind::Miri,
518+
_ => unreachable!(),
519+
};
508520

509-
this.check_rustc_alloc_request(size, align)?;
521+
let ptr = ecx.allocate_ptr(
522+
Size::from_bytes(size),
523+
Align::from_bytes(align).unwrap(),
524+
memory_kind.into(),
525+
)?;
510526

511-
let ptr = this.allocate_ptr(
512-
Size::from_bytes(size),
513-
Align::from_bytes(align).unwrap(),
514-
MiriMemoryKind::Miri.into(),
515-
)?;
527+
ecx.write_pointer(ptr, dest)
528+
};
516529

517-
this.write_pointer(ptr, dest)?;
530+
match link_name.as_str() {
531+
"__rust_alloc" => return this.emulate_allocator(default),
532+
"miri_alloc" => {
533+
default(this)?;
534+
return interp_ok(EmulateItemResult::NeedsReturn);
535+
}
536+
_ => unreachable!(),
537+
}
518538
}
519-
"miri_dealloc" => {
520-
let [ptr, old_size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?;
521-
let ptr = this.read_pointer(ptr)?;
522-
let old_size = this.read_target_usize(old_size)?;
523-
let align = this.read_target_usize(align)?;
539+
"__rust_alloc_zeroed" => {
540+
return this.emulate_allocator(|this| {
541+
// See the comment for `__rust_alloc` why `check_shim` is only called in the
542+
// default case.
543+
let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?;
544+
let size = this.read_target_usize(size)?;
545+
let align = this.read_target_usize(align)?;
524546

525-
// No need to check old_size/align; we anyway check that they match the allocation.
526-
this.deallocate_ptr(
527-
ptr,
528-
Some((Size::from_bytes(old_size), Align::from_bytes(align).unwrap())),
529-
MiriMemoryKind::Miri.into(),
530-
)?;
547+
this.check_rustc_alloc_request(size, align)?;
548+
549+
let ptr = this.allocate_ptr(
550+
Size::from_bytes(size),
551+
Align::from_bytes(align).unwrap(),
552+
MiriMemoryKind::Rust.into(),
553+
)?;
554+
555+
// We just allocated this, the access is definitely in-bounds.
556+
this.write_bytes_ptr(
557+
ptr.into(),
558+
iter::repeat(0u8).take(usize::try_from(size).unwrap()),
559+
)
560+
.unwrap();
561+
this.write_pointer(ptr, dest)
562+
});
563+
}
564+
"__rust_dealloc" | "miri_dealloc" => {
565+
let default = |ecx: &mut MiriInterpCx<'tcx>| {
566+
// See the comment for `__rust_alloc` why `check_shim` is only called in the
567+
// default case.
568+
let [ptr, old_size, align] =
569+
ecx.check_shim(abi, Conv::Rust, link_name, args)?;
570+
let ptr = ecx.read_pointer(ptr)?;
571+
let old_size = ecx.read_target_usize(old_size)?;
572+
let align = ecx.read_target_usize(align)?;
573+
574+
let memory_kind = match link_name.as_str() {
575+
"__rust_dealloc" => MiriMemoryKind::Rust,
576+
"miri_dealloc" => MiriMemoryKind::Miri,
577+
_ => unreachable!(),
578+
};
579+
580+
// No need to check old_size/align; we anyway check that they match the allocation.
581+
ecx.deallocate_ptr(
582+
ptr,
583+
Some((Size::from_bytes(old_size), Align::from_bytes(align).unwrap())),
584+
memory_kind.into(),
585+
)
586+
};
587+
588+
match link_name.as_str() {
589+
"__rust_dealloc" => {
590+
return this.emulate_allocator(default);
591+
}
592+
"miri_dealloc" => {
593+
default(this)?;
594+
return interp_ok(EmulateItemResult::NeedsReturn);
595+
}
596+
_ => unreachable!(),
597+
}
598+
}
599+
"__rust_realloc" => {
600+
return this.emulate_allocator(|this| {
601+
// See the comment for `__rust_alloc` why `check_shim` is only called in the
602+
// default case.
603+
let [ptr, old_size, align, new_size] =
604+
this.check_shim(abi, Conv::Rust, link_name, args)?;
605+
let ptr = this.read_pointer(ptr)?;
606+
let old_size = this.read_target_usize(old_size)?;
607+
let align = this.read_target_usize(align)?;
608+
let new_size = this.read_target_usize(new_size)?;
609+
// No need to check old_size; we anyway check that they match the allocation.
610+
611+
this.check_rustc_alloc_request(new_size, align)?;
612+
613+
let align = Align::from_bytes(align).unwrap();
614+
let new_ptr = this.reallocate_ptr(
615+
ptr,
616+
Some((Size::from_bytes(old_size), align)),
617+
Size::from_bytes(new_size),
618+
align,
619+
MiriMemoryKind::Rust.into(),
620+
)?;
621+
this.write_pointer(new_ptr, dest)
622+
});
531623
}
532624

533625
// C memory handling functions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 1 and alignment ALIGN
2+
--> tests/fail/alloc/deallocate-bad-alignment.rs:LL:CC
3+
|
4+
LL | dealloc(x, Layout::from_size_align_unchecked(1, 2));
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 1 and alignment ALIGN
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at tests/fail/alloc/deallocate-bad-alignment.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to 1 previous error
15+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN
2+
--> tests/fail/alloc/deallocate-bad-size.rs:LL:CC
3+
|
4+
LL | dealloc(x, Layout::from_size_align_unchecked(2, 1));
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `main` at tests/fail/alloc/deallocate-bad-size.rs:LL:CC
11+
12+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
13+
14+
error: aborting due to 1 previous error
15+

src/tools/miri/tests/fail/alloc/deallocate-twice.stderr

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling
2-
--> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC
2+
--> tests/fail/alloc/deallocate-twice.rs:LL:CC
33
|
4-
LL | unsafe { libc::free(ptr as *mut libc::c_void) }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling
4+
LL | dealloc(x, Layout::from_size_align_unchecked(1, 1));
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
@@ -17,13 +17,7 @@ help: ALLOC was deallocated here:
1717
LL | dealloc(x, Layout::from_size_align_unchecked(1, 1));
1818
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1919
= note: BACKTRACE (of the first span):
20-
= note: inside `std::sys::alloc::unix::<impl std::alloc::GlobalAlloc for std::alloc::System>::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC
21-
= note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC
22-
note: inside `main`
23-
--> tests/fail/alloc/deallocate-twice.rs:LL:CC
24-
|
25-
LL | dealloc(x, Layout::from_size_align_unchecked(1, 1));
26-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20+
= note: inside `main` at tests/fail/alloc/deallocate-twice.rs:LL:CC
2721

2822
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
2923

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error: Undefined Behavior: deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation
2+
--> RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC
3+
|
4+
LL | FREE();
5+
| ^ deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: BACKTRACE:
10+
= note: inside `std::sys::alloc::PLATFORM::<impl std::alloc::GlobalAlloc for std::alloc::System>::dealloc` at RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC
11+
= note: inside `<std::alloc::System as std::alloc::Allocator>::deallocate` at RUSTLIB/std/src/alloc.rs:LL:CC
12+
note: inside `main`
13+
--> tests/fail/alloc/global_system_mixup.rs:LL:CC
14+
|
15+
LL | unsafe { System.deallocate(ptr, l) };
16+
| ^
17+
18+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
19+
20+
error: aborting due to 1 previous error
21+
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
1-
error: memory leaked: ALLOC (C heap, size: 1, align: 1), allocated here:
2-
--> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC
1+
error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN
2+
--> tests/fail/alloc/reallocate-bad-size.rs:LL:CC
33
|
4-
LL | unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | let _y = realloc(x, Layout::from_size_align_unchecked(2, 1), 1);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN
66
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
79
= note: BACKTRACE:
8-
= note: inside `std::sys::alloc::unix::<impl std::alloc::GlobalAlloc for std::alloc::System>::realloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC
9-
= note: inside `std::alloc::__default_lib_allocator::__rust_realloc` at RUSTLIB/std/src/alloc.rs:LL:CC
10-
note: inside `main`
11-
--> tests/fail/alloc/reallocate-bad-size.rs:LL:CC
12-
|
13-
LL | ... let _y = realloc(x, Layout::from_size_align_unchecked(2, 1), 1);
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10+
= note: inside `main` at tests/fail/alloc/reallocate-bad-size.rs:LL:CC
1511

1612
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1713

18-
note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check
19-
2014
error: aborting due to 1 previous error
2115

src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling
2-
--> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC
2+
--> tests/fail/alloc/reallocate-dangling.rs:LL:CC
33
|
4-
LL | unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling
4+
LL | let _z = realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
@@ -17,13 +17,7 @@ help: ALLOC was deallocated here:
1717
LL | dealloc(x, Layout::from_size_align_unchecked(1, 1));
1818
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1919
= note: BACKTRACE (of the first span):
20-
= note: inside `std::sys::alloc::unix::<impl std::alloc::GlobalAlloc for std::alloc::System>::realloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC
21-
= note: inside `std::alloc::__default_lib_allocator::__rust_realloc` at RUSTLIB/std/src/alloc.rs:LL:CC
22-
note: inside `main`
23-
--> tests/fail/alloc/reallocate-dangling.rs:LL:CC
24-
|
25-
LL | let _z = realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
26-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20+
= note: inside `main` at tests/fail/alloc/reallocate-dangling.rs:LL:CC
2721

2822
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
2923

src/tools/miri/tests/fail/alloc/stack_free.stderr

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
error: Undefined Behavior: deallocating ALLOC, which is stack variable memory, using C heap deallocation operation
2-
--> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC
1+
error: Undefined Behavior: deallocating ALLOC, which is stack variable memory, using Rust heap deallocation operation
2+
--> RUSTLIB/alloc/src/boxed.rs:LL:CC
33
|
4-
LL | unsafe { libc::free(ptr as *mut libc::c_void) }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating ALLOC, which is stack variable memory, using C heap deallocation operation
4+
LL | self.1.deallocate(From::from(ptr.cast()), layout);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating ALLOC, which is stack variable memory, using Rust heap deallocation operation
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE:
10-
= note: inside `std::sys::alloc::unix::<impl std::alloc::GlobalAlloc for std::alloc::System>::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC
11-
= note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC
1210
= note: inside `<std::boxed::Box<i32> as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC
1311
= note: inside `std::ptr::drop_in_place::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
1412
= note: inside `std::mem::drop::<std::boxed::Box<i32>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC

0 commit comments

Comments
 (0)