Skip to content

Commit 3846f94

Browse files
committed
miri native_calls: ensure we actually expose *mutable* provenance to the memory FFI can access
1 parent 705421b commit 3846f94

File tree

4 files changed

+12
-3
lines changed

4 files changed

+12
-3
lines changed

Diff for: compiler/rustc_const_eval/src/interpret/memory.rs

+4
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
982982
todo.push(id);
983983
}
984984
}
985+
// Also expose the provenance of the interpreter-level allocation, so it can
986+
// be read by FFI. The `black_box` is defensive programming as LLVM likes
987+
// to (incorrectly) optimize away ptr2int casts whose result is unused.
988+
std::hint::black_box(alloc.get_bytes_unchecked_raw().expose_provenance());
985989

986990
// Prepare for possible write from native code if mutable.
987991
if info.mutbl.is_mut() {

Diff for: compiler/rustc_middle/src/mir/interpret/allocation.rs

+5
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,11 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
679679
// Set provenance of all bytes to wildcard.
680680
self.provenance.write_wildcards(self.len());
681681

682+
// Also expose the provenance of the interpreter-level allocation, so it can
683+
// be written by FFI. The `black_box` is defensive programming as LLVM likes
684+
// to (incorrectly) optimize away ptr2int casts whose result is unused.
685+
std::hint::black_box(self.get_bytes_unchecked_raw_mut().expose_provenance());
686+
682687
Ok(())
683688
}
684689

Diff for: src/tools/miri/src/alloc_addresses/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
198198
}
199199
AllocKind::Dead => unreachable!(),
200200
};
201-
// Ensure this pointer's provenance is exposed, so that it can be used by FFI code.
202-
return interp_ok(base_ptr.expose_provenance().try_into().unwrap());
201+
// We don't have to expose this pointer yet, we do that in `prepare_for_native_call`.
202+
return interp_ok(base_ptr.addr().try_into().unwrap());
203203
}
204204
// We are not in native lib mode, so we control the addresses ourselves.
205205
if let Some((reuse_addr, clock)) = global_state.reuse.take_addr(

Diff for: src/tools/miri/src/shims/native_lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ fn imm_to_carg<'tcx>(v: &ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<'
266266
CArg::USize(v.to_scalar().to_target_usize(cx)?.try_into().unwrap()),
267267
ty::RawPtr(..) => {
268268
let s = v.to_scalar().to_pointer(cx)?.addr();
269-
// This relies on the `expose_provenance` in `addr_from_alloc_id`.
269+
// This relies on the `expose_provenance` in `prepare_for_native_call`.
270270
CArg::RawPtr(std::ptr::with_exposed_provenance_mut(s.bytes_usize()))
271271
}
272272
_ => throw_unsup_format!("unsupported argument type for native call: {}", v.layout.ty),

0 commit comments

Comments
 (0)