Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Freebsd-target-support #2221

Merged
merged 9 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
5 changes: 5 additions & 0 deletions src/shims/unix/dlsym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ 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;

#[derive(Debug, Copy, Clone)]
pub enum Dlsym {
Linux(linux::Dlsym),
MacOs(macos::Dlsym),
FreeBSD(freebsd::Dlsym),
}

impl Dlsym {
Expand All @@ -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!(),
})
}
Expand All @@ -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),
}
}
}
23 changes: 23 additions & 0 deletions src/shims/unix/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() => {
Expand All @@ -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!(),
}
}
Expand Down
32 changes: 32 additions & 0 deletions src/shims/unix/freebsd/dlsym.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 31 additions & 0 deletions src/shims/unix/freebsd/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 0 deletions src/shims/unix/freebsd/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod dlsym;
pub mod foreign_items;
22 changes: 0 additions & 22 deletions src/shims/unix/linux/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.)
Expand Down
1 change: 1 addition & 0 deletions src/shims/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod fs;
mod sync;
mod thread;

mod freebsd;
mod linux;
mod macos;

Expand Down
20 changes: 10 additions & 10 deletions tests/pass/libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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()) };
Expand All @@ -291,25 +291,25 @@ 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();
test_mutex_libc_init_normal();
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();
}