@@ -232,6 +232,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
232
232
}
233
233
}
234
234
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
+
235
248
/// Emulates calling a foreign item, failing if the item is not supported.
236
249
/// This function will handle `goto_block` if needed.
237
250
/// Returns Ok(None) if the foreign item was completely handled
@@ -427,13 +440,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
427
440
} ) ?;
428
441
this. write_scalar ( Scalar :: from_u64 ( alloc_id. 0 . get ( ) ) , dest) ?;
429
442
}
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) ?;
432
445
let id = this. read_scalar ( id) ?. to_u64 ( ) ?;
446
+ let show_unnamed = this. read_scalar ( show_unnamed) ?. to_bool ( ) ?;
433
447
if let Some ( id) = std:: num:: NonZeroU64 :: new ( id) {
434
- this. print_stacks ( AllocId ( id) ) ?;
448
+ this. print_borrow_state ( AllocId ( id) , show_unnamed ) ?;
435
449
}
436
450
}
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
+ }
437
464
"miri_static_root" => {
438
465
let [ ptr] = this. check_shim ( abi, Abi :: Rust , link_name, args) ?;
439
466
let ptr = this. read_pointer ( ptr) ?;
@@ -487,12 +514,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
487
514
// Writes some bytes to the interpreter's stdout/stderr. See the
488
515
// README for details.
489
516
"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) ?;
496
519
// Note: we're ignoring errors writing to host stdout/stderr.
497
520
let _ignore = match link_name. as_str ( ) {
498
521
"miri_write_to_stdout" => std:: io:: stdout ( ) . write_all ( msg) ,
0 commit comments