Skip to content

Commit e25a04f

Browse files
committed
Auto merge of rust-lang#3143 - devnexen:fbsd_update, r=RalfJung
freebsd interceptions update proposal
2 parents fe0b970 + ba523be commit e25a04f

File tree

4 files changed

+112
-8
lines changed

4 files changed

+112
-8
lines changed

src/tools/miri/ci.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ case $HOST_TARGET in
108108
MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
109109
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
110110
MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
111-
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic env/var
111+
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthreads atomic env/var
112112
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
113113
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
114114
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm

src/tools/miri/src/shims/unix/freebsd/foreign_items.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2929
"pthread_set_name_np" => {
3030
let [thread, name] =
3131
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
32-
let max_len = usize::MAX; // freebsd does not seem to have a limit.
33-
let res = this.pthread_setname_np(
32+
let max_len = usize::MAX; // FreeBSD does not seem to have a limit.
33+
// FreeBSD's pthread_set_name_np does not return anything.
34+
this.pthread_setname_np(
3435
this.read_scalar(thread)?,
3536
this.read_scalar(name)?,
3637
max_len,
3738
)?;
38-
this.write_scalar(res, dest)?;
39+
}
40+
"pthread_get_name_np" => {
41+
let [thread, name, len] =
42+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
43+
// FreeBSD's pthread_get_name_np does not return anything.
44+
this.pthread_getname_np(
45+
this.read_scalar(thread)?,
46+
this.read_scalar(name)?,
47+
this.read_scalar(len)?,
48+
)?;
3949
}
4050

4151
// errno

src/tools/miri/src/shims/unix/sync.rs

+70
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
277277
) -> InterpResult<'tcx, i32> {
278278
let this = self.eval_context_mut();
279279

280+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
281+
throw_unsup_format!(
282+
"`pthread_mutexattr_init` is not supported on {}",
283+
this.tcx.sess.target.os
284+
);
285+
}
286+
280287
let default_kind = this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT");
281288
mutexattr_set_kind(this, attr_op, default_kind)?;
282289

@@ -359,6 +366,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
359366
) -> InterpResult<'tcx, i32> {
360367
let this = self.eval_context_mut();
361368

369+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
370+
throw_unsup_format!(
371+
"`pthread_mutex_init` is not supported on {}",
372+
this.tcx.sess.target.os
373+
);
374+
}
375+
362376
let attr = this.read_pointer(attr_op)?;
363377
let kind = if this.ptr_is_null(attr)? {
364378
this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")
@@ -513,6 +527,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
513527
) -> InterpResult<'tcx, i32> {
514528
let this = self.eval_context_mut();
515529

530+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
531+
throw_unsup_format!(
532+
"`pthread_rwlock_rdlock` is not supported on {}",
533+
this.tcx.sess.target.os
534+
);
535+
}
536+
516537
let id = rwlock_get_id(this, rwlock_op)?;
517538
let active_thread = this.get_active_thread();
518539

@@ -531,6 +552,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
531552
) -> InterpResult<'tcx, i32> {
532553
let this = self.eval_context_mut();
533554

555+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
556+
throw_unsup_format!(
557+
"`pthread_rwlock_tryrdlock` is not supported on {}",
558+
this.tcx.sess.target.os
559+
);
560+
}
561+
534562
let id = rwlock_get_id(this, rwlock_op)?;
535563
let active_thread = this.get_active_thread();
536564

@@ -548,6 +576,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
548576
) -> InterpResult<'tcx, i32> {
549577
let this = self.eval_context_mut();
550578

579+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
580+
throw_unsup_format!(
581+
"`pthread_rwlock_wrlock` is not supported on {}",
582+
this.tcx.sess.target.os
583+
);
584+
}
585+
551586
let id = rwlock_get_id(this, rwlock_op)?;
552587
let active_thread = this.get_active_thread();
553588

@@ -578,6 +613,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
578613
) -> InterpResult<'tcx, i32> {
579614
let this = self.eval_context_mut();
580615

616+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
617+
throw_unsup_format!(
618+
"`pthread_rwlock_trywrlock` is not supported on {}",
619+
this.tcx.sess.target.os
620+
);
621+
}
622+
581623
let id = rwlock_get_id(this, rwlock_op)?;
582624
let active_thread = this.get_active_thread();
583625

@@ -595,6 +637,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
595637
) -> InterpResult<'tcx, i32> {
596638
let this = self.eval_context_mut();
597639

640+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
641+
throw_unsup_format!(
642+
"`pthread_rwlock_unlock` is not supported on {}",
643+
this.tcx.sess.target.os
644+
);
645+
}
646+
598647
let id = rwlock_get_id(this, rwlock_op)?;
599648
let active_thread = this.get_active_thread();
600649

@@ -614,6 +663,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
614663
) -> InterpResult<'tcx, i32> {
615664
let this = self.eval_context_mut();
616665

666+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
667+
throw_unsup_format!(
668+
"`pthread_rwlock_destroy` is not supported on {}",
669+
this.tcx.sess.target.os
670+
);
671+
}
672+
617673
let id = rwlock_get_id(this, rwlock_op)?;
618674

