@@ -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}
0 commit comments