miri/shims/unix/solarish/
foreign_items.rsuse rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};
use crate::shims::unix::foreign_items::EvalContextExt as _;
use crate::shims::unix::*;
use crate::*;
pub fn is_dyn_sym(name: &str) -> bool {
matches!(name, "pthread_setname_np")
}
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner(
&mut self,
link_name: Symbol,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
let this = self.eval_context_mut();
match link_name.as_str() {
"pthread_setname_np" => {
let [thread, name] = this.check_shim(abi, Conv::C, link_name, args)?;
let max_len = 32;
let res = match this.pthread_setname_np(
this.read_scalar(thread)?,
this.read_scalar(name)?,
max_len,
false,
)? {
ThreadNameResult::Ok => Scalar::from_u32(0),
ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
};
this.write_scalar(res, dest)?;
}
"pthread_getname_np" => {
let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?;
let res = match this.pthread_getname_np(
this.read_scalar(thread)?,
this.read_scalar(name)?,
this.read_scalar(len)?,
false,
)? {
ThreadNameResult::Ok => Scalar::from_u32(0),
ThreadNameResult::NameTooLong => this.eval_libc("ERANGE"),
ThreadNameResult::ThreadNotFound => this.eval_libc("ESRCH"),
};
this.write_scalar(res, dest)?;
}
"stat" | "stat64" => {
let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_stat(path, buf)?;
this.write_scalar(result, dest)?;
}
"lstat" | "lstat64" => {
let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_lstat(path, buf)?;
this.write_scalar(result, dest)?;
}
"fstat" | "fstat64" => {
let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
this.write_scalar(result, dest)?;
}
"readdir" => {
let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.linux_solarish_readdir64("dirent", dirp)?;
this.write_scalar(result, dest)?;
}
"___errno" => {
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let errno_place = this.last_error_place()?;
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
}
"stack_getbounds" => {
let [stack] = this.check_shim(abi, Conv::C, link_name, args)?;
let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?;
this.write_int_fields_named(
&[
("ss_sp", this.machine.stack_addr.into()),
("ss_size", this.machine.stack_size.into()),
("ss_flags", 0),
],
&stack,
)?;
this.write_null(dest)?;
}
"pset_info" => {
let [pset, tpe, cpus, list] = this.check_shim(abi, Conv::C, link_name, args)?;
let pset = this.read_scalar(pset)?.to_i32()?;
let tpe = this.read_pointer(tpe)?;
let list = this.read_pointer(list)?;
let ps_myid = this.eval_libc_i32("PS_MYID");
if ps_myid != pset {
throw_unsup_format!("pset_info is only supported with pset==PS_MYID");
}
if !this.ptr_is_null(tpe)? {
throw_unsup_format!("pset_info is only supported with type==NULL");
}
if !this.ptr_is_null(list)? {
throw_unsup_format!("pset_info is only supported with list==NULL");
}
let cpus = this.deref_pointer(cpus)?;
this.write_scalar(Scalar::from_u32(this.machine.num_cpus), &cpus)?;
this.write_null(dest)?;
}
"__sysconf_xpg7" => {
let [val] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.sysconf(val)?;
this.write_scalar(result, dest)?;
}
_ => return interp_ok(EmulateItemResult::NotSupported),
}
interp_ok(EmulateItemResult::NeedsReturn)
}
}