619675
if this.rwlock_is_locked(id) {
@@ -638,6 +694,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
638694
) -> InterpResult<'tcx, i32> {
639695
let this = self.eval_context_mut();
640696

697+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
698+
throw_unsup_format!(
699+
"`pthread_condattr_init` is not supported on {}",
700+
this.tcx.sess.target.os
701+
);
702+
}
703+
641704
// The default value of the clock attribute shall refer to the system
642705
// clock.
643706
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setclock.html
@@ -704,6 +767,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
704767
) -> InterpResult<'tcx, i32> {
705768
let this = self.eval_context_mut();
706769

770+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
771+
throw_unsup_format!(
772+
"`pthread_cond_init` is not supported on {}",
773+
this.tcx.sess.target.os
774+
);
775+
}
776+
707777
let attr = this.read_pointer(attr_op)?;
708778
let clock_id = if this.ptr_is_null(attr)? {
709779
this.eval_libc_i32("CLOCK_REALTIME")

src/tools/miri/tests/pass-dep/shims/pthreads.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
//@ignore-target-windows: No libc on Windows
2-
use std::ffi::{CStr, CString};
2+
use std::ffi::CStr;
3+
#[cfg(not(target_os = "freebsd"))]
4+
use std::ffi::CString;
35
use std::thread;
46

57
fn main() {
8+
test_named_thread_truncation();
9+
10+
#[cfg(not(target_os = "freebsd"))]
611
test_mutex_libc_init_recursive();
12+
#[cfg(not(target_os = "freebsd"))]
713
test_mutex_libc_init_normal();
14+
#[cfg(not(target_os = "freebsd"))]
815
test_mutex_libc_init_errorcheck();
16+
#[cfg(not(target_os = "freebsd"))]
917
test_rwlock_libc_static_initializer();
10-
test_named_thread_truncation();
1118

1219
#[cfg(target_os = "linux")]
1320
test_mutex_libc_static_initializer_recursive();
1421
}
1522

23+
#[cfg(not(target_os = "freebsd"))]
1624
fn test_mutex_libc_init_recursive() {
1725
unsafe {
1826
let mut attr: libc::pthread_mutexattr_t = std::mem::zeroed();
@@ -37,6 +45,7 @@ fn test_mutex_libc_init_recursive() {
3745
}
3846
}
3947

48+
#[cfg(not(target_os = "freebsd"))]
4049
fn test_mutex_libc_init_normal() {
4150
unsafe {
4251
let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
@@ -59,6 +68,7 @@ fn test_mutex_libc_init_normal() {
5968
}
6069
}
6170

71+
#[cfg(not(target_os = "freebsd"))]
6272
fn test_mutex_libc_init_errorcheck() {
6373
unsafe {
6474
let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
@@ -104,6 +114,7 @@ fn test_mutex_libc_static_initializer_recursive() {
104114
// Testing the behavior of std::sync::RwLock does not fully exercise the pthread rwlock shims, we
105115
// need to go a layer deeper and test the behavior of the libc functions, because
106116
// std::sys::unix::rwlock::RWLock itself keeps track of write_locked and num_readers.
117+
#[cfg(not(target_os = "freebsd"))]
107118
fn test_rwlock_libc_static_initializer() {
108119
let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
109120
unsafe {
@@ -137,6 +148,12 @@ fn test_named_thread_truncation() {
137148
fn set_thread_name(name: &CStr) -> i32 {
138149
#[cfg(target_os = "linux")]
139150
return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) };
151+
#[cfg(target_os = "freebsd")]
152+
unsafe {
153+
// pthread_set_name_np does not return anything
154+
libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr().cast());
155+
return 0;
156+
};
140157
#[cfg(target_os = "macos")]
141158
return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) };
142159
}
@@ -147,16 +164,23 @@ fn test_named_thread_truncation() {
147164

148165
// But the system is limited -- make sure we successfully set a truncation.
149166
let mut buf = vec![0u8; long_name.len() + 1];
167+
#[cfg(not(target_os = "freebsd"))]
150168
unsafe {
151169
libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
152170
};
171+
#[cfg(target_os = "freebsd")]
172+
unsafe {
173+
libc::pthread_get_name_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
174+
};
153175
let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
154-
assert!(cstr.to_bytes().len() >= 15); // POSIX seems to promise at least 15 chars
176+
assert!(cstr.to_bytes().len() >= 15, "name is too short: len={}", cstr.to_bytes().len()); // POSIX seems to promise at least 15 chars
155177
assert!(long_name.as_bytes().starts_with(cstr.to_bytes()));
156178

157179
// Also test directly calling pthread_setname to check its return value.
158180
assert_eq!(set_thread_name(&cstr), 0);
159-
// But with a too long name it should fail.
181+
// But with a too long name it should fail (except on FreeBSD where the
182+
// function has no return, hence cannot indicate failure).
183+
#[cfg(not(target_os = "freebsd"))]
160184
assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0);
161185
});
162186
result.unwrap().join().unwrap();

0 commit comments

Comments
 (0)