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], _) = ecx.check_varargs(
29 shim_varargs![*libc::c_char],
30 varargs,
31 "prctl(PR_SET_NAME, ...)",
32 )?;
33
34 let name = ecx.read_scalar(name)?;
35 let thread = ecx.pthread_self()?;
36 let res =
39 ecx.pthread_setname_np(thread, name, TASK_COMM_LEN, true)?;
40 assert_eq!(res, ThreadNameResult::Ok);
41 Scalar::from_u32(0)
42 }
43 op if op == pr_get_name => {
44 let ([name], _) = ecx.check_varargs(
45 shim_varargs![*libc::c_char],
46 varargs,
47 "prctl(PR_GET_NAME, ...)",
48 )?;
49
50 let name = ecx.read_scalar(name)?;
51 let thread = ecx.pthread_self()?;
52 let len = Scalar::from_target_usize(TASK_COMM_LEN, ecx);
53 ecx.check_ptr_access(
54 name.to_pointer(ecx),
55 Size::from_bytes(TASK_COMM_LEN),
56 CheckInAllocMsg::MemoryAccess,
57 )?;
58 let res = ecx.pthread_getname_np(thread, name, len, false)?;
59 assert_eq!(res, ThreadNameResult::Ok);
60 Scalar::from_u32(0)
61 }
62 op => throw_unsup_format!("Miri does not support `prctl` syscall with op={}", op),
63 };
64 ecx.write_scalar(res, dest)?;
65 interp_ok(())
66}