Auto merge of #2221 - InfRandomness:freebsd-target-support, r=RalfJung
Freebsd-target-support Implement freebsd as a target for miri
This commit is contained in:
commit
f5593de579
11
ci.sh
11
ci.sh
@ -42,6 +42,16 @@ function run_tests {
|
||||
echo
|
||||
}
|
||||
|
||||
function run_tests_minimal {
|
||||
if [ -n "${MIRI_TEST_TARGET+exists}" ]; then
|
||||
echo "Testing MINIMAL foreign architecture $MIRI_TEST_TARGET: only testing $@"
|
||||
else
|
||||
echo "Testing MINIMAL host architecture: only testing $@"
|
||||
fi
|
||||
|
||||
./miri test --locked -- "$@"
|
||||
}
|
||||
|
||||
# host
|
||||
run_tests
|
||||
|
||||
@ -50,6 +60,7 @@ case $HOST_TARGET in
|
||||
MIRI_TEST_TARGET=i686-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
|
||||
;;
|
||||
x86_64-apple-darwin)
|
||||
MIRI_TEST_TARGET=mips64-unknown-linux-gnuabi64 run_tests # big-endian architecture
|
||||
|
@ -910,5 +910,5 @@ impl std::fmt::Display for HexRange {
|
||||
/// Helper function used inside the shims of foreign functions to check that
|
||||
/// `target_os` is a supported UNIX OS.
|
||||
pub fn target_os_is_unix(target_os: &str) -> bool {
|
||||
matches!(target_os, "linux" | "macos")
|
||||
matches!(target_os, "linux" | "macos" | "freebsd")
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use rustc_middle::mir;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::*;
|
||||
use shims::unix::freebsd::dlsym as freebsd;
|
||||
use shims::unix::linux::dlsym as linux;
|
||||
use shims::unix::macos::dlsym as macos;
|
||||
|
||||
@ -9,6 +10,7 @@ use shims::unix::macos::dlsym as macos;
|
||||
pub enum Dlsym {
|
||||
Linux(linux::Dlsym),
|
||||
MacOs(macos::Dlsym),
|
||||
FreeBSD(freebsd::Dlsym),
|
||||
}
|
||||
|
||||
impl Dlsym {
|
||||
@ -18,6 +20,7 @@ impl Dlsym {
|
||||
Ok(match target_os {
|
||||
"linux" => linux::Dlsym::from_str(name)?.map(Dlsym::Linux),
|
||||
"macos" => macos::Dlsym::from_str(name)?.map(Dlsym::MacOs),
|
||||
"freebsd" => freebsd::Dlsym::from_str(name)?.map(Dlsym::FreeBSD),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
@ -40,6 +43,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
match dlsym {
|
||||
Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
|
||||
Dlsym::MacOs(dlsym) => macos::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
|
||||
Dlsym::FreeBSD(dlsym) =>
|
||||
freebsd::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -461,6 +461,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
// Querying system information
|
||||
"pthread_attr_getstack" => {
|
||||
// We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here. Hence we can mostly ignore the input `attr_place`.
|
||||
let [attr_place, addr_place, size_place] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let _attr_place = this.deref_operand(attr_place)?;
|
||||
let addr_place = this.deref_operand(addr_place)?;
|
||||
let size_place = this.deref_operand(size_place)?;
|
||||
|
||||
this.write_scalar(
|
||||
Scalar::from_uint(STACK_ADDR, this.pointer_size()),
|
||||
&addr_place.into(),
|
||||
)?;
|
||||
this.write_scalar(
|
||||
Scalar::from_uint(STACK_SIZE, this.pointer_size()),
|
||||
&size_place.into(),
|
||||
)?;
|
||||
|
||||
// Return success (`0`).
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
| "signal"
|
||||
| "sigaltstack"
|
||||
if this.frame_in_std() => {
|
||||
@ -485,6 +507,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
match this.tcx.sess.target.os.as_ref() {
|
||||
"linux" => return shims::unix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
|
||||
"macos" => return shims::unix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
|
||||
"freebsd" => return shims::unix::freebsd::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
32
src/shims/unix/freebsd/dlsym.rs
Normal file
32
src/shims/unix/freebsd/dlsym.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use rustc_middle::mir;
|
||||
|
||||
use crate::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Dlsym {}
|
||||
|
||||
impl Dlsym {
|
||||
// Returns an error for unsupported symbols, and None if this symbol
|
||||
// should become a NULL pointer (pretend it does not exist).
|
||||
pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
|
||||
throw_unsup_format!("unsupported FreeBSD dlsym: {}", name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
|
||||
fn call_dlsym(
|
||||
&mut self,
|
||||
dlsym: Dlsym,
|
||||
_args: &[OpTy<'tcx, Tag>],
|
||||
_dest: &PlaceTy<'tcx, Tag>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let _ret = ret.expect("we don't support any diverging dlsym");
|
||||
assert!(this.tcx.sess.target.os == "freebsd");
|
||||
|
||||
match dlsym {}
|
||||
}
|
||||
}
|
31
src/shims/unix/freebsd/foreign_items.rs
Normal file
31
src/shims/unix/freebsd/foreign_items.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use rustc_middle::mir;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::*;
|
||||
use shims::foreign_items::EmulateByNameResult;
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
|
||||
fn emulate_foreign_item_by_name(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Tag>],
|
||||
dest: &PlaceTy<'tcx, Tag>,
|
||||
_ret: mir::BasicBlock,
|
||||
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
match link_name.as_str() {
|
||||
// Linux's `pthread_getattr_np` equivalent
|
||||
"pthread_attr_get_np" if this.frame_in_std() => {
|
||||
let [_thread, _attr] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
_ => return Ok(EmulateByNameResult::NotSupported),
|
||||
}
|
||||
Ok(EmulateByNameResult::NeedsJumping)
|
||||
}
|
||||
}
|
2
src/shims/unix/freebsd/mod.rs
Normal file
2
src/shims/unix/freebsd/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod dlsym;
|
||||
pub mod foreign_items;
|
@ -80,28 +80,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
this.write_scalar(Scalar::from_i32(result), dest)?;
|
||||
}
|
||||
|
||||
// Querying system information
|
||||
"pthread_attr_getstack" => {
|
||||
// We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here.
|
||||
let [attr_place, addr_place, size_place] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.deref_operand(attr_place)?;
|
||||
let addr_place = this.deref_operand(addr_place)?;
|
||||
let size_place = this.deref_operand(size_place)?;
|
||||
|
||||
this.write_scalar(
|
||||
Scalar::from_uint(STACK_ADDR, this.pointer_size()),
|
||||
&addr_place.into(),
|
||||
)?;
|
||||
this.write_scalar(
|
||||
Scalar::from_uint(STACK_SIZE, this.pointer_size()),
|
||||
&size_place.into(),
|
||||
)?;
|
||||
|
||||
// Return success (`0`).
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
// Threading
|
||||
"prctl" => {
|
||||
// prctl is variadic. (It is not documented like that in the manpage, but defined like that in the libc crate.)
|
||||
|
@ -5,6 +5,7 @@ mod fs;
|
||||
mod sync;
|
||||
mod thread;
|
||||
|
||||
mod freebsd;
|
||||
mod linux;
|
||||
mod macos;
|
||||
|
||||
|
@ -5,14 +5,14 @@
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
fn tmp() -> std::path::PathBuf {
|
||||
std::env::var("MIRI_TEMP")
|
||||
.map(std::path::PathBuf::from)
|
||||
.unwrap_or_else(|_| std::env::temp_dir())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
fn test_posix_fadvise() {
|
||||
use std::convert::TryInto;
|
||||
use std::fs::{remove_file, File};
|
||||
@ -42,7 +42,7 @@ fn test_posix_fadvise() {
|
||||
assert_eq!(result, 0);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
fn test_sync_file_range() {
|
||||
use std::fs::{remove_file, File};
|
||||
use std::io::Write;
|
||||
@ -208,7 +208,7 @@ fn test_rwlock_libc_static_initializer() {
|
||||
/// Test whether the `prctl` shim correctly sets the thread name.
|
||||
///
|
||||
/// Note: `prctl` exists only on Linux.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
fn test_prctl_thread_name() {
|
||||
use libc::c_long;
|
||||
use std::ffi::CString;
|
||||
@ -277,7 +277,7 @@ fn test_thread_local_errno() {
|
||||
}
|
||||
|
||||
/// Tests whether clock support exists at all
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
fn test_clocks() {
|
||||
let mut tp = std::mem::MaybeUninit::<libc::timespec>::uninit();
|
||||
let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) };
|
||||
@ -291,10 +291,10 @@ fn test_clocks() {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
test_posix_fadvise();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
test_sync_file_range();
|
||||
|
||||
test_mutex_libc_init_recursive();
|
||||
@ -302,14 +302,14 @@ fn main() {
|
||||
test_mutex_libc_init_errorcheck();
|
||||
test_rwlock_libc_static_initializer();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
test_mutex_libc_static_initializer_recursive();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
test_prctl_thread_name();
|
||||
|
||||
test_thread_local_errno();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
test_clocks();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user