Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit f5593de

Browse files
committed
Auto merge of rust-lang#2221 - InfRandomness:freebsd-target-support, r=RalfJung
Freebsd-target-support Implement freebsd as a target for miri
2 parents 99afff9 + 5719897 commit f5593de

File tree

10 files changed

+116
-33
lines changed

10 files changed

+116
-33
lines changed

ci.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ function run_tests {
4242
echo
4343
}
4444

45+
function run_tests_minimal {
46+
if [ -n "${MIRI_TEST_TARGET+exists}" ]; then
47+
echo "Testing MINIMAL foreign architecture $MIRI_TEST_TARGET: only testing $@"
48+
else
49+
echo "Testing MINIMAL host architecture: only testing $@"
50+
fi
51+
52+
./miri test --locked -- "$@"
53+
}
54+
4555
# host
4656
run_tests
4757

@@ -50,6 +60,7 @@ case $HOST_TARGET in
5060
MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
5161
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
5262
MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
63+
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec
5364
;;
5465
x86_64-apple-darwin)
5566
MIRI_TEST_TARGET=mips64-unknown-linux-gnuabi64 run_tests # big-endian architecture

src/helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,5 +910,5 @@ impl std::fmt::Display for HexRange {
910910
/// Helper function used inside the shims of foreign functions to check that
911911
/// `target_os` is a supported UNIX OS.
912912
pub fn target_os_is_unix(target_os: &str) -> bool {
913-
matches!(target_os, "linux" | "macos")
913+
matches!(target_os, "linux" | "macos" | "freebsd")
914914
}

src/shims/unix/dlsym.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ use rustc_middle::mir;
22
use rustc_target::spec::abi::Abi;
33

44
use crate::*;
5+
use shims::unix::freebsd::dlsym as freebsd;
56
use shims::unix::linux::dlsym as linux;
67
use shims::unix::macos::dlsym as macos;
78

89
#[derive(Debug, Copy, Clone)]
910
pub enum Dlsym {
1011
Linux(linux::Dlsym),
1112
MacOs(macos::Dlsym),
13+
FreeBSD(freebsd::Dlsym),
1214
}
1315

1416
impl Dlsym {
@@ -18,6 +20,7 @@ impl Dlsym {
1820
Ok(match target_os {
1921
"linux" => linux::Dlsym::from_str(name)?.map(Dlsym::Linux),
2022
"macos" => macos::Dlsym::from_str(name)?.map(Dlsym::MacOs),
23+
"freebsd" => freebsd::Dlsym::from_str(name)?.map(Dlsym::FreeBSD),
2124
_ => unreachable!(),
2225
})
2326
}
@@ -40,6 +43,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4043
match dlsym {
4144
Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
4245
Dlsym::MacOs(dlsym) => macos::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
46+
Dlsym::FreeBSD(dlsym) =>
47+
freebsd::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
4348
}
4449
}
4550
}

src/shims/unix/foreign_items.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
461461
this.write_null(dest)?;
462462
}
463463

464+
// Querying system information
465+
"pthread_attr_getstack" => {
466+
// 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`.
467+
let [attr_place, addr_place, size_place] =
468+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
469+
let _attr_place = this.deref_operand(attr_place)?;
470+
let addr_place = this.deref_operand(addr_place)?;
471+
let size_place = this.deref_operand(size_place)?;
472+
473+
this.write_scalar(
474+
Scalar::from_uint(STACK_ADDR, this.pointer_size()),
475+
&addr_place.into(),
476+
)?;
477+
this.write_scalar(
478+
Scalar::from_uint(STACK_SIZE, this.pointer_size()),
479+
&size_place.into(),
480+
)?;
481+
482+
// Return success (`0`).
483+
this.write_null(dest)?;
484+
}
485+
464486
| "signal"
465487
| "sigaltstack"
466488
if this.frame_in_std() => {
@@ -485,6 +507,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
485507
match this.tcx.sess.target.os.as_ref() {
486508
"linux" => return shims::unix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
487509
"macos" => return shims::unix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
510+
"freebsd" => return shims::unix::freebsd::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
488511
_ => unreachable!(),
489512
}
490513
}

