Auto merge of #3143 - devnexen:fbsd_update, r=RalfJung
freebsd interceptions update proposal
This commit is contained in:
commit
e25a04fbe5
@ -108,7 +108,7 @@ case $HOST_TARGET in
|
|||||||
MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
|
MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
|
||||||
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
|
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
|
||||||
MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
|
MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
|
||||||
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic env/var
|
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthreads atomic env/var
|
||||||
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
|
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
|
||||||
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
|
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm
|
||||||
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm
|
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm
|
||||||
|
@ -29,13 +29,23 @@ fn emulate_foreign_item_inner(
|
|||||||
"pthread_set_name_np" => {
|
"pthread_set_name_np" => {
|
||||||
let [thread, name] =
|
let [thread, name] =
|
||||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
let max_len = usize::MAX; // freebsd does not seem to have a limit.
|
let max_len = usize::MAX; // FreeBSD does not seem to have a limit.
|
||||||
let res = this.pthread_setname_np(
|
// FreeBSD's pthread_set_name_np does not return anything.
|
||||||
|
this.pthread_setname_np(
|
||||||
this.read_scalar(thread)?,
|
this.read_scalar(thread)?,
|
||||||
this.read_scalar(name)?,
|
this.read_scalar(name)?,
|
||||||
max_len,
|
max_len,
|
||||||
)?;
|
)?;
|
||||||
this.write_scalar(res, dest)?;
|
}
|
||||||
|
"pthread_get_name_np" => {
|
||||||
|
let [thread, name, len] =
|
||||||
|
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
|
// FreeBSD's pthread_get_name_np does not return anything.
|
||||||
|
this.pthread_getname_np(
|
||||||
|
this.read_scalar(thread)?,
|
||||||
|
this.read_scalar(name)?,
|
||||||
|
this.read_scalar(len)?,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// errno
|
// errno
|
||||||
|
@ -277,6 +277,13 @@ fn pthread_mutexattr_init(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_mutexattr_init` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let default_kind = this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT");
|
let default_kind = this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT");
|
||||||
mutexattr_set_kind(this, attr_op, default_kind)?;
|
mutexattr_set_kind(this, attr_op, default_kind)?;
|
||||||
|
|
||||||
@ -359,6 +366,13 @@ fn pthread_mutex_init(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_mutex_init` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let attr = this.read_pointer(attr_op)?;
|
let attr = this.read_pointer(attr_op)?;
|
||||||
let kind = if this.ptr_is_null(attr)? {
|
let kind = if this.ptr_is_null(attr)? {
|
||||||
this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")
|
this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")
|
||||||
@ -513,6 +527,13 @@ fn pthread_rwlock_rdlock(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_rwlock_rdlock` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let id = rwlock_get_id(this, rwlock_op)?;
|
let id = rwlock_get_id(this, rwlock_op)?;
|
||||||
let active_thread = this.get_active_thread();
|
let active_thread = this.get_active_thread();
|
||||||
|
|
||||||
@ -531,6 +552,13 @@ fn pthread_rwlock_tryrdlock(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_rwlock_tryrdlock` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let id = rwlock_get_id(this, rwlock_op)?;
|
let id = rwlock_get_id(this, rwlock_op)?;
|
||||||
let active_thread = this.get_active_thread();
|
let active_thread = this.get_active_thread();
|
||||||
|
|
||||||
@ -548,6 +576,13 @@ fn pthread_rwlock_wrlock(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_rwlock_wrlock` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let id = rwlock_get_id(this, rwlock_op)?;
|
let id = rwlock_get_id(this, rwlock_op)?;
|
||||||
let active_thread = this.get_active_thread();
|
let active_thread = this.get_active_thread();
|
||||||
|
|
||||||
@ -578,6 +613,13 @@ fn pthread_rwlock_trywrlock(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_rwlock_trywrlock` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let id = rwlock_get_id(this, rwlock_op)?;
|
let id = rwlock_get_id(this, rwlock_op)?;
|
||||||
let active_thread = this.get_active_thread();
|
let active_thread = this.get_active_thread();
|
||||||
|
|
||||||
@ -595,6 +637,13 @@ fn pthread_rwlock_unlock(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_rwlock_unlock` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let id = rwlock_get_id(this, rwlock_op)?;
|
let id = rwlock_get_id(this, rwlock_op)?;
|
||||||
let active_thread = this.get_active_thread();
|
let active_thread = this.get_active_thread();
|
||||||
|
|
||||||
@ -614,6 +663,13 @@ fn pthread_rwlock_destroy(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_rwlock_destroy` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let id = rwlock_get_id(this, rwlock_op)?;
|
let id = rwlock_get_id(this, rwlock_op)?;
|
||||||
|
|
||||||
if this.rwlock_is_locked(id) {
|
if this.rwlock_is_locked(id) {
|
||||||
@ -638,6 +694,13 @@ fn pthread_condattr_init(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_condattr_init` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// The default value of the clock attribute shall refer to the system
|
// The default value of the clock attribute shall refer to the system
|
||||||
// clock.
|
// clock.
|
||||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setclock.html
|
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setclock.html
|
||||||
@ -704,6 +767,13 @@ fn pthread_cond_init(
|
|||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
|
||||||
|
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
|
||||||
|
throw_unsup_format!(
|
||||||
|
"`pthread_cond_init` is not supported on {}",
|
||||||
|
this.tcx.sess.target.os
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let attr = this.read_pointer(attr_op)?;
|
let attr = this.read_pointer(attr_op)?;
|
||||||
let clock_id = if this.ptr_is_null(attr)? {
|
let clock_id = if this.ptr_is_null(attr)? {
|
||||||
this.eval_libc_i32("CLOCK_REALTIME")
|
this.eval_libc_i32("CLOCK_REALTIME")
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
//@ignore-target-windows: No libc on Windows
|
//@ignore-target-windows: No libc on Windows
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::CStr;
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
|
use std::ffi::CString;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test_mutex_libc_init_recursive();
|
|
||||||
test_mutex_libc_init_normal();
|
|
||||||
test_mutex_libc_init_errorcheck();
|
|
||||||
test_rwlock_libc_static_initializer();
|
|
||||||
test_named_thread_truncation();
|
test_named_thread_truncation();
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
|
test_mutex_libc_init_recursive();
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
|
test_mutex_libc_init_normal();
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
|
test_mutex_libc_init_errorcheck();
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
|
test_rwlock_libc_static_initializer();
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
test_mutex_libc_static_initializer_recursive();
|
test_mutex_libc_static_initializer_recursive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
fn test_mutex_libc_init_recursive() {
|
fn test_mutex_libc_init_recursive() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut attr: libc::pthread_mutexattr_t = std::mem::zeroed();
|
let mut attr: libc::pthread_mutexattr_t = std::mem::zeroed();
|
||||||
@ -37,6 +45,7 @@ fn test_mutex_libc_init_recursive() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
fn test_mutex_libc_init_normal() {
|
fn test_mutex_libc_init_normal() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
|
let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
|
||||||
@ -59,6 +68,7 @@ fn test_mutex_libc_init_normal() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
fn test_mutex_libc_init_errorcheck() {
|
fn test_mutex_libc_init_errorcheck() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
|
let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed();
|
||||||
@ -104,6 +114,7 @@ fn test_mutex_libc_static_initializer_recursive() {
|
|||||||
// Testing the behavior of std::sync::RwLock does not fully exercise the pthread rwlock shims, we
|
// Testing the behavior of std::sync::RwLock does not fully exercise the pthread rwlock shims, we
|
||||||
// need to go a layer deeper and test the behavior of the libc functions, because
|
// need to go a layer deeper and test the behavior of the libc functions, because
|
||||||
// std::sys::unix::rwlock::RWLock itself keeps track of write_locked and num_readers.
|
// std::sys::unix::rwlock::RWLock itself keeps track of write_locked and num_readers.
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
fn test_rwlock_libc_static_initializer() {
|
fn test_rwlock_libc_static_initializer() {
|
||||||
let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
|
let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER);
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -137,6 +148,12 @@ fn test_named_thread_truncation() {
|
|||||||
fn set_thread_name(name: &CStr) -> i32 {
|
fn set_thread_name(name: &CStr) -> i32 {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) };
|
return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) };
|
||||||
|
#[cfg(target_os = "freebsd")]
|
||||||
|
unsafe {
|
||||||
|
// pthread_set_name_np does not return anything
|
||||||
|
libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr().cast());
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) };
|
return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) };
|
||||||
}
|
}
|
||||||
@ -147,16 +164,23 @@ fn set_thread_name(name: &CStr) -> i32 {
|
|||||||
|
|
||||||
// But the system is limited -- make sure we successfully set a truncation.
|
// But the system is limited -- make sure we successfully set a truncation.
|
||||||
let mut buf = vec![0u8; long_name.len() + 1];
|
let mut buf = vec![0u8; long_name.len() + 1];
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
|
libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
|
||||||
};
|
};
|
||||||
|
#[cfg(target_os = "freebsd")]
|
||||||
|
unsafe {
|
||||||
|
libc::pthread_get_name_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
|
||||||
|
};
|
||||||
let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
|
let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
|
||||||
assert!(cstr.to_bytes().len() >= 15); // POSIX seems to promise at least 15 chars
|
assert!(cstr.to_bytes().len() >= 15, "name is too short: len={}", cstr.to_bytes().len()); // POSIX seems to promise at least 15 chars
|
||||||
assert!(long_name.as_bytes().starts_with(cstr.to_bytes()));
|
assert!(long_name.as_bytes().starts_with(cstr.to_bytes()));
|
||||||
|
|
||||||
// Also test directly calling pthread_setname to check its return value.
|
// Also test directly calling pthread_setname to check its return value.
|
||||||
assert_eq!(set_thread_name(&cstr), 0);
|
assert_eq!(set_thread_name(&cstr), 0);
|
||||||
// But with a too long name it should fail.
|
// But with a too long name it should fail (except on FreeBSD where the
|
||||||
|
// function has no return, hence cannot indicate failure).
|
||||||
|
#[cfg(not(target_os = "freebsd"))]
|
||||||
assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0);
|
assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0);
|
||||||
});
|
});
|
||||||
result.unwrap().join().unwrap();
|
result.unwrap().join().unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user