use crate::*;
-use rustc_index::vec::Idx;
use rustc_target::abi::LayoutOf;
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
);
let new_thread_id = this.create_thread()?;
+ // Also switch to new thread so that we can push the first stackframe.
let old_thread_id = this.set_active_thread(new_thread_id)?;
let thread_info_place = this.deref_operand(thread)?;
- let thread_info_type = thread.layout.ty
- .builtin_deref(true)
- .ok_or_else(|| err_ub_format!(
- "wrong signature used for `pthread_create`: first argument must be a raw pointer."
- ))?
- .ty;
- let thread_info_layout = this.layout_of(thread_info_type)?;
this.write_scalar(
- Scalar::from_uint(new_thread_id.index() as u128, thread_info_layout.size),
+ Scalar::from_uint(new_thread_id.to_u128(), thread_info_place.layout.size),
thread_info_place.into(),
)?;
let instance = this.memory.get_fn(fn_ptr)?.as_instance()?;
let func_arg = this.read_immediate(arg)?;
- let func_args = [*func_arg];
let ret_place =
this.allocate(this.layout_of(this.tcx.types.usize)?, MiriMemoryKind::Machine.into());
this.call_function(
instance,
- &func_args[..],
+ &[*func_arg],
Some(ret_place.into()),
StackPopCleanup::None { cleanup: true },
)?;
throw_unsup_format!("Miri supports pthread_join only with retval==NULL");
}
- let thread_id = this.read_scalar(thread)?.not_undef()?.to_machine_usize(this)?;
+ let thread_id = this.read_scalar(thread)?.to_machine_usize(this)?;
this.join_thread(thread_id.into())?;
Ok(0)
fn pthread_detach(&mut self, thread: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
- let thread_id = this.read_scalar(thread)?.not_undef()?.to_machine_usize(this)?;
+ let thread_id = this.read_scalar(thread)?.to_machine_usize(this)?;
this.detach_thread(thread_id.into())?;
Ok(0)
let this = self.eval_context_mut();
let thread_id = this.get_active_thread()?;
- this.write_scalar(Scalar::from_uint(thread_id.index() as u128, dest.layout.size), dest)
+ this.write_scalar(Scalar::from_uint(thread_id.to_u128(), dest.layout.size), dest)
}
fn prctl(
&mut self,
option: OpTy<'tcx, Tag>,
arg2: OpTy<'tcx, Tag>,
- arg3: OpTy<'tcx, Tag>,
- arg4: OpTy<'tcx, Tag>,
- arg5: OpTy<'tcx, Tag>,
+ _arg3: OpTy<'tcx, Tag>,
+ _arg4: OpTy<'tcx, Tag>,
+ _arg5: OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
- // prctl last 5 arguments are declared as variadic. Therefore, we need
- // to check their types manually.
- let c_long_size = this.libc_ty_layout("c_long")?.size.bytes();
- let check_arg = |arg: OpTy<'tcx, Tag>| -> InterpResult<'tcx> {
- match this.read_scalar(arg)?.not_undef()? {
- Scalar::Raw { size, .. } if u64::from(size) == c_long_size => Ok(()),
- _ => throw_ub_format!("an argument of unsupported type was passed to prctl"),
- }
- };
- check_arg(arg2)?;
- check_arg(arg3)?;
- check_arg(arg4)?;
- check_arg(arg5)?;
-
- let option = this.read_scalar(option)?.not_undef()?.to_i32()?;
+ let option = this.read_scalar(option)?.to_i32()?;
if option == this.eval_libc_i32("PR_SET_NAME")? {
let address = this.read_scalar(arg2)?.not_undef()?;
let name = this.memory.read_c_str(address)?.to_owned();
let name = this.get_active_thread_name()?.to_vec();
this.memory.write_bytes(address, name)?;
} else {
- throw_unsup_format!("Unsupported prctl option.");
+ throw_unsup_format!("unsupported prctl option {}", option);
}
Ok(0)
pub struct TlsEntry<'tcx> {
/// The data for this key. None is used to represent NULL.
/// (We normalize this early to avoid having to do a NULL-ptr-test each time we access the data.)
- /// Will eventually become a map from thread IDs to `Scalar`s, if we ever support more than one thread.
data: BTreeMap<ThreadId, Scalar<Tag>>,
dtor: Option<ty::Instance<'tcx>>,
}
) -> InterpResult<'tcx, Scalar<Tag>> {
match self.keys.get(&key) {
Some(TlsEntry { data, .. }) => {
- let value = data.get(&thread_id).cloned();
+ let value = data.get(&thread_id).copied();
trace!("TLS key {} for thread {:?} loaded: {:?}", key, thread_id, value);
Ok(value.unwrap_or_else(|| Scalar::null_ptr(cx).into()))
}
pub fn store_tls(
&mut self,
- key: TlsKey, thread_id: ThreadId, new_data: Option<Scalar<Tag>>) -> InterpResult<'tcx> {
+ key: TlsKey,
+ thread_id: ThreadId,
+ new_data: Option<Scalar<Tag>>
+ ) -> InterpResult<'tcx> {
match self.keys.get_mut(&key) {
Some(TlsEntry { data, .. }) => {
match new_data {