@@ -691,7 +691,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
691
691
Ok ( ( ) )
692
692
}
693
693
694
- fn add_extern_static (
694
+ pub ( crate ) fn add_extern_static (
695
695
this : & mut MiriInterpCx < ' mir , ' tcx > ,
696
696
name : & str ,
697
697
ptr : Pointer < Option < Provenance > > ,
@@ -701,75 +701,6 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
701
701
this. machine . extern_statics . try_insert ( Symbol :: intern ( name) , ptr) . unwrap ( ) ;
702
702
}
703
703
704
- fn alloc_extern_static (
705
- this : & mut MiriInterpCx < ' mir , ' tcx > ,
706
- name : & str ,
707
- val : ImmTy < ' tcx , Provenance > ,
708
- ) -> InterpResult < ' tcx > {
709
- let place = this. allocate ( val. layout , MiriMemoryKind :: ExternStatic . into ( ) ) ?;
710
- this. write_immediate ( * val, & place) ?;
711
- Self :: add_extern_static ( this, name, place. ptr ( ) ) ;
712
- Ok ( ( ) )
713
- }
714
-
715
- /// Sets up the "extern statics" for this machine.
716
- fn init_extern_statics ( this : & mut MiriInterpCx < ' mir , ' tcx > ) -> InterpResult < ' tcx > {
717
- // "__rust_no_alloc_shim_is_unstable"
718
- let val = ImmTy :: from_int ( 0 , this. machine . layouts . u8 ) ;
719
- Self :: alloc_extern_static ( this, "__rust_no_alloc_shim_is_unstable" , val) ?;
720
-
721
- match this. tcx . sess . target . os . as_ref ( ) {
722
- "linux" => {
723
- // "environ"
724
- Self :: add_extern_static (
725
- this,
726
- "environ" ,
727
- this. machine . env_vars . environ . as_ref ( ) . unwrap ( ) . ptr ( ) ,
728
- ) ;
729
- // A couple zero-initialized pointer-sized extern statics.
730
- // Most of them are for weak symbols, which we all set to null (indicating that the
731
- // symbol is not supported, and triggering fallback code which ends up calling a
732
- // syscall that we do support).
733
- for name in & [ "__cxa_thread_atexit_impl" , "getrandom" , "statx" , "__clock_gettime64" ]
734
- {
735
- let val = ImmTy :: from_int ( 0 , this. machine . layouts . usize ) ;
736
- Self :: alloc_extern_static ( this, name, val) ?;
737
- }
738
- }
739
- "freebsd" => {
740
- // "environ"
741
- Self :: add_extern_static (
742
- this,
743
- "environ" ,
744
- this. machine . env_vars . environ . as_ref ( ) . unwrap ( ) . ptr ( ) ,
745
- ) ;
746
- }
747
- "android" => {
748
- // "signal" -- just needs a non-zero pointer value (function does not even get called),
749
- // but we arrange for this to be callable anyway (it will then do nothing).
750
- let layout = this. machine . layouts . const_raw_ptr ;
751
- let ptr = this. fn_ptr ( FnVal :: Other ( DynSym :: from_str ( "signal" ) ) ) ;
752
- let val = ImmTy :: from_scalar ( Scalar :: from_pointer ( ptr, this) , layout) ;
753
- Self :: alloc_extern_static ( this, "signal" , val) ?;
754
- // A couple zero-initialized pointer-sized extern statics.
755
- // Most of them are for weak symbols, which we all set to null (indicating that the
756
- // symbol is not supported, and triggering fallback code.)
757
- for name in & [ "bsd_signal" ] {
758
- let val = ImmTy :: from_int ( 0 , this. machine . layouts . usize ) ;
759
- Self :: alloc_extern_static ( this, name, val) ?;
760
- }
761
- }
762
- "windows" => {
763
- // "_tls_used"
764
- // This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
765
- let val = ImmTy :: from_int ( 0 , this. machine . layouts . u8 ) ;
766
- Self :: alloc_extern_static ( this, "_tls_used" , val) ?;
767
- }
768
- _ => { } // No "extern statics" supported on this target
769
- }
770
- Ok ( ( ) )
771
- }
772
-
773
704
pub ( crate ) fn communicate ( & self ) -> bool {
774
705
self . isolated_op == IsolatedOp :: Allow
775
706
}
@@ -989,7 +920,21 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
989
920
ret : Option < mir:: BasicBlock > ,
990
921
unwind : mir:: UnwindAction ,
991
922
) -> InterpResult < ' tcx , Option < ( & ' mir mir:: Body < ' tcx > , ty:: Instance < ' tcx > ) > > {
992
- ecx. find_mir_or_eval_fn ( instance, abi, args, dest, ret, unwind)
923
+ // For foreign items, try to see if we can emulate them.
924
+ if ecx. tcx . is_foreign_item ( instance. def_id ( ) ) {
925
+ // An external function call that does not have a MIR body. We either find MIR elsewhere
926
+ // or emulate its effect.
927
+ // This will be Ok(None) if we're emulating the intrinsic entirely within Miri (no need
928
+ // to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
929
+ // foreign function
930
+ // Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
931
+ let args = ecx. copy_fn_args ( args) ?; // FIXME: Should `InPlace` arguments be reset to uninit?
932
+ let link_name = ecx. item_link_name ( instance. def_id ( ) ) ;
933
+ return ecx. emulate_foreign_item ( link_name, abi, & args, dest, ret, unwind) ;
934
+ }
935
+
936
+ // Otherwise, load the MIR.
937
+ Ok ( Some ( ( ecx. load_mir ( instance. def , None ) ?, instance) ) )
993
938
}
994
939
995
940
#[ inline( always) ]
0 commit comments