@@ -232,6 +232,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
232232 }
233233 }
234234
235+ /// Read bytes from a `(ptr, len)` argument
236+ fn read_byte_slice < ' i > ( & ' i self , bytes : & OpTy < ' tcx , Provenance > ) -> InterpResult < ' tcx , & ' i [ u8 ] >
237+ where
238+ ' mir : ' i ,
239+ {
240+ let this = self . eval_context_ref ( ) ;
241+ let ( ptr, len) = this. read_immediate ( bytes) ?. to_scalar_pair ( ) ;
242+ let ptr = ptr. to_pointer ( this) ?;
243+ let len = len. to_target_usize ( this) ?;
244+ let bytes = this. read_bytes_ptr_strip_provenance ( ptr, Size :: from_bytes ( len) ) ?;
245+ Ok ( bytes)
246+ }
247+
235248 /// Emulates calling a foreign item, failing if the item is not supported.
236249 /// This function will handle `goto_block` if needed.
237250 /// Returns Ok(None) if the foreign item was completely handled
@@ -427,13 +440,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
427440 } ) ?;
428441 this. write_scalar ( Scalar :: from_u64 ( alloc_id. 0 . get ( ) ) , dest) ?;
429442 }
430- "miri_print_borrow_stacks " => {
431- let [ id] = this. check_shim ( abi, Abi :: Rust , link_name, args) ?;
443+ "miri_print_borrow_state " => {
444+ let [ id, show_unnamed ] = this. check_shim ( abi, Abi :: Rust , link_name, args) ?;
432445 let id = this. read_scalar ( id) ?. to_u64 ( ) ?;
446+ let show_unnamed = this. read_scalar ( show_unnamed) ?. to_bool ( ) ?;
433447 if let Some ( id) = std:: num:: NonZeroU64 :: new ( id) {
434- this. print_stacks ( AllocId ( id) ) ?;
448+ this. print_borrow_state ( AllocId ( id) , show_unnamed ) ?;
435449 }
436450 }
451+ "miri_pointer_name" => {
452+ // This associates a name to a tag. Very useful for debugging, and also makes
453+ // tests more strict.
454+ let [ ptr, nth_parent, name] = this. check_shim ( abi, Abi :: Rust , link_name, args) ?;
455+ let ptr = this. read_pointer ( ptr) ?;
456+ let nth_parent = this. read_scalar ( nth_parent) ?. to_u8 ( ) ?;
457+ let name = this. read_byte_slice ( name) ?;
458+ // We must make `name` owned because we need to
459+ // end the shared borrow from `read_byte_slice` before we can
460+ // start the mutable borrow for `give_pointer_debug_name`.
461+ let name = String :: from_utf8_lossy ( name) . into_owned ( ) ;
462+ this. give_pointer_debug_name ( ptr, nth_parent, & name) ?;
463+ }
437464 "miri_static_root" => {
438465 let [ ptr] = this. check_shim ( abi, Abi :: Rust , link_name, args) ?;
439466 let ptr = this. read_pointer ( ptr) ?;
@@ -487,12 +514,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
487514 // Writes some bytes to the interpreter's stdout/stderr. See the
488515 // README for details.
489516 "miri_write_to_stdout" | "miri_write_to_stderr" => {
490- let [ bytes] = this. check_shim ( abi, Abi :: Rust , link_name, args) ?;
491- let ( ptr, len) = this. read_immediate ( bytes) ?. to_scalar_pair ( ) ;
492- let ptr = ptr. to_pointer ( this) ?;
493- let len = len. to_target_usize ( this) ?;
494- let msg = this. read_bytes_ptr_strip_provenance ( ptr, Size :: from_bytes ( len) ) ?;
495-
517+ let [ msg] = this. check_shim ( abi, Abi :: Rust , link_name, args) ?;
518+ let msg = this. read_byte_slice ( msg) ?;
496519 // Note: we're ignoring errors writing to host stdout/stderr.
497520 let _ignore = match link_name. as_str ( ) {
498521 "miri_write_to_stdout" => std:: io:: stdout ( ) . write_all ( msg) ,
0 commit comments