@@ -10,8 +10,8 @@ use std::process;
10
10
11
11
use either:: Either ;
12
12
use rand:: rngs:: StdRng ;
13
- use rand:: SeedableRng ;
14
13
use rand:: Rng ;
14
+ use rand:: SeedableRng ;
15
15
16
16
use rustc_ast:: ast:: Mutability ;
17
17
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
@@ -83,7 +83,8 @@ pub struct FrameExtra<'tcx> {
83
83
impl < ' tcx > std:: fmt:: Debug for FrameExtra < ' tcx > {
84
84
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
85
85
// 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 ;
87
88
f. debug_struct ( "FrameData" )
88
89
. field ( "borrow_tracker" , borrow_tracker)
89
90
. field ( "catch_unwind" , catch_unwind)
@@ -93,7 +94,8 @@ impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {
93
94
94
95
impl VisitProvenance for FrameExtra < ' _ > {
95
96
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 ;
97
99
98
100
catch_unwind. visit_provenance ( visit) ;
99
101
borrow_tracker. visit_provenance ( visit) ;
@@ -710,7 +712,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
710
712
Ok ( ( ) )
711
713
}
712
714
713
- fn add_extern_static (
715
+ pub ( crate ) fn add_extern_static (
714
716
this : & mut MiriInterpCx < ' mir , ' tcx > ,
715
717
name : & str ,
716
718
ptr : Pointer < Option < Provenance > > ,
@@ -720,75 +722,6 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
720
722
this. machine . extern_statics . try_insert ( Symbol :: intern ( name) , ptr) . unwrap ( ) ;
721
723
}
722
724
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
-
792
725
pub ( crate ) fn communicate ( & self ) -> bool {
793
726
self . isolated_op == IsolatedOp :: Allow
794
727
}
@@ -1009,7 +942,21 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
1009
942
ret : Option < mir:: BasicBlock > ,
1010
943
unwind : mir:: UnwindAction ,
1011
944
) -> 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) ) )
1013
960
}
1014
961
1015
962
#[ inline( always) ]
0 commit comments