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