@@ -3,7 +3,8 @@ use std::ops::Deref;
3
3
4
4
use libffi:: high:: call as ffi;
5
5
use libffi:: low:: CodePtr ;
6
- use rustc_abi:: { BackendRepr , HasDataLayout } ;
6
+ use rustc_abi:: { BackendRepr , HasDataLayout , Size } ;
7
+ use rustc_middle:: mir:: interpret:: Pointer ;
7
8
use rustc_middle:: ty:: { self as ty, IntTy , UintTy } ;
8
9
use rustc_span:: Symbol ;
9
10
@@ -75,6 +76,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
75
76
unsafe { ffi:: call :: < ( ) > ( ptr, libffi_args. as_slice ( ) ) } ;
76
77
return interp_ok ( ImmTy :: uninit ( dest. layout ) ) ;
77
78
}
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
+ }
78
84
_ => throw_unsup_format ! ( "unsupported return type for native call: {:?}" , link_name) ,
79
85
} ;
80
86
interp_ok ( ImmTy :: from_scalar ( scalar, dest. layout ) )
@@ -152,9 +158,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
152
158
if !matches ! ( arg. layout. backend_repr, BackendRepr :: Scalar ( _) ) {
153
159
throw_unsup_format ! ( "only scalar argument types are support for native calls" )
154
160
}
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
+ }
156
177
}
157
178
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
+
158
182
// Convert them to `libffi::high::Arg` type.
159
183
let libffi_args = libffi_args
160
184
. iter ( )
@@ -220,7 +244,7 @@ impl<'a> CArg {
220
244
221
245
/// Extract the scalar value from the result of reading a scalar from the machine,
222
246
/// 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 > {
224
248
interp_ok ( match v. layout . ty . kind ( ) {
225
249
// If the primitive provided can be converted to a type matching the type pattern
226
250
// 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
238
262
ty:: Uint ( UintTy :: U64 ) => CArg :: UInt64 ( v. to_scalar ( ) . to_u64 ( ) ?) ,
239
263
ty:: Uint ( UintTy :: Usize ) =>
240
264
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 ( ) ) )
253
269
}
254
270
_ => throw_unsup_format ! ( "unsupported argument type for native call: {}" , v. layout. ty) ,
255
271
} )
0 commit comments