@@ -3,8 +3,11 @@ use std::ops::Deref;
33
44use libffi:: high:: call as ffi;
55use libffi:: low:: CodePtr ;
6- use rustc_abi:: { BackendRepr , HasDataLayout } ;
7- use rustc_middle:: ty:: { self as ty, IntTy , UintTy } ;
6+ use rustc_abi:: { BackendRepr , HasDataLayout , Size } ;
7+ use rustc_middle:: {
8+ mir:: interpret:: Pointer ,
9+ ty:: { self as ty, IntTy , UintTy } ,
10+ } ;
811use rustc_span:: Symbol ;
912
1013use crate :: * ;
@@ -75,6 +78,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
7578 unsafe { ffi:: call :: < ( ) > ( ptr, libffi_args. as_slice ( ) ) } ;
7679 return interp_ok ( ImmTy :: uninit ( dest. layout ) ) ;
7780 }
81+ ty:: RawPtr ( ..) => {
82+ let x = unsafe { ffi:: call :: < * const ( ) > ( ptr, libffi_args. as_slice ( ) ) } ;
83+ let ptr = Pointer :: new ( Provenance :: Wildcard , Size :: from_bytes ( x. addr ( ) ) ) ;
84+ Scalar :: from_pointer ( ptr, this)
85+ }
7886 _ => throw_unsup_format ! ( "unsupported return type for native call: {:?}" , link_name) ,
7987 } ;
8088 interp_ok ( ImmTy :: from_scalar ( scalar, dest. layout ) )
@@ -152,8 +160,26 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
152160 if !matches ! ( arg. layout. backend_repr, BackendRepr :: Scalar ( _) ) {
153161 throw_unsup_format ! ( "only scalar argument types are support for native calls" )
154162 }
155- libffi_args. push ( imm_to_carg ( this. read_immediate ( arg) ?, this) ?) ;
163+ let imm = this. read_immediate ( arg) ?;
164+ libffi_args. push ( imm_to_carg ( & imm, this) ?) ;
165+ // If we are passing a pointer, prepare the memory it points to.
166+ if matches ! ( arg. layout. ty. kind( ) , ty:: RawPtr ( ..) ) {
167+ let ptr = imm. to_scalar ( ) . to_pointer ( this) ?;
168+ let Some ( prov) = ptr. provenance else {
169+ // Pointer without provenance may not access any memory.
170+ continue ;
171+ } ;
172+ // We use `get_alloc_id` for its best-effort behaviour with Wildcard provenance.
173+ let Some ( alloc_id) = prov. get_alloc_id ( ) else {
174+ // Wildcard pointer, whatever it points to must be already exposed.
175+ continue ;
176+ } ;
177+ this. prepare_for_native_call ( alloc_id, prov) ?;
178+ }
156179 }
180+
181+ // FIXME: In the future, we should also call `prepare_for_native_call` on all previously
182+ // exposed allocations, since C may access any of them.
157183
158184 // Convert them to `libffi::high::Arg` type.
159185 let libffi_args = libffi_args
@@ -220,7 +246,7 @@ impl<'a> CArg {
220246
221247/// Extract the scalar value from the result of reading a scalar from the machine,
222248/// and convert it to a `CArg`.
223- fn imm_to_carg < ' tcx > ( v : ImmTy < ' tcx > , cx : & impl HasDataLayout ) -> InterpResult < ' tcx , CArg > {
249+ fn imm_to_carg < ' tcx > ( v : & ImmTy < ' tcx > , cx : & impl HasDataLayout ) -> InterpResult < ' tcx , CArg > {
224250 interp_ok ( match v. layout . ty . kind ( ) {
225251 // If the primitive provided can be converted to a type matching the type pattern
226252 // then create a `CArg` of this primitive value with the corresponding `CArg` constructor.
@@ -238,18 +264,10 @@ fn imm_to_carg<'tcx>(v: ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<'t
238264 ty:: Uint ( UintTy :: U64 ) => CArg :: UInt64 ( v. to_scalar ( ) . to_u64 ( ) ?) ,
239265 ty:: Uint ( UintTy :: Usize ) =>
240266 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- }
267+ ty:: RawPtr ( ..) => {
268+ let s = v. to_scalar ( ) . to_pointer ( cx) ?. addr ( ) ;
269+ // This relies on the `expose_provenance` in `addr_from_alloc_id`.
270+ CArg :: RawPtr ( std:: ptr:: with_exposed_provenance_mut ( s. bytes_usize ( ) ) )
253271 }
254272 _ => throw_unsup_format ! ( "unsupported argument type for native call: {}" , v. layout. ty) ,
255273 } )
0 commit comments