Skip to content

Commit

Permalink
Split write_c_ints into less specific helper functions
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdrz committed Oct 11, 2019
1 parent 8ffe5de commit 9813851
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 28 deletions.
39 changes: 15 additions & 24 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
use rustc::mir;
use rustc::ty::{
self,
layout::{self, Align, LayoutOf, Size},
layout::{self, Align, LayoutOf, Size, TyLayout},
};

use rand::RngCore;
Expand Down Expand Up @@ -295,47 +295,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
}

fn write_c_ints(
// Writes several `ImmTy`s contiguosly into memory. This is useful when you have to pack
// different values into an struct.
fn write_immediates(
&mut self,
ptr: &Pointer<Tag>,
bits: &[i128],
ty_names: &[&str],
imms: &[ImmTy<'tcx, Tag>],
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

let tcx = &{ this.tcx.tcx };

let mut sizes = Vec::new();

for name in ty_names {
let ty = this.resolve_path(&["libc", name])?.ty(*tcx);
sizes.push(this.layout_of(ty)?.size);
}

let allocation = this.memory_mut().get_mut(ptr.alloc_id)?;
let mut offset = Size::from_bytes(0);

for (&value, size) in bits.iter().zip(sizes) {
// If `value` does not fit in `size` bits, we error instead of letting
// `Scalar::from_int` panic.
let truncated = truncate(value as u128, size);
if sign_extend(truncated, size) as i128 != value {
throw_unsup_format!(
"Signed value {:#x} does not fit in {} bits",
value,
size.bits()
)
}

for imm in imms {
let size = imm.layout.size;
allocation.write_scalar(
tcx,
ptr.offset(offset, tcx)?,
Scalar::from_int(value, size).into(),
imm.to_scalar()?.into(),
size,
)?;
offset += size;
}

Ok(())
}

fn libc_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyLayout<'tcx>> {
let this = self.eval_context_mut();
let tcx = &{ this.tcx.tcx };
let ty = this.resolve_path(&["libc", name])?.ty(*tcx);
this.layout_of(ty)
}
}
40 changes: 36 additions & 4 deletions src/shims/time.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use std::time::{Duration, SystemTime};

use rustc::ty::layout::TyLayout;

use crate::stacked_borrows::Tag;
use crate::*;

use std::time::{Duration, SystemTime};

// Returns the time elapsed between now and the unix epoch as a `Duration` and the sign of the time
// interval
fn get_time() -> (Duration, i128) {
let mut sign = 1;
let duration = SystemTime::now()
Expand All @@ -14,6 +18,24 @@ fn get_time() -> (Duration, i128) {
(duration, sign)
}

fn int_to_immty_checked<'tcx>(
int: i128,
layout: TyLayout<'tcx>,
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
// If `int` does not fit in `size` bits, we error instead of letting
// `ImmTy::from_int` panic.
let size = layout.size;
let truncated = truncate(int as u128, size);
if sign_extend(truncated, size) as i128 != int {
throw_unsup_format!(
"Signed value {:#x} does not fit in {} bits",
int,
size.bits()
)
}
Ok(ImmTy::from_int(int, layout))
}

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
// Foreign function used by linux
Expand Down Expand Up @@ -45,7 +67,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
tv_nsec *= sign;
}

this.write_c_ints(&tp, &[tv_sec, tv_nsec], &["time_t", "c_long"])?;
let imms = [
int_to_immty_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
int_to_immty_checked(tv_nsec, this.libc_ty_layout("c_long")?)?,
];

this.write_immediates(&tp, &imms)?;

Ok(0)
}
Expand Down Expand Up @@ -78,7 +105,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
tv_usec *= sign;
}

this.write_c_ints(&tv, &[tv_sec, tv_usec], &["time_t", "suseconds_t"])?;
let imms = [
int_to_immty_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
int_to_immty_checked(tv_usec, this.libc_ty_layout("suseconds_t")?)?,
];

this.write_immediates(&tv, &imms)?;

Ok(0)
}
Expand Down

0 comments on commit 9813851

Please sign in to comment.