diff --git a/Cargo.lock b/Cargo.lock index a7303421808..9df35ec0deb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -308,6 +308,25 @@ version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +[[package]] +name = "libffi" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e454b3efb16fba3b17810ae5e41df02b649e564ab3c5a34b3b93ed07ad287e6" +dependencies = [ + "libc", + "libffi-sys", +] + +[[package]] +name = "libffi-sys" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab4106b7f09d7b87d021334d5618fac1dfcfb824d4c5fe111ff0074dfd242e15" +dependencies = [ + "cc", +] + [[package]] name = "libloading" version = "0.7.3" @@ -392,6 +411,7 @@ dependencies = [ "getrandom", "lazy_static", "libc", + "libffi", "libloading", "log", "measureme", diff --git a/Cargo.toml b/Cargo.toml index c0a217b6411..0a3dfc2a84e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ doctest = false # and no doc tests [dependencies] getrandom = { version = "0.2", features = ["std"] } env_logger = "0.9" -#FIXME(miri#2526): libffi = "3.0.0" +libffi = "3.0.0" libloading = "0.7" log = "0.4" shell-escape = "0.1.4" diff --git a/README.md b/README.md index c7a3200dbd9..8e96338a865 100644 --- a/README.md +++ b/README.md @@ -346,6 +346,17 @@ to Miri failing to detect cases of undefined behavior in a program. this flag is **unsound**. * `-Zmiri-disable-weak-memory-emulation` disables the emulation of some C++11 weak memory effects. +* `-Zmiri-extern-so-file=` is an experimental flag for providing support + for FFI calls. Functions not provided by that file are still executed via the usual Miri shims. + **WARNING**: If an invalid/incorrect `.so` file is specified, this can cause undefined behaviour in Miri itself! + And of course, Miri cannot do any checks on the actions taken by the external code. + Note that Miri has its own handling of file descriptors, so if you want to replace *some* functions + working on file descriptors, you will have to replace *all* of them, or the two kinds of + file descriptors will be mixed up. + This is **work in progress**; currently, only integer arguments and return values are + supported (and no, pointer/integer casts to work around this limitation will not work; + they will fail horribly). + Follow [the discussion on supporting other types](https://github.com/rust-lang/miri/issues/2365). * `-Zmiri-measureme=` enables `measureme` profiling for the interpreted program. This can be used to find which parts of your program are executing slowly under Miri. The profile is written out to a file with the prefix ``, and can be processed diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index bd46e4ae80e..b94b6bbb2b8 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -23,7 +23,7 @@ use rustc_target::{ use super::backtrace::EvalContextExt as _; use crate::helpers::{convert::Truncate, target_os_is_unix}; -//FIXME(miri#2526): use crate::shims::ffi_support::EvalContextExt as _; +use crate::shims::ffi_support::EvalContextExt as _; use crate::*; /// Returned by `emulate_foreign_item_by_name`. @@ -375,9 +375,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // An Ok(false) here means that the function being called was not exported // by the specified `.so` file; we should continue and check if it corresponds to // a provided shim. - /*FIXME(miri#2526): if this.call_external_c_fct(link_name, dest, args)? { + if this.call_external_c_fct(link_name, dest, args)? { return Ok(EmulateByNameResult::NeedsJumping); - }*/ + } } // When adding a new shim, you should follow the following pattern: diff --git a/src/shims/mod.rs b/src/shims/mod.rs index 8179d09defe..ee2145db7e1 100644 --- a/src/shims/mod.rs +++ b/src/shims/mod.rs @@ -1,7 +1,7 @@ #![warn(clippy::integer_arithmetic)] mod backtrace; -//FIXME(miri#2526): pub mod ffi_support; +pub mod ffi_support; pub mod foreign_items; pub mod intrinsics; pub mod unix; diff --git a/tests/compiletest.rs b/tests/compiletest.rs index 0e492c3eecd..6b5668e2d6c 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -212,8 +212,8 @@ fn main() -> Result<()> { ui(Mode::Panic, "tests/panic", WithDependencies)?; ui(Mode::Fail { require_patterns: true }, "tests/fail", WithDependencies)?; if cfg!(target_os = "linux") { - //FIXME(miri#2526): ui(Mode::Pass, "tests/extern-so/pass", WithoutDependencies)?; - //FIXME(miri#2526): ui(Mode::Fail { require_patterns: true }, "tests/extern-so/fail", WithDependencies)?; + ui(Mode::Pass, "tests/extern-so/pass", WithoutDependencies)?; + ui(Mode::Fail { require_patterns: true }, "tests/extern-so/fail", WithDependencies)?; } Ok(())