Skip to content

Commit 25d7e19

Browse files
authored
Merge pull request #487 from solson/rustup
Rustup
2 parents 53dc505 + 1a7fb7e commit 25d7e19

40 files changed

+802
-414
lines changed

rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
nightly-2018-10-14
1+
nightly-2018-10-22

src/fn_call.rs

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ pub trait EvalContextExt<'tcx, 'mir> {
1212
fn emulate_foreign_item(
1313
&mut self,
1414
def_id: DefId,
15-
args: &[OpTy<'tcx>],
16-
dest: PlaceTy<'tcx>,
15+
args: &[OpTy<'tcx, Borrow>],
16+
dest: PlaceTy<'tcx, Borrow>,
1717
ret: mir::BasicBlock,
1818
) -> EvalResult<'tcx>;
1919

@@ -24,28 +24,28 @@ pub trait EvalContextExt<'tcx, 'mir> {
2424
fn emulate_missing_fn(
2525
&mut self,
2626
path: String,
27-
args: &[OpTy<'tcx>],
28-
dest: Option<PlaceTy<'tcx>>,
27+
args: &[OpTy<'tcx, Borrow>],
28+
dest: Option<PlaceTy<'tcx, Borrow>>,
2929
ret: Option<mir::BasicBlock>,
3030
) -> EvalResult<'tcx>;
3131

3232
fn find_fn(
3333
&mut self,
3434
instance: ty::Instance<'tcx>,
35-
args: &[OpTy<'tcx>],
36-
dest: Option<PlaceTy<'tcx>>,
35+
args: &[OpTy<'tcx, Borrow>],
36+
dest: Option<PlaceTy<'tcx, Borrow>>,
3737
ret: Option<mir::BasicBlock>,
3838
) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>>;
3939

40-
fn write_null(&mut self, dest: PlaceTy<'tcx>) -> EvalResult<'tcx>;
40+
fn write_null(&mut self, dest: PlaceTy<'tcx, Borrow>) -> EvalResult<'tcx>;
4141
}
4242

43-
impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, 'mir, 'tcx, super::Evaluator<'tcx>> {
43+
impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for super::MiriEvalContext<'a, 'mir, 'tcx> {
4444
fn find_fn(
4545
&mut self,
4646
instance: ty::Instance<'tcx>,
47-
args: &[OpTy<'tcx>],
48-
dest: Option<PlaceTy<'tcx>>,
47+
args: &[OpTy<'tcx, Borrow>],
48+
dest: Option<PlaceTy<'tcx, Borrow>>,
4949
ret: Option<mir::BasicBlock>,
5050
) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>> {
5151
trace!("eval_fn_call: {:#?}, {:?}", instance, dest.map(|place| *place));
@@ -104,8 +104,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
104104
fn emulate_foreign_item(
105105
&mut self,
106106
def_id: DefId,
107-
args: &[OpTy<'tcx>],
108-
dest: PlaceTy<'tcx>,
107+
args: &[OpTy<'tcx, Borrow>],
108+
dest: PlaceTy<'tcx, Borrow>,
109109
ret: mir::BasicBlock,
110110
) -> EvalResult<'tcx> {
111111
let attrs = self.tcx.get_attrs(def_id);
@@ -114,6 +114,10 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
114114
None => self.tcx.item_name(def_id).as_str(),
115115
};
116116

117+
// All these functions take raw pointers, so if we access memory directly
118+
// (as opposed to through a place), we have to remember to erase any tag
119+
// that might still hang around!
120+
117121
match &link_name[..] {
118122
"malloc" => {
119123
let size = self.read_scalar(args[0])?.to_usize(&self)?;
@@ -127,10 +131,10 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
127131
}
128132

129133
"free" => {
130-
let ptr = self.read_scalar(args[0])?.not_undef()?;
134+
let ptr = self.read_scalar(args[0])?.not_undef()?.erase_tag(); // raw ptr operation, no tag
131135
if !ptr.is_null() {
132136
self.memory.deallocate(
133-
ptr.to_ptr()?,
137+
ptr.to_ptr()?.with_default_tag(),
134138
None,
135139
MiriMemoryKind::C.into(),
136140
)?;
@@ -167,7 +171,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
167171
self.write_scalar(Scalar::Ptr(ptr), dest)?;
168172
}
169173
"__rust_dealloc" => {
170-
let ptr = self.read_scalar(args[0])?.to_ptr()?;
174+
let ptr = self.read_scalar(args[0])?.to_ptr()?.erase_tag(); // raw ptr operation, no tag
171175
let old_size = self.read_scalar(args[1])?.to_usize(&self)?;
172176
let align = self.read_scalar(args[2])?.to_usize(&self)?;
173177
if old_size == 0 {
@@ -177,13 +181,13 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
177181
return err!(HeapAllocNonPowerOfTwoAlignment(align));
178182
}
179183
self.memory.deallocate(
180-
ptr,
184+
ptr.with_default_tag(),
181185
Some((Size::from_bytes(old_size), Align::from_bytes(align, align).unwrap())),
182186
MiriMemoryKind::Rust.into(),
183187
)?;
184188
}
185189
"__rust_realloc" => {
186-
let ptr = self.read_scalar(args[0])?.to_ptr()?;
190+
let ptr = self.read_scalar(args[0])?.to_ptr()?.erase_tag(); // raw ptr operation, no tag
187191
let old_size = self.read_scalar(args[1])?.to_usize(&self)?;
188192
let align = self.read_scalar(args[2])?.to_usize(&self)?;
189193
let new_size = self.read_scalar(args[3])?.to_usize(&self)?;
@@ -194,7 +198,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
194198
return err!(HeapAllocNonPowerOfTwoAlignment(align));
195199
}
196200
let new_ptr = self.memory.reallocate(
197-
ptr,
201+
ptr.with_default_tag(),
198202
Size::from_bytes(old_size),
199203
Align::from_bytes(align, align).unwrap(),
200204
Size::from_bytes(new_size),
@@ -226,8 +230,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
226230

227231
"dlsym" => {
228232
let _handle = self.read_scalar(args[0])?;
229-
let symbol = self.read_scalar(args[1])?.to_ptr()?;
230-
let symbol_name = self.memory.read_c_str(symbol)?;
233+
let symbol = self.read_scalar(args[1])?.to_ptr()?.erase_tag();
234+
let symbol_name = self.memory.read_c_str(symbol.with_default_tag())?;
231235
let err = format!("bad c unicode symbol: {:?}", symbol_name);
232236
let symbol_name = ::std::str::from_utf8(symbol_name).unwrap_or(&err);
233237
return err!(Unimplemented(format!(
@@ -280,13 +284,13 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
280284
return err!(MachineError("the evaluated program panicked".to_string())),
281285

282286
"memcmp" => {
283-
let left = self.read_scalar(args[0])?.not_undef()?;
284-
let right = self.read_scalar(args[1])?.not_undef()?;
287+
let left = self.read_scalar(args[0])?.not_undef()?.erase_tag(); // raw ptr operation
288+
let right = self.read_scalar(args[1])?.not_undef()?.erase_tag(); // raw ptr operation
285289
let n = Size::from_bytes(self.read_scalar(args[2])?.to_usize(&self)?);
286290

287291
let result = {
288-
let left_bytes = self.memory.read_bytes(left, n)?;
289-
let right_bytes = self.memory.read_bytes(right, n)?;
292+
let left_bytes = self.memory.read_bytes(left.with_default_tag(), n)?;
293+
let right_bytes = self.memory.read_bytes(right.with_default_tag(), n)?;
290294

291295
use std::cmp::Ordering::*;
292296
match left_bytes.cmp(right_bytes) {
@@ -303,12 +307,12 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
303307
}
304308

305309
"memrchr" => {
306-
let ptr = self.read_scalar(args[0])?.not_undef()?;
310+
let ptr = self.read_scalar(args[0])?.not_undef()?.erase_tag(); // raw ptr operation
311+
let ptr = ptr.with_default_tag();
307312
let val = self.read_scalar(args[1])?.to_bytes()? as u8;
308313
let num = self.read_scalar(args[2])?.to_usize(&self)?;
309-
if let Some(idx) = self.memory.read_bytes(ptr, Size::from_bytes(num))?.iter().rev().position(
310-
|&c| c == val,
311-
)
314+
if let Some(idx) = self.memory.read_bytes(ptr, Size::from_bytes(num))?
315+
.iter().rev().position(|&c| c == val)
312316
{
313317
let new_ptr = ptr.ptr_offset(Size::from_bytes(num - idx as u64 - 1), &self)?;
314318
self.write_scalar(new_ptr, dest)?;
@@ -318,7 +322,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
318322
}
319323

320324
"memchr" => {
321-
let ptr = self.read_scalar(args[0])?.not_undef()?;
325+
let ptr = self.read_scalar(args[0])?.not_undef()?.erase_tag(); // raw ptr operation
326+
let ptr = ptr.with_default_tag();
322327
let val = self.read_scalar(args[1])?.to_bytes()? as u8;
323328
let num = self.read_scalar(args[2])?.to_usize(&self)?;
324329
if let Some(idx) = self.memory.read_bytes(ptr, Size::from_bytes(num))?.iter().position(
@@ -334,8 +339,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
334339

335340
"getenv" => {
336341
let result = {
337-
let name_ptr = self.read_scalar(args[0])?.to_ptr()?;
338-
let name = self.memory.read_c_str(name_ptr)?;
342+
let name_ptr = self.read_scalar(args[0])?.to_ptr()?.erase_tag(); // raw ptr operation
343+
let name = self.memory.read_c_str(name_ptr.with_default_tag())?;
339344
match self.machine.env_vars.get(name) {
340345
Some(&var) => Scalar::Ptr(var),
341346
None => Scalar::ptr_null(*self.tcx),
@@ -347,9 +352,9 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
347352
"unsetenv" => {
348353
let mut success = None;
349354
{
350-
let name_ptr = self.read_scalar(args[0])?.not_undef()?;
355+
let name_ptr = self.read_scalar(args[0])?.not_undef()?.erase_tag(); // raw ptr operation
351356
if !name_ptr.is_null() {
352-
let name = self.memory.read_c_str(name_ptr.to_ptr()?)?;
357+
let name = self.memory.read_c_str(name_ptr.to_ptr()?.with_default_tag())?;
353358
if !name.is_empty() && !name.contains(&b'=') {
354359
success = Some(self.machine.env_vars.remove(name));
355360
}
@@ -368,11 +373,11 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
368373
"setenv" => {
369374
let mut new = None;
370375
{
371-
let name_ptr = self.read_scalar(args[0])?.not_undef()?;
372-
let value_ptr = self.read_scalar(args[1])?.to_ptr()?;
373-
let value = self.memory.read_c_str(value_ptr)?;
376+
let name_ptr = self.read_scalar(args[0])?.not_undef()?.erase_tag(); // raw ptr operation
377+
let value_ptr = self.read_scalar(args[1])?.to_ptr()?.erase_tag(); // raw ptr operation
378+
let value = self.memory.read_c_str(value_ptr.with_default_tag())?;
374379
if !name_ptr.is_null() {
375-
let name = self.memory.read_c_str(name_ptr.to_ptr()?)?;
380+
let name = self.memory.read_c_str(name_ptr.to_ptr()?.with_default_tag())?;
376381
if !name.is_empty() && !name.contains(&b'=') {
377382
new = Some((name.to_owned(), value.to_owned()));
378383
}
@@ -403,14 +408,14 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
403408

404409
"write" => {
405410
let fd = self.read_scalar(args[0])?.to_bytes()?;
406-
let buf = self.read_scalar(args[1])?.not_undef()?;
411+
let buf = self.read_scalar(args[1])?.not_undef()?.erase_tag();
407412
let n = self.read_scalar(args[2])?.to_bytes()? as u64;
408413
trace!("Called write({:?}, {:?}, {:?})", fd, buf, n);
409414
let result = if fd == 1 || fd == 2 {
410415
// stdout/stderr
411416
use std::io::{self, Write};
412417

413-
let buf_cont = self.memory.read_bytes(buf, Size::from_bytes(n))?;
418+
let buf_cont = self.memory.read_bytes(buf.with_default_tag(), Size::from_bytes(n))?;
414419
let res = if fd == 1 {
415420
io::stdout().write(buf_cont)
416421
} else {
@@ -431,8 +436,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
431436
}
432437

433438
"strlen" => {
434-
let ptr = self.read_scalar(args[0])?.to_ptr()?;
435-
let n = self.memory.read_c_str(ptr)?.len();
439+
let ptr = self.read_scalar(args[0])?.to_ptr()?.erase_tag();
440+
let n = self.memory.read_c_str(ptr.with_default_tag())?.len();
436441
self.write_scalar(Scalar::from_uint(n as u64, dest.layout.size), dest)?;
437442
}
438443

@@ -478,7 +483,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
478483

479484
// Hook pthread calls that go to the thread-local storage memory subsystem
480485
"pthread_key_create" => {
481-
let key_ptr = self.read_scalar(args[0])?.to_ptr()?;
486+
let key_ptr = self.read_scalar(args[0])?.to_ptr()?.erase_tag(); // raw ptr operation
482487

483488
// Extract the function type out of the signature (that seems easier than constructing it ourselves...)
484489
let dtor = match self.read_scalar(args[1])?.not_undef()? {
@@ -501,7 +506,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
501506
return err!(OutOfTls);
502507
}
503508
self.memory.write_scalar(
504-
key_ptr,
509+
key_ptr.with_default_tag(),
505510
key_layout.align,
506511
Scalar::from_uint(key, key_layout.size).into(),
507512
key_layout.size,
@@ -637,8 +642,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
637642
fn emulate_missing_fn(
638643
&mut self,
639644
path: String,
640-
_args: &[OpTy<'tcx>],
641-
dest: Option<PlaceTy<'tcx>>,
645+
_args: &[OpTy<'tcx, Borrow>],
646+
dest: Option<PlaceTy<'tcx, Borrow>>,
642647
ret: Option<mir::BasicBlock>,
643648
) -> EvalResult<'tcx> {
644649
// In some cases in non-MIR libstd-mode, not having a destination is legit. Handle these early.
@@ -686,7 +691,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
686691
Ok(())
687692
}
688693

689-
fn write_null(&mut self, dest: PlaceTy<'tcx>) -> EvalResult<'tcx> {
694+
fn write_null(&mut self, dest: PlaceTy<'tcx, Borrow>) -> EvalResult<'tcx> {
690695
self.write_scalar(Scalar::from_int(0, dest.layout.size), dest)
691696
}
692697
}

src/helpers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub trait ScalarExt {
1212
fn to_bytes(self) -> EvalResult<'static, u128>;
1313
}
1414

15-
impl ScalarExt for Scalar {
15+
impl<Tag> ScalarExt for Scalar<Tag> {
1616
fn to_bytes(self) -> EvalResult<'static, u128> {
1717
match self {
1818
Scalar::Bits { bits, size } => {
@@ -24,7 +24,7 @@ impl ScalarExt for Scalar {
2424
}
2525
}
2626

27-
impl ScalarExt for ScalarMaybeUndef {
27+
impl<Tag> ScalarExt for ScalarMaybeUndef<Tag> {
2828
fn to_bytes(self) -> EvalResult<'static, u128> {
2929
self.not_undef()?.to_bytes()
3030
}

src/intrinsic.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,38 @@ use rustc::ty::layout::{self, LayoutOf, Size};
33
use rustc::ty;
44

55
use rustc::mir::interpret::{EvalResult, PointerArithmetic};
6-
use rustc_mir::interpret::{EvalContext, PlaceTy, OpTy};
76

87
use super::{
9-
Value, Scalar, ScalarMaybeUndef,
8+
PlaceTy, OpTy, Value, Scalar, ScalarMaybeUndef, Borrow,
109
ScalarExt, OperatorEvalContextExt
1110
};
1211

1312
pub trait EvalContextExt<'tcx> {
1413
fn call_intrinsic(
1514
&mut self,
1615
instance: ty::Instance<'tcx>,
17-
args: &[OpTy<'tcx>],
18-
dest: PlaceTy<'tcx>,
16+
args: &[OpTy<'tcx, Borrow>],
17+
dest: PlaceTy<'tcx, Borrow>,
1918
) -> EvalResult<'tcx>;
2019
}
2120

22-
impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super::Evaluator<'tcx>> {
21+
impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, 'tcx> {
2322
fn call_intrinsic(
2423
&mut self,
2524
instance: ty::Instance<'tcx>,
26-
args: &[OpTy<'tcx>],
27-
dest: PlaceTy<'tcx>,
25+
args: &[OpTy<'tcx, Borrow>],
26+
dest: PlaceTy<'tcx, Borrow>,
2827
) -> EvalResult<'tcx> {
2928
if self.emulate_intrinsic(instance, args, dest)? {
3029
return Ok(());
3130
}
3231

3332
let substs = instance.substs;
3433

34+
// All these intrinsics take raw pointers, so if we access memory directly
35+
// (as opposed to through a place), we have to remember to erase any tag
36+
// that might still hang around!
37+
3538
let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..];
3639
match intrinsic_name {
3740
"arith_offset" => {
@@ -147,12 +150,13 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
147150
let elem_size = elem_layout.size.bytes();
148151
let count = self.read_scalar(args[2])?.to_usize(&self)?;
149152
let elem_align = elem_layout.align;
150-
let src = self.read_scalar(args[0])?.not_undef()?;
151-
let dest = self.read_scalar(args[1])?.not_undef()?;
153+
// erase tags: this is a raw ptr operation
154+
let src = self.read_scalar(args[0])?.not_undef()?.erase_tag();
155+
let dest = self.read_scalar(args[1])?.not_undef()?.erase_tag();
152156
self.memory.copy(
153-
src,
157+
src.with_default_tag(),
154158
elem_align,
155-
dest,
159+
dest.with_default_tag(),
156160
elem_align,
157161
Size::from_bytes(count * elem_size),
158162
intrinsic_name.ends_with("_nonoverlapping"),
@@ -429,7 +433,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
429433
let ty = substs.type_at(0);
430434
let ty_layout = self.layout_of(ty)?;
431435
let val_byte = self.read_scalar(args[1])?.to_u8()?;
432-
let ptr = self.read_scalar(args[0])?.not_undef()?;
436+
let ptr = self.read_scalar(args[0])?.not_undef()?.erase_tag().with_default_tag();
433437
let count = self.read_scalar(args[2])?.to_usize(&self)?;
434438
self.memory.check_align(ptr, ty_layout.align)?;
435439
self.memory.write_repeat(ptr, val_byte, ty_layout.size * count)?;

0 commit comments

Comments
 (0)