@@ -12,8 +12,8 @@ pub trait EvalContextExt<'tcx, 'mir> {
12
12
fn emulate_foreign_item (
13
13
& mut self ,
14
14
def_id : DefId ,
15
- args : & [ OpTy < ' tcx > ] ,
16
- dest : PlaceTy < ' tcx > ,
15
+ args : & [ OpTy < ' tcx , Borrow > ] ,
16
+ dest : PlaceTy < ' tcx , Borrow > ,
17
17
ret : mir:: BasicBlock ,
18
18
) -> EvalResult < ' tcx > ;
19
19
@@ -24,28 +24,28 @@ pub trait EvalContextExt<'tcx, 'mir> {
24
24
fn emulate_missing_fn (
25
25
& mut self ,
26
26
path : String ,
27
- args : & [ OpTy < ' tcx > ] ,
28
- dest : Option < PlaceTy < ' tcx > > ,
27
+ args : & [ OpTy < ' tcx , Borrow > ] ,
28
+ dest : Option < PlaceTy < ' tcx , Borrow > > ,
29
29
ret : Option < mir:: BasicBlock > ,
30
30
) -> EvalResult < ' tcx > ;
31
31
32
32
fn find_fn (
33
33
& mut self ,
34
34
instance : ty:: Instance < ' tcx > ,
35
- args : & [ OpTy < ' tcx > ] ,
36
- dest : Option < PlaceTy < ' tcx > > ,
35
+ args : & [ OpTy < ' tcx , Borrow > ] ,
36
+ dest : Option < PlaceTy < ' tcx , Borrow > > ,
37
37
ret : Option < mir:: BasicBlock > ,
38
38
) -> EvalResult < ' tcx , Option < & ' mir mir:: Mir < ' tcx > > > ;
39
39
40
- fn write_null ( & mut self , dest : PlaceTy < ' tcx > ) -> EvalResult < ' tcx > ;
40
+ fn write_null ( & mut self , dest : PlaceTy < ' tcx , Borrow > ) -> EvalResult < ' tcx > ;
41
41
}
42
42
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 > {
44
44
fn find_fn (
45
45
& mut self ,
46
46
instance : ty:: Instance < ' tcx > ,
47
- args : & [ OpTy < ' tcx > ] ,
48
- dest : Option < PlaceTy < ' tcx > > ,
47
+ args : & [ OpTy < ' tcx , Borrow > ] ,
48
+ dest : Option < PlaceTy < ' tcx , Borrow > > ,
49
49
ret : Option < mir:: BasicBlock > ,
50
50
) -> EvalResult < ' tcx , Option < & ' mir mir:: Mir < ' tcx > > > {
51
51
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, '
104
104
fn emulate_foreign_item (
105
105
& mut self ,
106
106
def_id : DefId ,
107
- args : & [ OpTy < ' tcx > ] ,
108
- dest : PlaceTy < ' tcx > ,
107
+ args : & [ OpTy < ' tcx , Borrow > ] ,
108
+ dest : PlaceTy < ' tcx , Borrow > ,
109
109
ret : mir:: BasicBlock ,
110
110
) -> EvalResult < ' tcx > {
111
111
let attrs = self . tcx . get_attrs ( def_id) ;
@@ -114,6 +114,10 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
114
114
None => self . tcx . item_name ( def_id) . as_str ( ) ,
115
115
} ;
116
116
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
+
117
121
match & link_name[ ..] {
118
122
"malloc" => {
119
123
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, '
127
131
}
128
132
129
133
"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
131
135
if !ptr. is_null ( ) {
132
136
self . memory . deallocate (
133
- ptr. to_ptr ( ) ?,
137
+ ptr. to_ptr ( ) ?. with_default_tag ( ) ,
134
138
None ,
135
139
MiriMemoryKind :: C . into ( ) ,
136
140
) ?;
@@ -167,7 +171,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
167
171
self . write_scalar ( Scalar :: Ptr ( ptr) , dest) ?;
168
172
}
169
173
"__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
171
175
let old_size = self . read_scalar ( args[ 1 ] ) ?. to_usize ( & self ) ?;
172
176
let align = self . read_scalar ( args[ 2 ] ) ?. to_usize ( & self ) ?;
173
177
if old_size == 0 {
@@ -177,13 +181,13 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
177
181
return err ! ( HeapAllocNonPowerOfTwoAlignment ( align) ) ;
178
182
}
179
183
self . memory . deallocate (
180
- ptr,
184
+ ptr. with_default_tag ( ) ,
181
185
Some ( ( Size :: from_bytes ( old_size) , Align :: from_bytes ( align, align) . unwrap ( ) ) ) ,
182
186
MiriMemoryKind :: Rust . into ( ) ,
183
187
) ?;
184
188
}
185
189
"__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
187
191
let old_size = self . read_scalar ( args[ 1 ] ) ?. to_usize ( & self ) ?;
188
192
let align = self . read_scalar ( args[ 2 ] ) ?. to_usize ( & self ) ?;
189
193
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, '
194
198
return err ! ( HeapAllocNonPowerOfTwoAlignment ( align) ) ;
195
199
}
196
200
let new_ptr = self . memory . reallocate (
197
- ptr,
201
+ ptr. with_default_tag ( ) ,
198
202
Size :: from_bytes ( old_size) ,
199
203
Align :: from_bytes ( align, align) . unwrap ( ) ,
200
204
Size :: from_bytes ( new_size) ,
@@ -226,8 +230,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
226
230
227
231
"dlsym" => {
228
232
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 ( ) ) ?;
231
235
let err = format ! ( "bad c unicode symbol: {:?}" , symbol_name) ;
232
236
let symbol_name = :: std:: str:: from_utf8 ( symbol_name) . unwrap_or ( & err) ;
233
237
return err ! ( Unimplemented ( format!(
@@ -280,13 +284,13 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
280
284
return err ! ( MachineError ( "the evaluated program panicked" . to_string( ) ) ) ,
281
285
282
286
"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
285
289
let n = Size :: from_bytes ( self . read_scalar ( args[ 2 ] ) ?. to_usize ( & self ) ?) ;
286
290
287
291
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) ?;
290
294
291
295
use std:: cmp:: Ordering :: * ;
292
296
match left_bytes. cmp ( right_bytes) {
@@ -303,12 +307,12 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
303
307
}
304
308
305
309
"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 ( ) ;
307
312
let val = self . read_scalar ( args[ 1 ] ) ?. to_bytes ( ) ? as u8 ;
308
313
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)
312
316
{
313
317
let new_ptr = ptr. ptr_offset ( Size :: from_bytes ( num - idx as u64 - 1 ) , & self ) ?;
314
318
self . write_scalar ( new_ptr, dest) ?;
@@ -318,7 +322,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
318
322
}
319
323
320
324
"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 ( ) ;
322
327
let val = self . read_scalar ( args[ 1 ] ) ?. to_bytes ( ) ? as u8 ;
323
328
let num = self . read_scalar ( args[ 2 ] ) ?. to_usize ( & self ) ?;
324
329
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, '
334
339
335
340
"getenv" => {
336
341
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 ( ) ) ?;
339
344
match self . machine . env_vars . get ( name) {
340
345
Some ( & var) => Scalar :: Ptr ( var) ,
341
346
None => Scalar :: ptr_null ( * self . tcx ) ,
@@ -347,9 +352,9 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
347
352
"unsetenv" => {
348
353
let mut success = None ;
349
354
{
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
351
356
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 ( ) ) ?;
353
358
if !name. is_empty ( ) && !name. contains ( & b'=' ) {
354
359
success = Some ( self . machine . env_vars . remove ( name) ) ;
355
360
}
@@ -368,11 +373,11 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
368
373
"setenv" => {
369
374
let mut new = None ;
370
375
{
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 ( ) ) ?;
374
379
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 ( ) ) ?;
376
381
if !name. is_empty ( ) && !name. contains ( & b'=' ) {
377
382
new = Some ( ( name. to_owned ( ) , value. to_owned ( ) ) ) ;
378
383
}
@@ -403,14 +408,14 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
403
408
404
409
"write" => {
405
410
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 ( ) ;
407
412
let n = self . read_scalar ( args[ 2 ] ) ?. to_bytes ( ) ? as u64 ;
408
413
trace ! ( "Called write({:?}, {:?}, {:?})" , fd, buf, n) ;
409
414
let result = if fd == 1 || fd == 2 {
410
415
// stdout/stderr
411
416
use std:: io:: { self , Write } ;
412
417
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) ) ?;
414
419
let res = if fd == 1 {
415
420
io:: stdout ( ) . write ( buf_cont)
416
421
} else {
@@ -431,8 +436,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
431
436
}
432
437
433
438
"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 ( ) ;
436
441
self . write_scalar ( Scalar :: from_uint ( n as u64 , dest. layout . size ) , dest) ?;
437
442
}
438
443
@@ -478,7 +483,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
478
483
479
484
// Hook pthread calls that go to the thread-local storage memory subsystem
480
485
"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
482
487
483
488
// Extract the function type out of the signature (that seems easier than constructing it ourselves...)
484
489
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, '
501
506
return err ! ( OutOfTls ) ;
502
507
}
503
508
self . memory . write_scalar (
504
- key_ptr,
509
+ key_ptr. with_default_tag ( ) ,
505
510
key_layout. align ,
506
511
Scalar :: from_uint ( key, key_layout. size ) . into ( ) ,
507
512
key_layout. size ,
@@ -637,8 +642,8 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for EvalContext<'a, '
637
642
fn emulate_missing_fn (
638
643
& mut self ,
639
644
path : String ,
640
- _args : & [ OpTy < ' tcx > ] ,
641
- dest : Option < PlaceTy < ' tcx > > ,
645
+ _args : & [ OpTy < ' tcx , Borrow > ] ,
646
+ dest : Option < PlaceTy < ' tcx , Borrow > > ,
642
647
ret : Option < mir:: BasicBlock > ,
643
648
) -> EvalResult < ' tcx > {
644
649
// 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, '
686
691
Ok ( ( ) )
687
692
}
688
693
689
- fn write_null ( & mut self , dest : PlaceTy < ' tcx > ) -> EvalResult < ' tcx > {
694
+ fn write_null ( & mut self , dest : PlaceTy < ' tcx , Borrow > ) -> EvalResult < ' tcx > {
690
695
self . write_scalar ( Scalar :: from_int ( 0 , dest. layout . size ) , dest)
691
696
}
692
697
}
0 commit comments