src/shims/unix/freebsd/dlsym.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use rustc_middle::mir;
2+
3+
use crate::*;
4+
5+
#[derive(Debug, Copy, Clone)]
6+
#[allow(non_camel_case_types)]
7+
pub enum Dlsym {}
8+
9+
impl Dlsym {
10+
// Returns an error for unsupported symbols, and None if this symbol
11+
// should become a NULL pointer (pretend it does not exist).
12+
pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
13+
throw_unsup_format!("unsupported FreeBSD dlsym: {}", name)
14+
}
15+
}
16+
17+
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
18+
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
19+
fn call_dlsym(
20+
&mut self,
21+
dlsym: Dlsym,
22+
_args: &[OpTy<'tcx, Tag>],
23+
_dest: &PlaceTy<'tcx, Tag>,
24+
ret: Option<mir::BasicBlock>,
25+
) -> InterpResult<'tcx> {
26+
let this = self.eval_context_mut();
27+
let _ret = ret.expect("we don't support any diverging dlsym");
28+
assert!(this.tcx.sess.target.os == "freebsd");
29+
30+
match dlsym {}
31+
}
32+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use rustc_middle::mir;
2+
use rustc_span::Symbol;
3+
use rustc_target::spec::abi::Abi;
4+
5+
use crate::*;
6+
use shims::foreign_items::EmulateByNameResult;
7+
8+
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
9+
10+
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
11+
fn emulate_foreign_item_by_name(
12+
&mut self,
13+
link_name: Symbol,
14+
abi: Abi,
15+
args: &[OpTy<'tcx, Tag>],
16+
dest: &PlaceTy<'tcx, Tag>,
17+
_ret: mir::BasicBlock,
18+
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
19+
let this = self.eval_context_mut();
20+
match link_name.as_str() {
21+
// Linux's `pthread_getattr_np` equivalent
22+
"pthread_attr_get_np" if this.frame_in_std() => {
23+
let [_thread, _attr] =
24+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
25+
this.write_null(dest)?;
26+
}
27+
_ => return Ok(EmulateByNameResult::NotSupported),
28+
}
29+
Ok(EmulateByNameResult::NeedsJumping)
30+
}
31+
}

src/shims/unix/freebsd/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod dlsym;
2+
pub mod foreign_items;

src/shims/unix/linux/foreign_items.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -80,28 +80,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8080
this.write_scalar(Scalar::from_i32(result), dest)?;
8181
}
8282

83-
// Querying system information
84-
"pthread_attr_getstack" => {
85-
// We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here.
86-
let [attr_place, addr_place, size_place] =
87-
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
88-
this.deref_operand(attr_place)?;
89-
let addr_place = this.deref_operand(addr_place)?;
90-
let size_place = this.deref_operand(size_place)?;
91-
92-
this.write_scalar(
93-
Scalar::from_uint(STACK_ADDR, this.pointer_size()),
94-
&addr_place.into(),
95-
)?;
96-
this.write_scalar(
97-
Scalar::from_uint(STACK_SIZE, this.pointer_size()),
98-
&size_place.into(),
99-
)?;
100-
101-
// Return success (`0`).
102-
this.write_null(dest)?;
103-
}
104-
10583
// Threading
10684
"prctl" => {
10785
// prctl is variadic. (It is not documented like that in the manpage, but defined like that in the libc crate.)

src/shims/unix/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod fs;
55
mod sync;
66
mod thread;
77

8+
mod freebsd;
89
mod linux;
910
mod macos;
1011

tests/pass/libc.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55

66
extern crate libc;
77

8-
#[cfg(target_os = "linux")]
8+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
99
fn tmp() -> std::path::PathBuf {
1010
std::env::var("MIRI_TEMP")
1111
.map(std::path::PathBuf::from)
1212
.unwrap_or_else(|_| std::env::temp_dir())
1313
}
1414

15-
#[cfg(target_os = "linux")]
15+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
1616
fn test_posix_fadvise() {
1717
use std::convert::TryInto;
1818
use std::fs::{remove_file, File};
@@ -42,7 +42,7 @@ fn test_posix_fadvise() {
4242
assert_eq!(result, 0);
4343
}
4444

45-
#[cfg(target_os = "linux")]
45+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
4646
fn test_sync_file_range() {
4747
use std::fs::{remove_file, File};
4848
use std::io::Write;
@@ -208,7 +208,7 @@ fn test_rwlock_libc_static_initializer() {
208208
/// Test whether the `prctl` shim correctly sets the thread name.
209209
///
210210
/// Note: `prctl` exists only on Linux.
211-
#[cfg(target_os = "linux")]
211+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
212212
fn test_prctl_thread_name() {
213213
use libc::c_long;
214214
use std::ffi::CString;
@@ -277,7 +277,7 @@ fn test_thread_local_errno() {
277277
}
278278

279279
/// Tests whether clock support exists at all
280-
#[cfg(target_os = "linux")]
280+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
281281
fn test_clocks() {
282282
let mut tp = std::mem::MaybeUninit::<libc::timespec>::uninit();
283283
let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) };
@@ -291,25 +291,25 @@ fn test_clocks() {
291291
}
292292

293293
fn main() {
294-
#[cfg(target_os = "linux")]
294+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
295295
test_posix_fadvise();
296296

297-
#[cfg(target_os = "linux")]
297+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
298298
test_sync_file_range();
299299

300300
test_mutex_libc_init_recursive();
301301
test_mutex_libc_init_normal();
302302
test_mutex_libc_init_errorcheck();
303303
test_rwlock_libc_static_initializer();
304304

305-
#[cfg(target_os = "linux")]
305+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
306306
test_mutex_libc_static_initializer_recursive();
307307

308-
#[cfg(target_os = "linux")]
308+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
309309
test_prctl_thread_name();
310310

311311
test_thread_local_errno();
312312

313-
#[cfg(target_os = "linux")]
313+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
314314
test_clocks();
315315
}

0 commit comments

Comments
 (0)