miri/shims/unix/linux_like/
thread.rs1use rustc_abi::{CanonAbi, Size};
2use rustc_middle::ty::Ty;
3use rustc_span::Symbol;
4use rustc_target::callconv::FnAbi;
5
6use crate::shims::sig::check_min_vararg_count;
7use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult};
8use crate::*;
9
10const TASK_COMM_LEN: u64 = 16;
11
12pub fn prctl<'tcx>(
13 ecx: &mut MiriInterpCx<'tcx>,
14 link_name: Symbol,
15 abi: &FnAbi<'tcx, Ty<'tcx>>,
16 args: &[OpTy<'tcx>],
17 dest: &MPlaceTy<'tcx>,
18) -> InterpResult<'tcx> {
19 let ([op], varargs) = ecx.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?;
20
21 let pr_set_name = ecx.eval_libc_i32("PR_SET_NAME");
22 let pr_get_name = ecx.eval_libc_i32("PR_GET_NAME");
23
24 let res = match ecx.read_scalar(op)?.to_i32()? {
25 op if op == pr_set_name => {
26 let [name] = check_min_vararg_count("prctl(PR_SET_NAME, ...)", varargs)?;
27 let name = ecx.read_scalar(name)?;
28 let thread = ecx.pthread_self()?;
29 let res =
32 ecx.pthread_setname_np(thread, name, TASK_COMM_LEN, true)?;
33 assert_eq!(res, ThreadNameResult::Ok);
34 Scalar::from_u32(0)
35 }
36 op if op == pr_get_name => {
37 let [name] = check_min_vararg_count("prctl(PR_GET_NAME, ...)", varargs)?;
38 let name = ecx.read_scalar(name)?;
39 let thread = ecx.pthread_self()?;
40 let len = Scalar::from_target_usize(TASK_COMM_LEN, ecx);
41 ecx.check_ptr_access(
42 name.to_pointer(ecx)?,
43 Size::from_bytes(TASK_COMM_LEN),
44 CheckInAllocMsg::MemoryAccess,
45 )?;
46 let res = ecx.pthread_getname_np(thread, name, len, false)?;
47 assert_eq!(res, ThreadNameResult::Ok);
48 Scalar::from_u32(0)
49 }
50 op => throw_unsup_format!("Miri does not support `prctl` syscall with op={}", op),
51 };
52 ecx.write_scalar(res, dest)?;
53 interp_ok(())
54}