Auto merge of #2798 - LevitatingLion:master, r=oli-obk

Get Miri working on ARM

- Add a shim for `llvm.arm.hint`, which is required by `core::hint::spin_loop` on `arm` targets. The shim simply calls `yield_active_thread` on a YIELD hint, just like the shim for `llvm.aarch64.isb` that's already present.
- Change the signature of `miri_host_to_target_path` to use `c_char` instead of `i8`, to make it compatible with `CStr` on targets where `c_char` is unsigned. The implementation of `miri_host_to_target_path` accesses the memory as bytes and does not need to be adjusted.
- Enable ARM targets in CI. Specifically, `aarch64-unknown-linux-gnu` and `arm-unknown-linux-gnueabi` on the Linux host.

Since all tests also pass for `aarch64-unknown-linux-gnu` I took the liberty of adding that target to CI as well.

Fixes #2791
This commit is contained in:
bors 2023-02-25 16:45:50 +00:00
commit ffd12f67cf
9 changed files with 46 additions and 17 deletions

View file

@ -213,7 +213,9 @@ degree documented below):
- The best-supported target is `x86_64-unknown-linux-gnu`. Miri releases are
blocked on things working with this target. Most other Linux targets should
also work well; we do run the test suite on `i686-unknown-linux-gnu` as a
32bit target and `mips64-unknown-linux-gnuabi64` as a big-endian target.
32bit target and `mips64-unknown-linux-gnuabi64` as a big-endian target, as
well as the ARM targets `aarch64-unknown-linux-gnu` and
`arm-unknown-linux-gnueabi`.
- `x86_64-apple-darwin` should work basically as well as Linux. We also test
`aarch64-apple-darwin`. However, we might ship Miri with a nightly even when
some features on these targets regress.
@ -590,7 +592,7 @@ extern "Rust" {
/// `out` must point to at least `out_size` many bytes, and the result will be stored there
/// with a null terminator.
/// Returns 0 if the `out` buffer was large enough, and the required size otherwise.
fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
fn miri_host_to_target_path(path: *const std::ffi::c_char, out: *mut std::ffi::c_char, out_size: usize) -> usize;
}
```

View file

@ -104,6 +104,7 @@ run_tests
case $HOST_TARGET in
x86_64-unknown-linux-gnu)
MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var
@ -118,6 +119,7 @@ case $HOST_TARGET in
MIRI_TEST_TARGET=x86_64-pc-windows-msvc run_tests
;;
i686-pc-windows-msvc)
MIRI_TEST_TARGET=arm-unknown-linux-gnueabi run_tests
MIRI_TEST_TARGET=x86_64-unknown-linux-gnu run_tests
MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests
;;

View file

@ -885,6 +885,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
}
}
"llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => {
let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
let arg = this.read_scalar(arg)?.to_i32()?;
match arg {
// YIELD
1 => {
this.yield_active_thread();
}
_ => {
throw_unsup_format!("unsupported llvm.arm.hint argument {}", arg);
}
}
}
// Platform-specific shims
_ =>

View file

@ -23,7 +23,7 @@ fn main() {
// (We rely on the test runner to always disable isolation when passing no arguments.)
if std::env::args().len() <= 1 {
fn host_to_target_path(path: String) -> PathBuf {
use std::ffi::{CStr, CString};
use std::ffi::{c_char, CStr, CString};
let path = CString::new(path).unwrap();
let mut out = Vec::with_capacity(1024);
@ -31,8 +31,8 @@ fn main() {
unsafe {
extern "Rust" {
fn miri_host_to_target_path(
path: *const i8,
out: *mut i8,
path: *const c_char,
out: *mut c_char,
out_size: usize,
) -> usize;
}

View file

@ -5,7 +5,7 @@ fn main() {
println!("subcrate running");
fn host_to_target_path(path: String) -> PathBuf {
use std::ffi::{CStr, CString};
use std::ffi::{c_char, CStr, CString};
let path = CString::new(path).unwrap();
let mut out = Vec::with_capacity(1024);
@ -13,8 +13,8 @@ fn main() {
unsafe {
extern "Rust" {
fn miri_host_to_target_path(
path: *const i8,
out: *mut i8,
path: *const c_char,
out: *mut c_char,
out_size: usize,
) -> usize;
}

View file

@ -8,7 +8,7 @@ fn main() {
println!("subcrate testing");
fn host_to_target_path(path: String) -> PathBuf {
use std::ffi::{CStr, CString};
use std::ffi::{c_char, CStr, CString};
let path = CString::new(path).unwrap();
let mut out = Vec::with_capacity(1024);
@ -16,8 +16,8 @@ fn main() {
unsafe {
extern "Rust" {
fn miri_host_to_target_path(
path: *const i8,
out: *mut i8,
path: *const c_char,
out: *mut c_char,
out_size: usize,
) -> usize;
}

View file

@ -5,7 +5,7 @@
#![feature(io_error_uncategorized)]
use std::convert::TryInto;
use std::ffi::{CStr, CString};
use std::ffi::{c_char, CStr, CString};
use std::fs::{canonicalize, remove_dir_all, remove_file, File};
use std::io::{Error, ErrorKind, Write};
use std::os::unix::ffi::OsStrExt;
@ -31,7 +31,11 @@ fn tmp() -> PathBuf {
unsafe {
extern "Rust" {
fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
fn miri_host_to_target_path(
path: *const c_char,
out: *mut c_char,
out_size: usize,
) -> usize;
}
let ret = miri_host_to_target_path(path.as_ptr(), out.as_mut_ptr(), out.capacity());
assert_eq!(ret, 0);

View file

@ -7,7 +7,7 @@ use std::os::unix::io::AsRawFd;
use std::path::PathBuf;
fn tmp() -> PathBuf {
use std::ffi::{CStr, CString};
use std::ffi::{c_char, CStr, CString};
let path = std::env::var("MIRI_TEMP")
.unwrap_or_else(|_| std::env::temp_dir().into_os_string().into_string().unwrap());
@ -17,7 +17,11 @@ fn tmp() -> PathBuf {
unsafe {
extern "Rust" {
fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
fn miri_host_to_target_path(
path: *const c_char,
out: *mut c_char,
out_size: usize,
) -> usize;
}
let ret = miri_host_to_target_path(path.as_ptr(), out.as_mut_ptr(), out.capacity());
assert_eq!(ret, 0);

View file

@ -6,7 +6,7 @@
#![feature(is_terminal)]
use std::collections::HashMap;
use std::ffi::OsString;
use std::ffi::{c_char, OsString};
use std::fs::{
canonicalize, create_dir, read_dir, read_link, remove_dir, remove_dir_all, remove_file, rename,
File, OpenOptions,
@ -39,7 +39,11 @@ fn host_to_target_path(path: String) -> PathBuf {
unsafe {
extern "Rust" {
fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
fn miri_host_to_target_path(
path: *const c_char,
out: *mut c_char,
out_size: usize,
) -> usize;
}
let ret = miri_host_to_target_path(path.as_ptr(), out.as_mut_ptr(), out.capacity());
assert_eq!(ret, 0);