Skip to content

Commit

Permalink
Fix miri
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Dec 13, 2024
1 parent 61a8112 commit 74a8a1d
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/tools/miri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ extern crate rustc_index;
extern crate rustc_middle;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_symbol_mangling;
extern crate rustc_target;
// Linking `rustc_driver` pulls in the required object code as the rest of the rustc crates are
// shipped only as rmeta files.
Expand Down
8 changes: 7 additions & 1 deletion src/tools/miri/src/shims/extern_static.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Provides the `extern static` that this platform expects.
use rustc_symbol_mangling::mangle_internal_symbol;

use crate::*;

impl<'tcx> MiriMachine<'tcx> {
Expand Down Expand Up @@ -50,7 +52,11 @@ impl<'tcx> MiriMachine<'tcx> {
// "__rust_alloc_error_handler_should_panic"
let val = ecx.tcx.sess.opts.unstable_opts.oom.should_panic();
let val = ImmTy::from_int(val, ecx.machine.layouts.u8);
Self::alloc_extern_static(ecx, "__rust_alloc_error_handler_should_panic", val)?;
Self::alloc_extern_static(
ecx,
&mangle_internal_symbol(*ecx.tcx, "__rust_alloc_error_handler_should_panic"),
val,
)?;

if ecx.target_os_is_unix() {
// "environ" is mandated by POSIX.
Expand Down
50 changes: 32 additions & 18 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc_hir::def_id::CrateNum;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::{mir, ty};
use rustc_span::Symbol;
use rustc_symbol_mangling::mangle_internal_symbol;

use self::helpers::{ToHost, ToSoft};
use super::alloc::EvalContextExt as _;
Expand Down Expand Up @@ -49,17 +50,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

// Some shims forward to other MIR bodies.
match link_name.as_str() {
"__rust_alloc_error_handler" => {
name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_error_handler") => {
// Forward to the right symbol that implements this function.
let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else {
// in real code, this symbol does not exist without an allocator
throw_unsup_format!(
"`__rust_alloc_error_handler` cannot be called when no alloc error handler is set"
);
};
let name = alloc_error_handler_name(handler_kind);
let name =
mangle_internal_symbol(*this.tcx, alloc_error_handler_name(handler_kind));
let handler = this
.lookup_exported_symbol(Symbol::intern(name))?
.lookup_exported_symbol(Symbol::intern(&name))?
.expect("missing alloc error handler symbol");
return interp_ok(Some(handler));
}
Expand Down Expand Up @@ -134,15 +136,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Find it if it was not cached.
let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None;
helpers::iter_exported_symbols(tcx, |cnum, def_id| {
if tcx.is_foreign_item(def_id) {
// Skip over imports of items
return interp_ok(());
}

let attrs = tcx.codegen_fn_attrs(def_id);
// FIXME use tcx.symbol_name(instance) instead
let symbol_name = if let Some(export_name) = attrs.export_name {
export_name
} else if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
} else if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
|| attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
{
tcx.item_name(def_id)
} else {
// Skip over items without an explicitly defined symbol name.
return interp_ok(());
};
let symbol_name =
if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
Symbol::intern(&mangle_internal_symbol(tcx, symbol_name.as_str()))
} else {
symbol_name
};
if symbol_name == link_name {
if let Some((original_instance, original_cnum)) = instance_and_crate {
// Make sure we are consistent wrt what is 'first' and 'second'.
Expand Down Expand Up @@ -495,7 +511,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
}

// Rust allocation
"__rust_alloc" | "miri_alloc" => {
name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc")
|| name == "miri_alloc" =>
{
let default = |ecx: &mut MiriInterpCx<'tcx>| {
// Only call `check_shim` when `#[global_allocator]` isn't used. When that
// macro is used, we act like no shim exists, so that the exported function can run.
Expand All @@ -506,9 +524,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
ecx.check_rustc_alloc_request(size, align)?;

let memory_kind = match link_name.as_str() {
"__rust_alloc" => MiriMemoryKind::Rust,
"miri_alloc" => MiriMemoryKind::Miri,
_ => unreachable!(),
_ => MiriMemoryKind::Rust,
};

let ptr = ecx.allocate_ptr(
Expand All @@ -521,15 +538,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
};

match link_name.as_str() {
"__rust_alloc" => return this.emulate_allocator(default),
"miri_alloc" => {
default(this)?;
return interp_ok(EmulateItemResult::NeedsReturn);
}
_ => unreachable!(),
_ => return this.emulate_allocator(default),
}
}
"__rust_alloc_zeroed" => {
name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_zeroed") => {
return this.emulate_allocator(|this| {
// See the comment for `__rust_alloc` why `check_shim` is only called in the
// default case.
Expand All @@ -554,7 +570,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_pointer(ptr, dest)
});
}
"__rust_dealloc" | "miri_dealloc" => {
name if name == mangle_internal_symbol(*this.tcx, "__rust_dealloc")
|| name == "miri_dealloc" =>
{
let default = |ecx: &mut MiriInterpCx<'tcx>| {
// See the comment for `__rust_alloc` why `check_shim` is only called in the
// default case.
Expand All @@ -565,9 +583,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
let align = ecx.read_target_usize(align)?;

let memory_kind = match link_name.as_str() {
"__rust_dealloc" => MiriMemoryKind::Rust,
"miri_dealloc" => MiriMemoryKind::Miri,
_ => unreachable!(),
_ => MiriMemoryKind::Rust,
};

// No need to check old_size/align; we anyway check that they match the allocation.
Expand All @@ -579,17 +596,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
};

match link_name.as_str() {
"__rust_dealloc" => {
return this.emulate_allocator(default);
}
"miri_dealloc" => {
default(this)?;
return interp_ok(EmulateItemResult::NeedsReturn);
}
_ => unreachable!(),
_ => return this.emulate_allocator(default),
}
}
"__rust_realloc" => {
name if name == mangle_internal_symbol(*this.tcx, "__rust_realloc") => {
return this.emulate_allocator(|this| {
// See the comment for `__rust_alloc` why `check_shim` is only called in the
// default case.
Expand Down
3 changes: 2 additions & 1 deletion src/tools/miri/src/shims/windows/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_int(1, dest)?;
}
"TlsFree" => {
let [key] = this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
let [key] =
this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
let key = u128::from(this.read_scalar(key)?.to_u32()?);
this.machine.tls.delete_tls_key(key)?;

Expand Down
3 changes: 3 additions & 0 deletions src/tools/miri/tests/fail/alloc/too_large.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#![feature(rustc_attrs)]

extern "Rust" {
#[rustc_std_internal_symbol]
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
}

Expand Down
3 changes: 3 additions & 0 deletions src/tools/miri/tests/fail/alloc/unsupported_big_alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// because rustc does not support alignments that large.
// https://github.com/rust-lang/miri/issues/3687

#![feature(rustc_attrs)]

extern "Rust" {
#[rustc_std_internal_symbol]
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// Test non-power-of-two alignment.

#![feature(rustc_attrs)]

extern "Rust" {
#[rustc_std_internal_symbol]
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
}

Expand Down
3 changes: 3 additions & 0 deletions src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// Avoid accidental synchronization via address reuse inside `thread::spawn`.
//@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0

#![feature(rustc_attrs)]

use std::thread::spawn;

#[derive(Copy, Clone)]
Expand All @@ -12,6 +14,7 @@ unsafe impl<T> Send for EvilSend<T> {}
unsafe impl<T> Sync for EvilSend<T> {}

extern "Rust" {
#[rustc_std_internal_symbol]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
}

Expand Down
3 changes: 3 additions & 0 deletions src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// Avoid accidental synchronization via address reuse inside `thread::spawn`.
//@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0

#![feature(rustc_attrs)]

use std::thread::spawn;

#[derive(Copy, Clone)]
Expand All @@ -12,6 +14,7 @@ unsafe impl<T> Send for EvilSend<T> {}
unsafe impl<T> Sync for EvilSend<T> {}

extern "Rust" {
#[rustc_std_internal_symbol]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
}

Expand Down
3 changes: 3 additions & 0 deletions src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// Avoid accidental synchronization via address reuse inside `thread::spawn`.
//@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0

#![feature(rustc_attrs)]

use std::thread::spawn;

#[derive(Copy, Clone)]
Expand All @@ -12,6 +14,7 @@ unsafe impl<T> Send for EvilSend<T> {}
unsafe impl<T> Sync for EvilSend<T> {}

extern "Rust" {
#[rustc_std_internal_symbol]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
}
pub fn main() {
Expand Down
3 changes: 3 additions & 0 deletions src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// Avoid accidental synchronization via address reuse inside `thread::spawn`.
//@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0

#![feature(rustc_attrs)]

use std::thread::spawn;

#[derive(Copy, Clone)]
Expand All @@ -12,6 +14,7 @@ unsafe impl<T> Send for EvilSend<T> {}
unsafe impl<T> Sync for EvilSend<T> {}

extern "Rust" {
#[rustc_std_internal_symbol]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
}
pub fn main() {
Expand Down
2 changes: 2 additions & 0 deletions src/tools/miri/tests/pass/function_calls/exported_symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ fn main() {

extern "Rust" {
fn bar() -> i32;
#[rustc_std_internal_symbol]
fn baz() -> i32;
fn qux() -> i32;
}
Expand All @@ -63,6 +64,7 @@ fn main() {

extern "C" {
fn bar() -> i32;
#[rustc_std_internal_symbol]
fn baz() -> i32;
fn qux() -> i32;
}
Expand Down

0 comments on commit 74a8a1d

Please sign in to comment.