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:
bors 2022-06-27 17:40:15 +00:00
commit f5593de579
10 changed files with 116 additions and 33 deletions

11
ci.sh
View File

@ -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

View File

@ -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")
}

View File

@ -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),
}
}
}

View File

@ -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!(),
}
}

View 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 {}
}
}

View 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)
}
}

View File

@ -0,0 +1,2 @@
pub mod dlsym;
pub mod foreign_items;

View File

@ -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.)

View File

@ -5,6 +5,7 @@ mod fs;
mod sync;
mod thread;
mod freebsd;
mod linux;
mod macos;

View File

@ -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();
}