Rollup merge of #126787 - Strophox:get-bytes, r=RalfJung
Add direct accessors for memory addresses in `Machine` (for Miri) The purpose of this PR is to enable direct (immutable) access to memory addresses in `Machine`, which will be needed for further extension of Miri. This is done by adding (/completing missings pairs of) accessor functions, with the relevant signatures as follows: ```rust /* rust/compiler/rustc_middle/src/mir/interpret/allocation.rs */ pub trait AllocBytes { // .. fn as_ptr(&self) -> *const u8; /*fn as_mut_ptr(&mut self) -> *mut u8; -- Already in the compiler*/ } impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes> { // .. pub fn get_bytes_unchecked_raw(&self) -> *const u8; /*pub fn get_bytes_unchecked_raw_mut(&mut self) -> *mut u8; -- Already in the compiler*/ } ``` ```rust /* rust/compiler/rustc_const_eval/src/interpret/memory.rs */ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // .. pub fn get_alloc_bytes_unchecked_raw(&self, id: AllocId) -> InterpResult<'tcx, *const u8>; pub fn get_alloc_bytes_unchecked_raw_mut(&mut self, id: AllocId) -> InterpResult<'tcx, *mut u8>; } ``` r? ``@RalfJung``
This commit is contained in:
commit
9498d5cf2f
@ -630,6 +630,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gives raw, immutable access to the `Allocation` address, without bounds or alignment checks.
|
||||||
|
/// The caller is responsible for calling the access hooks!
|
||||||
|
pub fn get_alloc_bytes_unchecked_raw(&self, id: AllocId) -> InterpResult<'tcx, *const u8> {
|
||||||
|
let alloc = self.get_alloc_raw(id)?;
|
||||||
|
Ok(alloc.get_bytes_unchecked_raw())
|
||||||
|
}
|
||||||
|
|
||||||
/// Bounds-checked *but not align-checked* allocation access.
|
/// Bounds-checked *but not align-checked* allocation access.
|
||||||
pub fn get_ptr_alloc<'a>(
|
pub fn get_ptr_alloc<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
@ -713,6 +720,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||||||
Ok((alloc, &mut self.machine))
|
Ok((alloc, &mut self.machine))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gives raw, mutable access to the `Allocation` address, without bounds or alignment checks.
|
||||||
|
/// The caller is responsible for calling the access hooks!
|
||||||
|
pub fn get_alloc_bytes_unchecked_raw_mut(
|
||||||
|
&mut self,
|
||||||
|
id: AllocId,
|
||||||
|
) -> InterpResult<'tcx, *mut u8> {
|
||||||
|
let alloc = self.get_alloc_raw_mut(id)?.0;
|
||||||
|
Ok(alloc.get_bytes_unchecked_raw_mut())
|
||||||
|
}
|
||||||
|
|
||||||
/// Bounds-checked *but not align-checked* allocation access.
|
/// Bounds-checked *but not align-checked* allocation access.
|
||||||
pub fn get_ptr_alloc_mut<'a>(
|
pub fn get_ptr_alloc_mut<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
|
@ -40,9 +40,16 @@ pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Targe
|
|||||||
/// Gives direct access to the raw underlying storage.
|
/// Gives direct access to the raw underlying storage.
|
||||||
///
|
///
|
||||||
/// Crucially this pointer is compatible with:
|
/// Crucially this pointer is compatible with:
|
||||||
/// - other pointers retunred by this method, and
|
/// - other pointers returned by this method, and
|
||||||
/// - references returned from `deref()`, as long as there was no write.
|
/// - references returned from `deref()`, as long as there was no write.
|
||||||
fn as_mut_ptr(&mut self) -> *mut u8;
|
fn as_mut_ptr(&mut self) -> *mut u8;
|
||||||
|
|
||||||
|
/// Gives direct access to the raw underlying storage.
|
||||||
|
///
|
||||||
|
/// Crucially this pointer is compatible with:
|
||||||
|
/// - other pointers returned by this method, and
|
||||||
|
/// - references returned from `deref()`, as long as there was no write.
|
||||||
|
fn as_ptr(&self) -> *const u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default `bytes` for `Allocation` is a `Box<u8>`.
|
/// Default `bytes` for `Allocation` is a `Box<u8>`.
|
||||||
@ -62,6 +69,11 @@ impl AllocBytes for Box<[u8]> {
|
|||||||
// Carefully avoiding any intermediate references.
|
// Carefully avoiding any intermediate references.
|
||||||
ptr::addr_of_mut!(**self).cast()
|
ptr::addr_of_mut!(**self).cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_ptr(&self) -> *const u8 {
|
||||||
|
// Carefully avoiding any intermediate references.
|
||||||
|
ptr::addr_of!(**self).cast()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This type represents an Allocation in the Miri/CTFE core engine.
|
/// This type represents an Allocation in the Miri/CTFE core engine.
|
||||||
@ -490,19 +502,27 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
|
|||||||
self.provenance.clear(range, cx)?;
|
self.provenance.clear(range, cx)?;
|
||||||
|
|
||||||
assert!(range.end().bytes_usize() <= self.bytes.len()); // need to do our own bounds-check
|
assert!(range.end().bytes_usize() <= self.bytes.len()); // need to do our own bounds-check
|
||||||
// Cruciall, we go via `AllocBytes::as_mut_ptr`, not `AllocBytes::deref_mut`.
|
// Crucially, we go via `AllocBytes::as_mut_ptr`, not `AllocBytes::deref_mut`.
|
||||||
let begin_ptr = self.bytes.as_mut_ptr().wrapping_add(range.start.bytes_usize());
|
let begin_ptr = self.bytes.as_mut_ptr().wrapping_add(range.start.bytes_usize());
|
||||||
let len = range.end().bytes_usize() - range.start.bytes_usize();
|
let len = range.end().bytes_usize() - range.start.bytes_usize();
|
||||||
Ok(ptr::slice_from_raw_parts_mut(begin_ptr, len))
|
Ok(ptr::slice_from_raw_parts_mut(begin_ptr, len))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This gives direct mutable access to the entire buffer, just exposing their internal state
|
/// This gives direct mutable access to the entire buffer, just exposing their internal state
|
||||||
/// without reseting anything. Directly exposes `AllocBytes::as_mut_ptr`. Only works if
|
/// without resetting anything. Directly exposes `AllocBytes::as_mut_ptr`. Only works if
|
||||||
/// `OFFSET_IS_ADDR` is true.
|
/// `OFFSET_IS_ADDR` is true.
|
||||||
pub fn get_bytes_unchecked_raw_mut(&mut self) -> *mut u8 {
|
pub fn get_bytes_unchecked_raw_mut(&mut self) -> *mut u8 {
|
||||||
assert!(Prov::OFFSET_IS_ADDR);
|
assert!(Prov::OFFSET_IS_ADDR);
|
||||||
self.bytes.as_mut_ptr()
|
self.bytes.as_mut_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This gives direct immutable access to the entire buffer, just exposing their internal state
|
||||||
|
/// without resetting anything. Directly exposes `AllocBytes::as_ptr`. Only works if
|
||||||
|
/// `OFFSET_IS_ADDR` is true.
|
||||||
|
pub fn get_bytes_unchecked_raw(&self) -> *const u8 {
|
||||||
|
assert!(Prov::OFFSET_IS_ADDR);
|
||||||
|
self.bytes.as_ptr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reading and writing.
|
/// Reading and writing.
|
||||||
|
@ -108,4 +108,8 @@ impl AllocBytes for MiriAllocBytes {
|
|||||||
fn as_mut_ptr(&mut self) -> *mut u8 {
|
fn as_mut_ptr(&mut self) -> *mut u8 {
|
||||||
self.ptr
|
self.ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_ptr(&self) -> *const u8 {
|
||||||
|
self.ptr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user