@@ -10,8 +10,8 @@ use std::process;
1010
1111use either:: Either ;
1212use rand:: rngs:: StdRng ;
13- use rand:: SeedableRng ;
1413use rand:: Rng ;
14+ use rand:: SeedableRng ;
1515
1616use rustc_ast:: ast:: Mutability ;
1717use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
@@ -83,7 +83,8 @@ pub struct FrameExtra<'tcx> {
8383impl < ' tcx > std:: fmt:: Debug for FrameExtra < ' tcx > {
8484 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
8585 // Omitting `timing`, it does not support `Debug`.
86- let FrameExtra { borrow_tracker, catch_unwind, timing : _, is_user_relevant : _, salt : _ } = self ;
86+ let FrameExtra { borrow_tracker, catch_unwind, timing : _, is_user_relevant : _, salt : _ } =
87+ self ;
8788 f. debug_struct ( "FrameData" )
8889 . field ( "borrow_tracker" , borrow_tracker)
8990 . field ( "catch_unwind" , catch_unwind)
@@ -93,7 +94,8 @@ impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {
9394
9495impl VisitProvenance for FrameExtra < ' _ > {
9596 fn visit_provenance ( & self , visit : & mut VisitWith < ' _ > ) {
96- let FrameExtra { catch_unwind, borrow_tracker, timing : _, is_user_relevant : _, salt : _ } = self ;
97+ let FrameExtra { catch_unwind, borrow_tracker, timing : _, is_user_relevant : _, salt : _ } =
98+ self ;
9799
98100 catch_unwind. visit_provenance ( visit) ;
99101 borrow_tracker. visit_provenance ( visit) ;
@@ -710,7 +712,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
710712 Ok ( ( ) )
711713 }
712714
713- fn add_extern_static (
715+ pub ( crate ) fn add_extern_static (
714716 this : & mut MiriInterpCx < ' mir , ' tcx > ,
715717 name : & str ,
716718 ptr : Pointer < Option < Provenance > > ,
@@ -720,75 +722,6 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
720722 this. machine . extern_statics . try_insert ( Symbol :: intern ( name) , ptr) . unwrap ( ) ;
721723 }
722724
723- fn alloc_extern_static (
724- this : & mut MiriInterpCx < ' mir , ' tcx > ,
725- name : & str ,
726- val : ImmTy < ' tcx , Provenance > ,
727- ) -> InterpResult < ' tcx > {
728- let place = this. allocate ( val. layout , MiriMemoryKind :: ExternStatic . into ( ) ) ?;
729- this. write_immediate ( * val, & place) ?;
730- Self :: add_extern_static ( this, name, place. ptr ( ) ) ;
731- Ok ( ( ) )
732- }
733-
734- /// Sets up the "extern statics" for this machine.
735- fn init_extern_statics ( this : & mut MiriInterpCx < ' mir , ' tcx > ) -> InterpResult < ' tcx > {
736- // "__rust_no_alloc_shim_is_unstable"
737- let val = ImmTy :: from_int ( 0 , this. machine . layouts . u8 ) ;
738- Self :: alloc_extern_static ( this, "__rust_no_alloc_shim_is_unstable" , val) ?;
739-
740- match this. tcx . sess . target . os . as_ref ( ) {
741- "linux" => {
742- // "environ"
743- Self :: add_extern_static (
744- this,
745- "environ" ,
746- this. machine . env_vars . environ . as_ref ( ) . unwrap ( ) . ptr ( ) ,
747- ) ;
748- // A couple zero-initialized pointer-sized extern statics.
749- // Most of them are for weak symbols, which we all set to null (indicating that the
750- // symbol is not supported, and triggering fallback code which ends up calling a
751- // syscall that we do support).
752- for name in & [ "__cxa_thread_atexit_impl" , "getrandom" , "statx" , "__clock_gettime64" ]
753- {
754- let val = ImmTy :: from_int ( 0 , this. machine . layouts . usize ) ;
755- Self :: alloc_extern_static ( this, name, val) ?;
756- }
757- }
758- "freebsd" => {
759- // "environ"
760- Self :: add_extern_static (
761- this,
762- "environ" ,
763- this. machine . env_vars . environ . as_ref ( ) . unwrap ( ) . ptr ( ) ,
764- ) ;
765- }
766- "android" => {
767- // "signal" -- just needs a non-zero pointer value (function does not even get called),
768- // but we arrange for this to be callable anyway (it will then do nothing).
769- let layout = this. machine . layouts . const_raw_ptr ;
770- let ptr = this. fn_ptr ( FnVal :: Other ( DynSym :: from_str ( "signal" ) ) ) ;
771- let val = ImmTy :: from_scalar ( Scalar :: from_pointer ( ptr, this) , layout) ;
772- Self :: alloc_extern_static ( this, "signal" , val) ?;
773- // A couple zero-initialized pointer-sized extern statics.
774- // Most of them are for weak symbols, which we all set to null (indicating that the
775- // symbol is not supported, and triggering fallback code.)
776- for name in & [ "bsd_signal" ] {
777- let val = ImmTy :: from_int ( 0 , this. machine . layouts . usize ) ;
778- Self :: alloc_extern_static ( this, name, val) ?;
779- }
780- }
781- "windows" => {
782- // "_tls_used"
783- // This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
784- let val = ImmTy :: from_int ( 0 , this. machine . layouts . u8 ) ;
785- Self :: alloc_extern_static ( this, "_tls_used" , val) ?;
786- }
787- _ => { } // No "extern statics" supported on this target
788- }
789- Ok ( ( ) )
790- }
791-
792725 pub ( crate ) fn communicate ( & self ) -> bool {
793726 self . isolated_op == IsolatedOp :: Allow
794727 }
@@ -1009,7 +942,21 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
1009942 ret : Option < mir:: BasicBlock > ,
1010943 unwind : mir:: UnwindAction ,
1011944 ) -> InterpResult < ' tcx , Option < ( & ' mir mir:: Body < ' tcx > , ty:: Instance < ' tcx > ) > > {
1012- ecx. find_mir_or_eval_fn ( instance, abi, args, dest, ret, unwind)
945+ // For foreign items, try to see if we can emulate them.
946+ if ecx. tcx . is_foreign_item ( instance. def_id ( ) ) {
947+ // An external function call that does not have a MIR body. We either find MIR elsewhere
948+ // or emulate its effect.
949+ // This will be Ok(None) if we're emulating the intrinsic entirely within Miri (no need
950+ // to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
951+ // foreign function
952+ // Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
953+ let args = ecx. copy_fn_args ( args) ?; // FIXME: Should `InPlace` arguments be reset to uninit?
954+ let link_name = ecx. item_link_name ( instance. def_id ( ) ) ;
955+ return ecx. emulate_foreign_item ( link_name, abi, & args, dest, ret, unwind) ;
956+ }
957+
958+ // Otherwise, load the MIR.
959+ Ok ( Some ( ( ecx. load_mir ( instance. def , None ) ?, instance) ) )
1013960 }
1014961
1015962 #[ inline( always) ]
0 commit comments