Use new write_bytes method
This commit is contained in:
commit
be415dbeda
10 changed files with 48 additions and 70 deletions
|
|
@ -12,6 +12,9 @@ branches:
|
|||
- auto
|
||||
- try
|
||||
|
||||
matrix:
|
||||
fast_finish: true # set this flag to immediately finish build once one of the jobs fails.
|
||||
|
||||
cache:
|
||||
- '%USERPROFILE%\.cargo'
|
||||
- '%USERPROFILE%\.rustup'
|
||||
|
|
|
|||
16
Cargo.lock
generated
16
Cargo.lock
generated
|
|
@ -215,6 +215,11 @@ dependencies = [
|
|||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.6.2"
|
||||
|
|
@ -294,6 +299,14 @@ dependencies = [
|
|||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.4"
|
||||
|
|
@ -343,6 +356,7 @@ dependencies = [
|
|||
"env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getrandom 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -828,6 +842,7 @@ dependencies = [
|
|||
"checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
|
||||
"checksum directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c"
|
||||
"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
|
||||
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
|
||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
||||
|
|
@ -837,6 +852,7 @@ dependencies = [
|
|||
"checksum getrandom 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fc344b02d3868feb131e8b5fe2b9b0a1cc42942679af493061fc13b853243872"
|
||||
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
|
||||
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
|
||||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ log = "0.4"
|
|||
shell-escape = "0.1.4"
|
||||
hex = "0.3.2"
|
||||
rand = "0.7"
|
||||
itertools = "0.8"
|
||||
|
||||
# A noop dependency that changes in the Rust repository, it's a bit of a hack.
|
||||
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
7979016aff545f7b41cc517031026020b340989d
|
||||
6576f4be5af31a5e61dfc0cf50b7130e6c6dfb35
|
||||
|
|
|
|||
|
|
@ -257,8 +257,9 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) {
|
|||
trace!("-------------------");
|
||||
trace!("Frame {}", i);
|
||||
trace!(" return: {:?}", frame.return_place.map(|p| *p));
|
||||
for (i, local) in frame.locals.iter().enumerate() {
|
||||
trace!(" local {}: {:?}", i, local.value);
|
||||
for (_i, _local) in frame.locals.iter().enumerate() {
|
||||
//trace!(" local {}: {:?}", i, local.value);
|
||||
//FIXME: enable this again when the LocalValue Debug impl is back
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
|
|||
use rustc::mir;
|
||||
use rustc::ty::{
|
||||
self,
|
||||
layout::{self, Align, LayoutOf, Size, TyLayout},
|
||||
layout::{self, LayoutOf, Size, TyLayout},
|
||||
};
|
||||
|
||||
use rand::RngCore;
|
||||
|
|
@ -95,13 +95,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
}
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Don't forget the bounds check.
|
||||
let ptr = this.memory.check_ptr_access(
|
||||
ptr,
|
||||
Size::from_bytes(len as u64),
|
||||
Align::from_bytes(1).unwrap()
|
||||
)?.expect("we already checked for size 0");
|
||||
|
||||
let mut data = vec![0; len];
|
||||
|
||||
if this.machine.communicate {
|
||||
|
|
@ -114,7 +107,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
rng.fill_bytes(&mut data);
|
||||
}
|
||||
|
||||
this.memory.get_mut(ptr.alloc_id)?.write_bytes(&*this.tcx, ptr, &data)
|
||||
this.memory.write_bytes(ptr, data.iter().copied())
|
||||
}
|
||||
|
||||
/// Visits the memory covered by `place`, sensitive to freezing: the 3rd parameter
|
||||
|
|
@ -420,27 +413,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
|
||||
/// Helper function to write an OsStr as a null-terminated sequence of bytes, which is what
|
||||
/// the Unix APIs usually handle.
|
||||
fn write_os_str_to_c_string(&mut self, os_str: &OsStr, ptr: Pointer<Tag>, size: u64) -> InterpResult<'tcx> {
|
||||
fn write_os_str_to_c_string(&mut self, os_str: &OsStr, scalar: Scalar<Tag>, size: u64) -> InterpResult<'tcx> {
|
||||
let bytes = os_str_to_bytes(os_str)?;
|
||||
let len = bytes.len();
|
||||
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
|
||||
// terminator to memory using the `ptr` pointer would cause an overflow.
|
||||
if size <= len as u64 {
|
||||
throw_unsup_format!("OsString of length {} is too large for destination buffer of size {}", len, size)
|
||||
if size <= bytes.len() as u64 {
|
||||
throw_unsup_format!("OsString of length {} is too large for destination buffer of size {}", bytes.len(), size)
|
||||
}
|
||||
let actual_len = (len as u64)
|
||||
.checked_add(1)
|
||||
.map(Size::from_bytes)
|
||||
.ok_or_else(|| err_unsup_format!("OsString of length {} is too large", len))?;
|
||||
let this = self.eval_context_mut();
|
||||
this.memory.check_ptr_access(ptr.into(), actual_len, Align::from_bytes(1).unwrap())?;
|
||||
let buffer = this.memory.get_mut(ptr.alloc_id)?.get_bytes_mut(&*this.tcx, ptr, actual_len)?;
|
||||
buffer[..len].copy_from_slice(bytes);
|
||||
// This is ok because the buffer was strictly larger than `bytes`, so after adding the
|
||||
// null terminator, the buffer size is larger or equal to `bytes.len()`, meaning that
|
||||
// `bytes` actually fit inside tbe buffer.
|
||||
buffer[len] = 0;
|
||||
Ok(())
|
||||
// FIXME: We should use `Iterator::chain` instead when rust-lang/rust#65704 lands.
|
||||
self.eval_context_mut().memory.write_bytes(scalar, [bytes, &[0]].concat())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,13 +123,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
|
||||
this.check_no_isolation("getcwd")?;
|
||||
|
||||
let buf = this.force_ptr(this.read_scalar(buf_op)?.not_undef()?)?;
|
||||
let buf = this.read_scalar(buf_op)?.not_undef()?;
|
||||
let size = this.read_scalar(size_op)?.to_usize(&*this.tcx)?;
|
||||
// If we cannot get the current directory, we return null
|
||||
match env::current_dir() {
|
||||
Ok(cwd) => {
|
||||
if this.write_os_str_to_c_string(&OsString::from(cwd), buf, size).is_ok() {
|
||||
return Ok(Scalar::Ptr(buf));
|
||||
return Ok(buf);
|
||||
}
|
||||
let erange = this.eval_libc("ERANGE")?;
|
||||
this.set_last_error(erange)?;
|
||||
|
|
|
|||
|
|
@ -52,9 +52,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
if zero_init {
|
||||
// We just allocated this, the access is definitely in-bounds.
|
||||
this.memory
|
||||
.get_mut(ptr.alloc_id)
|
||||
.unwrap()
|
||||
.write_repeat(&*this.tcx, ptr, 0, Size::from_bytes(size))
|
||||
.write_bytes(ptr.into(), itertools::repeat_n(0u8, size as usize))
|
||||
.unwrap();
|
||||
}
|
||||
Scalar::Ptr(ptr)
|
||||
|
|
@ -229,9 +227,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
);
|
||||
// We just allocated this, the access is definitely in-bounds.
|
||||
this.memory
|
||||
.get_mut(ptr.alloc_id)
|
||||
.unwrap()
|
||||
.write_repeat(tcx, ptr, 0, Size::from_bytes(size))
|
||||
.write_bytes(ptr.into(), itertools::repeat_n(0u8, size as usize))
|
||||
.unwrap();
|
||||
this.write_scalar(Scalar::Ptr(ptr), dest)?;
|
||||
}
|
||||
|
|
@ -841,25 +837,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
}
|
||||
"GetSystemInfo" => {
|
||||
let system_info = this.deref_operand(args[0])?;
|
||||
let system_info_ptr = this
|
||||
.check_mplace_access(system_info, None)?
|
||||
.expect("cannot be a ZST");
|
||||
// We rely on `deref_operand` doing bounds checks for us.
|
||||
// Initialize with `0`.
|
||||
this.memory
|
||||
.get_mut(system_info_ptr.alloc_id)?
|
||||
.write_repeat(tcx, system_info_ptr, 0, system_info.layout.size)?;
|
||||
.write_bytes(system_info.ptr, itertools::repeat_n(0, system_info.layout.size.bytes() as usize))?;
|
||||
// Set number of processors.
|
||||
let dword_size = Size::from_bytes(4);
|
||||
let offset = 2 * dword_size + 3 * tcx.pointer_size();
|
||||
this.memory
|
||||
.get_mut(system_info_ptr.alloc_id)?
|
||||
.write_scalar(
|
||||
tcx,
|
||||
system_info_ptr.offset(offset, tcx)?,
|
||||
Scalar::from_int(NUM_CPUS, dword_size).into(),
|
||||
dword_size,
|
||||
)?;
|
||||
let num_cpus = this.mplace_field(system_info, 6)?;
|
||||
this.write_scalar(
|
||||
Scalar::from_int(NUM_CPUS, dword_size),
|
||||
num_cpus.into(),
|
||||
)?;
|
||||
}
|
||||
|
||||
"TlsAlloc" => {
|
||||
|
|
|
|||
|
|
@ -356,11 +356,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
_ => {
|
||||
// Do it in memory
|
||||
let mplace = this.force_allocation(dest)?;
|
||||
mplace.meta.unwrap_none();
|
||||
// not a zst, must be valid pointer
|
||||
let ptr = mplace.ptr.to_ptr()?;
|
||||
// we know the return place is in-bounds
|
||||
this.memory.get_mut(ptr.alloc_id)?.write_repeat(tcx, ptr, 0, dest.layout.size)?;
|
||||
mplace.meta.unwrap_none(); // must be sized
|
||||
this.memory.write_bytes(mplace.ptr, itertools::repeat_n(0, dest.layout.size.bytes() as usize))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -565,16 +562,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
let ptr = this.read_scalar(args[0])?.not_undef()?;
|
||||
let count = this.read_scalar(args[2])?.to_usize(this)?;
|
||||
let byte_count = ty_layout.size * count;
|
||||
match this.memory.check_ptr_access(ptr, byte_count, ty_layout.align.abi)? {
|
||||
Some(ptr) => {
|
||||
this.memory
|
||||
.get_mut(ptr.alloc_id)?
|
||||
.write_repeat(tcx, ptr, val_byte, byte_count)?;
|
||||
}
|
||||
None => {
|
||||
// Size is 0, nothing to do.
|
||||
}
|
||||
}
|
||||
this.memory.write_bytes(ptr, itertools::repeat_n(val_byte, byte_count.bytes() as usize))?;
|
||||
}
|
||||
|
||||
name => throw_unsup_format!("unimplemented intrinsic: {}", name),
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
#![feature(untagged_unions)]
|
||||
#![allow(unions_with_drop_fields)]
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct Pair<T, U>(T, U);
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct Triple<T>(T, T, T);
|
||||
|
||||
#[repr(C)]
|
||||
union U<A, B> {
|
||||
union U<A: Copy, B: Copy> {
|
||||
a: Pair<A, A>,
|
||||
b: B,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
union W<A, B> {
|
||||
union W<A: Copy, B: Copy> {
|
||||
a: A,
|
||||
b: B,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue