@@ -3,7 +3,8 @@ use std::ops::Deref;
33
44use libffi:: high:: call as ffi;
55use libffi:: low:: CodePtr ;
6- use rustc_abi:: { BackendRepr , HasDataLayout } ;
6+ use rustc_abi:: { BackendRepr , HasDataLayout , Size } ;
7+ use rustc_middle:: mir:: interpret:: Pointer ;
78use rustc_middle:: ty:: { self as ty, IntTy , UintTy } ;
89use rustc_span:: Symbol ;
910
@@ -75,6 +76,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
7576 unsafe { ffi:: call :: < ( ) > ( ptr, libffi_args. as_slice ( ) ) } ;
7677 return interp_ok ( ImmTy :: uninit ( dest. layout ) ) ;
7778 }
79+ ty:: RawPtr ( ..) => {
80+ let x = unsafe { ffi:: call :: < * const ( ) > ( ptr, libffi_args. as_slice ( ) ) } ;
81+ let ptr = Pointer :: new ( Provenance :: Wildcard , Size :: from_bytes ( x. addr ( ) ) ) ;
82+ Scalar :: from_pointer ( ptr, this)
83+ }
7884 _ => throw_unsup_format ! ( "unsupported return type for native call: {:?}" , link_name) ,
7985 } ;
8086 interp_ok ( ImmTy :: from_scalar ( scalar, dest. layout ) )
@@ -152,9 +158,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
152158 if !matches ! ( arg. layout. backend_repr, BackendRepr :: Scalar ( _) ) {
153159 throw_unsup_format ! ( "only scalar argument types are support for native calls" )
154160 }
155- libffi_args. push ( imm_to_carg ( this. read_immediate ( arg) ?, this) ?) ;
161+ let imm = this. read_immediate ( arg) ?;
162+ libffi_args. push ( imm_to_carg ( & imm, this) ?) ;
163+ // If we are passing a pointer, prepare the memory it points to.
164+ if matches ! ( arg. layout. ty. kind( ) , ty:: RawPtr ( ..) ) {
165+ let ptr = imm. to_scalar ( ) . to_pointer ( this) ?;
166+ let Some ( prov) = ptr. provenance else {
167+ // Pointer without provenance may not access any memory.
168+ continue ;
169+ } ;
170+ // We use `get_alloc_id` for its best-effort behaviour with Wildcard provenance.
171+ let Some ( alloc_id) = prov. get_alloc_id ( ) else {
172+ // Wildcard pointer, whatever it points to must be already exposed.
173+ continue ;
174+ } ;
175+ this. prepare_for_native_call ( alloc_id, prov) ?;
176+ }
156177 }
157178
179+ // FIXME: In the future, we should also call `prepare_for_native_call` on all previously
180+ // exposed allocations, since C may access any of them.
181+
158182 // Convert them to `libffi::high::Arg` type.
159183 let libffi_args = libffi_args
160184 . iter ( )
@@ -220,7 +244,7 @@ impl<'a> CArg {
220244
221245/// Extract the scalar value from the result of reading a scalar from the machine,
222246/// and convert it to a `CArg`.
223- fn imm_to_carg < ' tcx > ( v : ImmTy < ' tcx > , cx : & impl HasDataLayout ) -> InterpResult < ' tcx , CArg > {
247+ fn imm_to_carg < ' tcx > ( v : & ImmTy < ' tcx > , cx : & impl HasDataLayout ) -> InterpResult < ' tcx , CArg > {
224248 interp_ok ( match v. layout . ty . kind ( ) {
225249 // If the primitive provided can be converted to a type matching the type pattern
226250 // then create a `CArg` of this primitive value with the corresponding `CArg` constructor.
@@ -238,18 +262,10 @@ fn imm_to_carg<'tcx>(v: ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<'t
238262 ty:: Uint ( UintTy :: U64 ) => CArg :: UInt64 ( v. to_scalar ( ) . to_u64 ( ) ?) ,
239263 ty:: Uint ( UintTy :: Usize ) =>
240264 CArg :: USize ( v. to_scalar ( ) . to_target_usize ( cx) ?. try_into ( ) . unwrap ( ) ) ,
241- ty:: RawPtr ( _, mutability) => {
242- // Arbitrary mutable pointer accesses are not currently supported in Miri.
243- if mutability. is_mut ( ) {
244- throw_unsup_format ! (
245- "unsupported mutable pointer type for native call: {}" ,
246- v. layout. ty
247- ) ;
248- } else {
249- let s = v. to_scalar ( ) . to_pointer ( cx) ?. addr ( ) ;
250- // This relies on the `expose_provenance` in `addr_from_alloc_id`.
251- CArg :: RawPtr ( std:: ptr:: with_exposed_provenance_mut ( s. bytes_usize ( ) ) )
252- }
265+ ty:: RawPtr ( ..) => {
266+ let s = v. to_scalar ( ) . to_pointer ( cx) ?. addr ( ) ;
267+ // This relies on the `expose_provenance` in `addr_from_alloc_id`.
268+ CArg :: RawPtr ( std:: ptr:: with_exposed_provenance_mut ( s. bytes_usize ( ) ) )
253269 }
254270 _ => throw_unsup_format ! ( "unsupported argument type for native call: {}" , v. layout. ty) ,
255271 } )
0 commit comments