remove a rustfmt::skip

This commit is contained in:
Ralf Jung 2025-01-12 16:41:51 +01:00
parent 30708e1eab
commit be36fbb720

View file

@ -109,56 +109,54 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let this = self.eval_context_mut();
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
#[rustfmt::skip]
match link_name.as_str() {
// Environment related shims
"getenv" => {
let [name] = this.check_shim(abi, Conv::C , link_name, args)?;
let [name] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.getenv(name)?;
this.write_pointer(result, dest)?;
}
"unsetenv" => {
let [name] = this.check_shim(abi, Conv::C , link_name, args)?;
let [name] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.unsetenv(name)?;
this.write_scalar(result, dest)?;
}
"setenv" => {
let [name, value, overwrite] = this.check_shim(abi, Conv::C , link_name, args)?;
let [name, value, overwrite] = this.check_shim(abi, Conv::C, link_name, args)?;
this.read_scalar(overwrite)?.to_i32()?;
let result = this.setenv(name, value)?;
this.write_scalar(result, dest)?;
}
"getcwd" => {
let [buf, size] = this.check_shim(abi, Conv::C , link_name, args)?;
let [buf, size] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.getcwd(buf, size)?;
this.write_pointer(result, dest)?;
}
"chdir" => {
let [path] = this.check_shim(abi, Conv::C , link_name, args)?;
let [path] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.chdir(path)?;
this.write_scalar(result, dest)?;
}
"getpid" => {
let [] = this.check_shim(abi, Conv::C , link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.getpid()?;
this.write_scalar(result, dest)?;
}
"sysconf" => {
let [val] =
this.check_shim(abi, Conv::C, link_name, args)?;
let [val] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.sysconf(val)?;
this.write_scalar(result, dest)?;
}
// File descriptors
"read" => {
let [fd, buf, count] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, buf, count] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let buf = this.read_pointer(buf)?;
let count = this.read_target_usize(count)?;
this.read(fd, buf, count, None, dest)?;
}
"write" => {
let [fd, buf, n] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, buf, n] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let buf = this.read_pointer(buf)?;
let count = this.read_target_usize(n)?;
@ -166,7 +164,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write(fd, buf, count, None, dest)?;
}
"pread" => {
let [fd, buf, count, offset] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, buf, count, offset] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let buf = this.read_pointer(buf)?;
let count = this.read_target_usize(count)?;
@ -174,7 +172,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.read(fd, buf, count, Some(offset), dest)?;
}
"pwrite" => {
let [fd, buf, n, offset] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, buf, n, offset] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let buf = this.read_pointer(buf)?;
let count = this.read_target_usize(n)?;
@ -183,49 +181,51 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write(fd, buf, count, Some(offset), dest)?;
}
"pread64" => {
let [fd, buf, count, offset] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, buf, count, offset] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let buf = this.read_pointer(buf)?;
let count = this.read_target_usize(count)?;
let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off64_t").size)?;
let offset =
this.read_scalar(offset)?.to_int(this.libc_ty_layout("off64_t").size)?;
this.read(fd, buf, count, Some(offset), dest)?;
}
"pwrite64" => {
let [fd, buf, n, offset] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, buf, n, offset] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let buf = this.read_pointer(buf)?;
let count = this.read_target_usize(n)?;
let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off64_t").size)?;
let offset =
this.read_scalar(offset)?.to_int(this.libc_ty_layout("off64_t").size)?;
trace!("Called pwrite64({:?}, {:?}, {:?}, {:?})", fd, buf, count, offset);
this.write(fd, buf, count, Some(offset), dest)?;
}
"close" => {
let [fd] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.close(fd)?;
this.write_scalar(result, dest)?;
}
"fcntl" => {
// `fcntl` is variadic. The argument count is checked based on the first argument
// in `this.fcntl()`, so we do not use `check_shim` here.
this.check_abi_and_shim_symbol_clash(abi, Conv::C , link_name)?;
this.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
let result = this.fcntl(args)?;
this.write_scalar(result, dest)?;
}
"dup" => {
let [old_fd] = this.check_shim(abi, Conv::C , link_name, args)?;
let [old_fd] = this.check_shim(abi, Conv::C, link_name, args)?;
let old_fd = this.read_scalar(old_fd)?.to_i32()?;
let new_fd = this.dup(old_fd)?;
this.write_scalar(new_fd, dest)?;
}
"dup2" => {
let [old_fd, new_fd] = this.check_shim(abi, Conv::C , link_name, args)?;
let [old_fd, new_fd] = this.check_shim(abi, Conv::C, link_name, args)?;
let old_fd = this.read_scalar(old_fd)?.to_i32()?;
let new_fd = this.read_scalar(new_fd)?.to_i32()?;
let result = this.dup2(old_fd, new_fd)?;
this.write_scalar(result, dest)?;
}
"flock" => {
let [fd, op] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, op] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let op = this.read_scalar(op)?.to_i32()?;
let result = this.flock(fd, op)?;
@ -234,48 +234,49 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// File and file system access
"open" | "open64" => {
// `open` is variadic, the third argument is only present when the second argument has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set
this.check_abi_and_shim_symbol_clash(abi, Conv::C , link_name)?;
// `open` is variadic, the third argument is only present when the second argument
// has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set
this.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
let result = this.open(args)?;
this.write_scalar(result, dest)?;
}
"unlink" => {
let [path] = this.check_shim(abi, Conv::C , link_name, args)?;
let [path] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.unlink(path)?;
this.write_scalar(result, dest)?;
}
"symlink" => {
let [target, linkpath] = this.check_shim(abi, Conv::C , link_name, args)?;
let [target, linkpath] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.symlink(target, linkpath)?;
this.write_scalar(result, dest)?;
}
"rename" => {
let [oldpath, newpath] = this.check_shim(abi, Conv::C , link_name, args)?;
let [oldpath, newpath] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.rename(oldpath, newpath)?;
this.write_scalar(result, dest)?;
}
"mkdir" => {
let [path, mode] = this.check_shim(abi, Conv::C , link_name, args)?;
let [path, mode] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.mkdir(path, mode)?;
this.write_scalar(result, dest)?;
}
"rmdir" => {
let [path] = this.check_shim(abi, Conv::C , link_name, args)?;
let [path] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.rmdir(path)?;
this.write_scalar(result, dest)?;
}
"opendir" => {
let [name] = this.check_shim(abi, Conv::C , link_name, args)?;
let [name] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.opendir(name)?;
this.write_scalar(result, dest)?;
}
"closedir" => {
let [dirp] = this.check_shim(abi, Conv::C , link_name, args)?;
let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.closedir(dirp)?;
this.write_scalar(result, dest)?;
}
"lseek64" => {
let [fd, offset, whence] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, offset, whence] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let offset = this.read_scalar(offset)?.to_i64()?;
let whence = this.read_scalar(whence)?.to_i32()?;
@ -283,7 +284,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_scalar(result, dest)?;
}
"lseek" => {
let [fd, offset, whence] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, offset, whence] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
let whence = this.read_scalar(whence)?.to_i32()?;
@ -291,39 +292,36 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_scalar(result, dest)?;
}
"ftruncate64" => {
let [fd, length] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, length] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let length = this.read_scalar(length)?.to_i64()?;
let result = this.ftruncate64(fd, length.into())?;
this.write_scalar(result, dest)?;
}
"ftruncate" => {
let [fd, length] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, length] = this.check_shim(abi, Conv::C, link_name, args)?;
let fd = this.read_scalar(fd)?.to_i32()?;
let length = this.read_scalar(length)?.to_int(this.libc_ty_layout("off_t").size)?;
let result = this.ftruncate64(fd, length)?;
this.write_scalar(result, dest)?;
}
"fsync" => {
let [fd] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.fsync(fd)?;
this.write_scalar(result, dest)?;
}
"fdatasync" => {
let [fd] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.fdatasync(fd)?;
this.write_scalar(result, dest)?;
}
"readlink" => {
let [pathname, buf, bufsize] = this.check_shim(abi, Conv::C , link_name, args)?;
let [pathname, buf, bufsize] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.readlink(pathname, buf, bufsize)?;
this.write_scalar(Scalar::from_target_isize(result, this), dest)?;
}
"posix_fadvise" => {
let [fd, offset, len, advice] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [fd, offset, len, advice] = this.check_shim(abi, Conv::C, link_name, args)?;
this.read_scalar(fd)?.to_i32()?;
this.read_target_isize(offset)?;
this.read_target_isize(len)?;
@ -332,12 +330,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_null(dest)?;
}
"realpath" => {
let [path, resolved_path] = this.check_shim(abi, Conv::C , link_name, args)?;
let [path, resolved_path] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.realpath(path, resolved_path)?;
this.write_scalar(result, dest)?;
}
"mkstemp" => {
let [template] = this.check_shim(abi, Conv::C , link_name, args)?;
let [template] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.mkstemp(template)?;
this.write_scalar(result, dest)?;
}
@ -345,63 +343,59 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Unnamed sockets and pipes
"socketpair" => {
let [domain, type_, protocol, sv] =
this.check_shim(abi, Conv::C , link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.socketpair(domain, type_, protocol, sv)?;
this.write_scalar(result, dest)?;
}
"pipe" => {
let [pipefd] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [pipefd] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.pipe2(pipefd, /*flags*/ None)?;
this.write_scalar(result, dest)?;
}
"pipe2" => {
// Currently this function does not exist on all Unixes, e.g. on macOS.
if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "solaris" | "illumos") {
throw_unsup_format!(
"`pipe2` is not supported on {}",
this.tcx.sess.target.os
);
if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "solaris" | "illumos")
{
throw_unsup_format!("`pipe2` is not supported on {}", this.tcx.sess.target.os);
}
let [pipefd, flags] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [pipefd, flags] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.pipe2(pipefd, Some(flags))?;
this.write_scalar(result, dest)?;
}
// Time
"gettimeofday" => {
let [tv, tz] = this.check_shim(abi, Conv::C , link_name, args)?;
let [tv, tz] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.gettimeofday(tv, tz)?;
this.write_scalar(result, dest)?;
}
"localtime_r" => {
let [timep, result_op] = this.check_shim(abi, Conv::C , link_name, args)?;
let [timep, result_op] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.localtime_r(timep, result_op)?;
this.write_pointer(result, dest)?;
}
"clock_gettime" => {
let [clk_id, tp] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [clk_id, tp] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.clock_gettime(clk_id, tp)?;
this.write_scalar(result, dest)?;
}
// Allocation
"posix_memalign" => {
let [memptr, align, size] = this.check_shim(abi, Conv::C , link_name, args)?;
let [memptr, align, size] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.posix_memalign(memptr, align, size)?;
this.write_scalar(result, dest)?;
}
"mmap" => {
let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, Conv::C , link_name, args)?;
let [addr, length, prot, flags, fd, offset] =
this.check_shim(abi, Conv::C, link_name, args)?;
let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
let ptr = this.mmap(addr, length, prot, flags, fd, offset)?;
this.write_scalar(ptr, dest)?;
}
"munmap" => {
let [addr, length] = this.check_shim(abi, Conv::C , link_name, args)?;
let [addr, length] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.munmap(addr, length)?;
this.write_scalar(result, dest)?;
}
@ -414,8 +408,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.tcx.sess.target.os
);
}
let [ptr, nmemb, size] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [ptr, nmemb, size] = this.check_shim(abi, Conv::C, link_name, args)?;
let ptr = this.read_pointer(ptr)?;
let nmemb = this.read_target_usize(nmemb)?;
let size = this.read_target_usize(size)?;
@ -438,19 +431,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"aligned_alloc" => {
// This is a C11 function, we assume all Unixes have it.
// (MSVC explicitly does not support this.)
let [align, size] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [align, size] = this.check_shim(abi, Conv::C, link_name, args)?;
let res = this.aligned_alloc(align, size)?;
this.write_pointer(res, dest)?;
}
// Dynamic symbol loading
"dlsym" => {
let [handle, symbol] = this.check_shim(abi, Conv::C , link_name, args)?;
let [handle, symbol] = this.check_shim(abi, Conv::C, link_name, args)?;
this.read_target_usize(handle)?;
let symbol = this.read_pointer(symbol)?;
let name = this.read_c_str(symbol)?;
if let Ok(name) = str::from_utf8(name) && is_dyn_sym(name, &this.tcx.sess.target.os) {
if let Ok(name) = str::from_utf8(name)
&& is_dyn_sym(name, &this.tcx.sess.target.os)
{
let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str(name)));
this.write_pointer(ptr, dest)?;
} else {
@ -460,7 +454,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Thread-local storage
"pthread_key_create" => {
let [key, dtor] = this.check_shim(abi, Conv::C , link_name, args)?;
let [key, dtor] = this.check_shim(abi, Conv::C, link_name, args)?;
let key_place = this.deref_pointer_as(key, this.libc_ty_layout("pthread_key_t"))?;
let dtor = this.read_pointer(dtor)?;
@ -488,21 +482,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_null(dest)?;
}
"pthread_key_delete" => {
let [key] = this.check_shim(abi, Conv::C , link_name, args)?;
let [key] = this.check_shim(abi, Conv::C, link_name, args)?;
let key = this.read_scalar(key)?.to_bits(key.layout.size)?;
this.machine.tls.delete_tls_key(key)?;
// Return success (0)
this.write_null(dest)?;
}
"pthread_getspecific" => {
let [key] = this.check_shim(abi, Conv::C , link_name, args)?;
let [key] = this.check_shim(abi, Conv::C, link_name, args)?;
let key = this.read_scalar(key)?.to_bits(key.layout.size)?;
let active_thread = this.active_thread();
let ptr = this.machine.tls.load_tls(key, active_thread, this)?;
this.write_scalar(ptr, dest)?;
}
"pthread_setspecific" => {
let [key, new_ptr] = this.check_shim(abi, Conv::C , link_name, args)?;
let [key, new_ptr] = this.check_shim(abi, Conv::C, link_name, args)?;
let key = this.read_scalar(key)?.to_bits(key.layout.size)?;
let active_thread = this.active_thread();
let new_data = this.read_scalar(new_ptr)?;
@ -514,151 +508,149 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Synchronization primitives
"pthread_mutexattr_init" => {
let [attr] = this.check_shim(abi, Conv::C , link_name, args)?;
let [attr] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_mutexattr_init(attr)?;
this.write_null(dest)?;
}
"pthread_mutexattr_settype" => {
let [attr, kind] = this.check_shim(abi, Conv::C , link_name, args)?;
let [attr, kind] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.pthread_mutexattr_settype(attr, kind)?;
this.write_scalar(result, dest)?;
}
"pthread_mutexattr_destroy" => {
let [attr] = this.check_shim(abi, Conv::C , link_name, args)?;
let [attr] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_mutexattr_destroy(attr)?;
this.write_null(dest)?;
}
"pthread_mutex_init" => {
let [mutex, attr] = this.check_shim(abi, Conv::C , link_name, args)?;
let [mutex, attr] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_mutex_init(mutex, attr)?;
this.write_null(dest)?;
}
"pthread_mutex_lock" => {
let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?;
let [mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_mutex_lock(mutex, dest)?;
}
"pthread_mutex_trylock" => {
let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?;
let [mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.pthread_mutex_trylock(mutex)?;
this.write_scalar(result, dest)?;
}
"pthread_mutex_unlock" => {
let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?;
let [mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.pthread_mutex_unlock(mutex)?;
this.write_scalar(result, dest)?;
}
"pthread_mutex_destroy" => {
let [mutex] = this.check_shim(abi, Conv::C , link_name, args)?;
let [mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_mutex_destroy(mutex)?;
this.write_int(0, dest)?;
}
"pthread_rwlock_rdlock" => {
let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?;
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_rwlock_rdlock(rwlock, dest)?;
}
"pthread_rwlock_tryrdlock" => {
let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?;
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.pthread_rwlock_tryrdlock(rwlock)?;
this.write_scalar(result, dest)?;
}
"pthread_rwlock_wrlock" => {
let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?;
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_rwlock_wrlock(rwlock, dest)?;
}
"pthread_rwlock_trywrlock" => {
let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?;
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.pthread_rwlock_trywrlock(rwlock)?;
this.write_scalar(result, dest)?;
}
"pthread_rwlock_unlock" => {
let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?;
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_rwlock_unlock(rwlock)?;
this.write_null(dest)?;
}
"pthread_rwlock_destroy" => {
let [rwlock] = this.check_shim(abi, Conv::C , link_name, args)?;
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_rwlock_destroy(rwlock)?;
this.write_null(dest)?;
}
"pthread_condattr_init" => {
let [attr] = this.check_shim(abi, Conv::C , link_name, args)?;
let [attr] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_condattr_init(attr)?;
this.write_null(dest)?;
}
"pthread_condattr_setclock" => {
let [attr, clock_id] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [attr, clock_id] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.pthread_condattr_setclock(attr, clock_id)?;
this.write_scalar(result, dest)?;
}
"pthread_condattr_getclock" => {
let [attr, clock_id] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [attr, clock_id] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_condattr_getclock(attr, clock_id)?;
this.write_null(dest)?;
}
"pthread_condattr_destroy" => {
let [attr] = this.check_shim(abi, Conv::C , link_name, args)?;
let [attr] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_condattr_destroy(attr)?;
this.write_null(dest)?;
}
"pthread_cond_init" => {
let [cond, attr] = this.check_shim(abi, Conv::C , link_name, args)?;
let [cond, attr] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_cond_init(cond, attr)?;
this.write_null(dest)?;
}
"pthread_cond_signal" => {
let [cond] = this.check_shim(abi, Conv::C , link_name, args)?;
let [cond] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_cond_signal(cond)?;
this.write_null(dest)?;
}
"pthread_cond_broadcast" => {
let [cond] = this.check_shim(abi, Conv::C , link_name, args)?;
let [cond] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_cond_broadcast(cond)?;
this.write_null(dest)?;
}
"pthread_cond_wait" => {
let [cond, mutex] = this.check_shim(abi, Conv::C , link_name, args)?;
let [cond, mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_cond_wait(cond, mutex, dest)?;
}
"pthread_cond_timedwait" => {
let [cond, mutex, abstime] = this.check_shim(abi, Conv::C , link_name, args)?;
let [cond, mutex, abstime] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_cond_timedwait(cond, mutex, abstime, dest)?;
}
"pthread_cond_destroy" => {
let [cond] = this.check_shim(abi, Conv::C , link_name, args)?;
let [cond] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_cond_destroy(cond)?;
this.write_null(dest)?;
}
// Threading
"pthread_create" => {
let [thread, attr, start, arg] = this.check_shim(abi, Conv::C , link_name, args)?;
let [thread, attr, start, arg] = this.check_shim(abi, Conv::C, link_name, args)?;
this.pthread_create(thread, attr, start, arg)?;
this.write_null(dest)?;
}
"pthread_join" => {
let [thread, retval] = this.check_shim(abi, Conv::C , link_name, args)?;
let [thread, retval] = this.check_shim(abi, Conv::C, link_name, args)?;
let res = this.pthread_join(thread, retval)?;
this.write_scalar(res, dest)?;
}
"pthread_detach" => {
let [thread] = this.check_shim(abi, Conv::C , link_name, args)?;
let [thread] = this.check_shim(abi, Conv::C, link_name, args)?;
let res = this.pthread_detach(thread)?;
this.write_scalar(res, dest)?;
}
"pthread_self" => {
let [] = this.check_shim(abi, Conv::C , link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let res = this.pthread_self()?;
this.write_scalar(res, dest)?;
}
"sched_yield" => {
let [] = this.check_shim(abi, Conv::C , link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
this.sched_yield()?;
this.write_null(dest)?;
}
"nanosleep" => {
let [req, rem] = this.check_shim(abi, Conv::C , link_name, args)?;
let [req, rem] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.nanosleep(req, rem)?;
this.write_scalar(result, dest)?;
}
@ -671,8 +663,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
);
}
let [pid, cpusetsize, mask] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [pid, cpusetsize, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
let pid = this.read_scalar(pid)?.to_u32()?;
let cpusetsize = this.read_target_usize(cpusetsize)?;
let mask = this.read_pointer(mask)?;
@ -680,7 +671,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// TODO: when https://github.com/rust-lang/miri/issues/3730 is fixed this should use its notion of tid/pid
let thread_id = match pid {
0 => this.active_thread(),
_ => throw_unsup_format!("`sched_getaffinity` is only supported with a pid of 0 (indicating the current thread)"),
_ =>
throw_unsup_format!(
"`sched_getaffinity` is only supported with a pid of 0 (indicating the current thread)"
),
};
// The mask is stored in chunks, and the size must be a whole number of chunks.
@ -694,7 +688,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
} else if let Some(cpuset) = this.machine.thread_cpu_affinity.get(&thread_id) {
let cpuset = cpuset.clone();
// we only copy whole chunks of size_of::<c_ulong>()
let byte_count = Ord::min(cpuset.as_slice().len(), cpusetsize.try_into().unwrap());
let byte_count =
Ord::min(cpuset.as_slice().len(), cpusetsize.try_into().unwrap());
this.write_bytes_ptr(mask, cpuset.as_slice()[..byte_count].iter().copied())?;
this.write_null(dest)?;
} else {
@ -711,8 +706,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
);
}
let [pid, cpusetsize, mask] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [pid, cpusetsize, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
let pid = this.read_scalar(pid)?.to_u32()?;
let cpusetsize = this.read_target_usize(cpusetsize)?;
let mask = this.read_pointer(mask)?;
@ -720,7 +714,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// TODO: when https://github.com/rust-lang/miri/issues/3730 is fixed this should use its notion of tid/pid
let thread_id = match pid {
0 => this.active_thread(),
_ => throw_unsup_format!("`sched_setaffinity` is only supported with a pid of 0 (indicating the current thread)"),
_ =>
throw_unsup_format!(
"`sched_setaffinity` is only supported with a pid of 0 (indicating the current thread)"
),
};
if this.ptr_is_null(mask)? {
@ -729,7 +726,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// NOTE: cpusetsize might be smaller than `CpuAffinityMask::CPU_MASK_BYTES`.
// Any unspecified bytes are treated as zero here (none of the CPUs are configured).
// This is not exactly documented, so we assume that this is the behavior in practice.
let bits_slice = this.read_bytes_ptr_strip_provenance(mask, Size::from_bytes(cpusetsize))?;
let bits_slice =
this.read_bytes_ptr_strip_provenance(mask, Size::from_bytes(cpusetsize))?;
// This ignores the bytes beyond `CpuAffinityMask::CPU_MASK_BYTES`
let bits_array: [u8; CpuAffinityMask::CPU_MASK_BYTES] =
std::array::from_fn(|i| bits_slice.get(i).copied().unwrap_or(0));
@ -748,12 +746,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Miscellaneous
"isatty" => {
let [fd] = this.check_shim(abi, Conv::C , link_name, args)?;
let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.isatty(fd)?;
this.write_scalar(result, dest)?;
}
"pthread_atfork" => {
let [prepare, parent, child] = this.check_shim(abi, Conv::C , link_name, args)?;
let [prepare, parent, child] = this.check_shim(abi, Conv::C, link_name, args)?;
this.read_pointer(prepare)?;
this.read_pointer(parent)?;
this.read_pointer(child)?;
@ -763,15 +761,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"getentropy" => {
// This function is non-standard but exists with the same signature and behavior on
// Linux, macOS, FreeBSD and Solaris/Illumos.
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd" | "illumos" | "solaris" | "android") {
if !matches!(
&*this.tcx.sess.target.os,
"linux" | "macos" | "freebsd" | "illumos" | "solaris" | "android"
) {
throw_unsup_format!(
"`getentropy` is not supported on {}",
this.tcx.sess.target.os
);
}
let [buf, bufsize] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [buf, bufsize] = this.check_shim(abi, Conv::C, link_name, args)?;
let buf = this.read_pointer(buf)?;
let bufsize = this.read_target_usize(bufsize)?;
@ -789,8 +789,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}
"strerror_r" => {
let [errnum, buf, buflen] =
this.check_shim(abi, Conv::C, link_name, args)?;
let [errnum, buf, buflen] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.strerror_r(errnum, buf, buflen)?;
this.write_scalar(result, dest)?;
}
@ -798,14 +797,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"getrandom" => {
// This function is non-standard but exists with the same signature and behavior on
// Linux, FreeBSD and Solaris/Illumos.
if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "illumos" | "solaris" | "android") {
if !matches!(
&*this.tcx.sess.target.os,
"linux" | "freebsd" | "illumos" | "solaris" | "android"
) {
throw_unsup_format!(
"`getrandom` is not supported on {}",
this.tcx.sess.target.os
);
}
let [ptr, len, flags] =
this.check_shim(abi, Conv::C , link_name, args)?;
let [ptr, len, flags] = this.check_shim(abi, Conv::C, link_name, args)?;
let ptr = this.read_pointer(ptr)?;
let len = this.read_target_usize(len)?;
let _flags = this.read_scalar(flags)?.to_i32()?;
@ -822,7 +823,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.tcx.sess.target.os
);
}
let [ptr, len] = this.check_shim(abi, Conv::C , link_name, args)?;
let [ptr, len] = this.check_shim(abi, Conv::C, link_name, args)?;
let ptr = this.read_pointer(ptr)?;
let len = this.read_target_usize(len)?;
this.gen_random(ptr, len)?;
@ -841,7 +842,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// For arm32 they did something custom, but similar enough that the same
// `_Unwind_RaiseException` impl in miri should work:
// https://github.com/ARM-software/abi-aa/blob/main/ehabi32/ehabi32.rst
if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "illumos" | "solaris" | "android" | "macos") {
if !matches!(
&*this.tcx.sess.target.os,
"linux" | "freebsd" | "illumos" | "solaris" | "android" | "macos"
) {
throw_unsup_format!(
"`_Unwind_RaiseException` is not supported on {}",
this.tcx.sess.target.os
@ -853,43 +857,42 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
return interp_ok(EmulateItemResult::NeedsUnwind);
}
"getuid" => {
let [] = this.check_shim(abi, Conv::C , link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
// For now, just pretend we always have this fixed UID.
this.write_int(UID, dest)?;
}
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
// These shims are enabled only when the caller is in the standard library.
"pthread_attr_getguardsize"
if this.frame_in_std() => {
let [_attr, guard_size] = this.check_shim(abi, Conv::C , link_name, args)?;
"pthread_attr_getguardsize" if this.frame_in_std() => {
let [_attr, guard_size] = this.check_shim(abi, Conv::C, link_name, args)?;
let guard_size = this.deref_pointer(guard_size)?;
let guard_size_layout = this.libc_ty_layout("size_t");
this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size)?;
this.write_scalar(
Scalar::from_uint(this.machine.page_size, guard_size_layout.size),
&guard_size,
)?;
// Return success (`0`).
this.write_null(dest)?;
}
| "pthread_attr_init"
| "pthread_attr_destroy"
if this.frame_in_std() => {
let [_] = this.check_shim(abi, Conv::C , link_name, args)?;
"pthread_attr_init" | "pthread_attr_destroy" if this.frame_in_std() => {
let [_] = this.check_shim(abi, Conv::C, link_name, args)?;
this.write_null(dest)?;
}
| "pthread_attr_setstacksize"
if this.frame_in_std() => {
let [_, _] = this.check_shim(abi, Conv::C , link_name, args)?;
"pthread_attr_setstacksize" if this.frame_in_std() => {
let [_, _] = this.check_shim(abi, Conv::C, link_name, args)?;
this.write_null(dest)?;
}
"pthread_attr_getstack"
if this.frame_in_std() => {
"pthread_attr_getstack" if this.frame_in_std() => {
// 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, Conv::C , link_name, args)?;
let _attr_place = this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?;
this.check_shim(abi, Conv::C, link_name, args)?;
let _attr_place =
this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?;
let addr_place = this.deref_pointer(addr_place)?;
let size_place = this.deref_pointer(size_place)?;
@ -906,24 +909,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_null(dest)?;
}
| "signal"
| "sigaltstack"
if this.frame_in_std() => {
let [_, _] = this.check_shim(abi, Conv::C , link_name, args)?;
"signal" | "sigaltstack" if this.frame_in_std() => {
let [_, _] = this.check_shim(abi, Conv::C, link_name, args)?;
this.write_null(dest)?;
}
| "sigaction"
| "mprotect"
if this.frame_in_std() => {
let [_, _, _] = this.check_shim(abi, Conv::C , link_name, args)?;
"sigaction" | "mprotect" if this.frame_in_std() => {
let [_, _, _] = this.check_shim(abi, Conv::C, link_name, args)?;
this.write_null(dest)?;
}
"getpwuid_r" | "__posix_getpwuid_r"
if this.frame_in_std() => {
"getpwuid_r" | "__posix_getpwuid_r" if this.frame_in_std() => {
// getpwuid_r is the standard name, __posix_getpwuid_r is used on solarish
let [uid, pwd, buf, buflen, result] =
this.check_shim(abi, Conv::C , link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.check_no_isolation("`getpwuid_r`")?;
let uid = this.read_scalar(uid)?.to_u32()?;
@ -961,11 +959,26 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
_ => {
let target_os = &*this.tcx.sess.target.os;
return match target_os {
"android" => android::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
"freebsd" => freebsd::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
"linux" => linux::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
"macos" => macos::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
"solaris" | "illumos" => solarish::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
"android" =>
android::EvalContextExt::emulate_foreign_item_inner(
this, link_name, abi, args, dest,
),
"freebsd" =>
freebsd::EvalContextExt::emulate_foreign_item_inner(
this, link_name, abi, args, dest,
),
"linux" =>
linux::EvalContextExt::emulate_foreign_item_inner(
this, link_name, abi, args, dest,
),
"macos" =>
macos::EvalContextExt::emulate_foreign_item_inner(
this, link_name, abi, args, dest,
),
"solaris" | "illumos" =>
solarish::EvalContextExt::emulate_foreign_item_inner(
this, link_name, abi, args, dest,
),
_ => interp_ok(EmulateItemResult::NotSupported),
};
}