interpret: pass MemoryKind to adjust_alloc_base_pointer
This commit is contained in:
parent
468f115684
commit
9e239bdc76
@ -301,15 +301,6 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
|||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
||||||
|
|
||||||
/// Return a "base" pointer for the given allocation: the one that is used for direct
|
|
||||||
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
|
|
||||||
///
|
|
||||||
/// Not called on `extern` or thread-local statics (those use the methods above).
|
|
||||||
fn adjust_alloc_base_pointer(
|
|
||||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
|
||||||
ptr: Pointer,
|
|
||||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
|
||||||
|
|
||||||
/// "Int-to-pointer cast"
|
/// "Int-to-pointer cast"
|
||||||
fn ptr_from_addr_cast(
|
fn ptr_from_addr_cast(
|
||||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||||
@ -336,6 +327,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
|||||||
|
|
||||||
/// Called to adjust allocations to the Provenance and AllocExtra of this machine.
|
/// Called to adjust allocations to the Provenance and AllocExtra of this machine.
|
||||||
///
|
///
|
||||||
|
/// If `alloc` contains pointers, then they are all pointing to globals.
|
||||||
|
///
|
||||||
/// The way we construct allocations is to always first construct it without extra and then add
|
/// The way we construct allocations is to always first construct it without extra and then add
|
||||||
/// the extra. This keeps uniform code paths for handling both allocations created by CTFE for
|
/// the extra. This keeps uniform code paths for handling both allocations created by CTFE for
|
||||||
/// globals, and allocations created by Miri during evaluation.
|
/// globals, and allocations created by Miri during evaluation.
|
||||||
@ -354,6 +347,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
|||||||
kind: Option<MemoryKind<Self::MemoryKind>>,
|
kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||||
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
|
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
|
||||||
|
|
||||||
|
/// Return a "root" pointer for the given allocation: the one that is used for direct
|
||||||
|
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
|
||||||
|
///
|
||||||
|
/// Not called on `extern` or thread-local statics (those use the methods above).
|
||||||
|
///
|
||||||
|
/// `kind` is the kind of the allocation the pointer points to; it can be `None` when
|
||||||
|
/// it's a global and `GLOBAL_KIND` is `None`.
|
||||||
|
fn adjust_alloc_base_pointer(
|
||||||
|
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||||
|
ptr: Pointer,
|
||||||
|
kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||||
|
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
||||||
|
|
||||||
/// Evaluate the inline assembly.
|
/// Evaluate the inline assembly.
|
||||||
///
|
///
|
||||||
/// This should take care of jumping to the next block (one of `targets`) when asm goto
|
/// This should take care of jumping to the next block (one of `targets`) when asm goto
|
||||||
@ -604,6 +610,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
|||||||
fn adjust_alloc_base_pointer(
|
fn adjust_alloc_base_pointer(
|
||||||
_ecx: &InterpCx<$mir, $tcx, Self>,
|
_ecx: &InterpCx<$mir, $tcx, Self>,
|
||||||
ptr: Pointer<CtfeProvenance>,
|
ptr: Pointer<CtfeProvenance>,
|
||||||
|
_kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||||
) -> InterpResult<$tcx, Pointer<CtfeProvenance>> {
|
) -> InterpResult<$tcx, Pointer<CtfeProvenance>> {
|
||||||
Ok(ptr)
|
Ok(ptr)
|
||||||
}
|
}
|
||||||
|
@ -180,10 +180,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
Some(GlobalAlloc::Static(def_id)) if self.tcx.is_foreign_item(def_id) => {
|
Some(GlobalAlloc::Static(def_id)) if self.tcx.is_foreign_item(def_id) => {
|
||||||
return M::extern_static_base_pointer(self, def_id);
|
return M::extern_static_base_pointer(self, def_id);
|
||||||
}
|
}
|
||||||
|
None => {
|
||||||
|
assert!(
|
||||||
|
self.memory.extra_fn_ptr_map.contains_key(&alloc_id),
|
||||||
|
"{alloc_id:?} is neither global nor a function pointer"
|
||||||
|
);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
// And we need to get the provenance.
|
// And we need to get the provenance.
|
||||||
M::adjust_alloc_base_pointer(self, ptr)
|
M::adjust_alloc_base_pointer(self, ptr, M::GLOBAL_KIND.map(MemoryKind::Machine))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fn_ptr(&mut self, fn_val: FnVal<'tcx, M::ExtraFnVal>) -> Pointer<M::Provenance> {
|
pub fn fn_ptr(&mut self, fn_val: FnVal<'tcx, M::ExtraFnVal>) -> Pointer<M::Provenance> {
|
||||||
@ -240,7 +246,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
);
|
);
|
||||||
let alloc = M::adjust_allocation(self, id, Cow::Owned(alloc), Some(kind))?;
|
let alloc = M::adjust_allocation(self, id, Cow::Owned(alloc), Some(kind))?;
|
||||||
self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
|
self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
|
||||||
M::adjust_alloc_base_pointer(self, Pointer::from(id))
|
M::adjust_alloc_base_pointer(self, Pointer::from(id), Some(kind))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reallocate_ptr(
|
pub fn reallocate_ptr(
|
||||||
|
@ -141,7 +141,11 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addr_from_alloc_id(&self, alloc_id: AllocId) -> InterpResult<'tcx, u64> {
|
fn addr_from_alloc_id(
|
||||||
|
&self,
|
||||||
|
alloc_id: AllocId,
|
||||||
|
_kind: MemoryKind,
|
||||||
|
) -> InterpResult<'tcx, u64> {
|
||||||
let ecx = self.eval_context_ref();
|
let ecx = self.eval_context_ref();
|
||||||
let mut global_state = ecx.machine.alloc_addresses.borrow_mut();
|
let mut global_state = ecx.machine.alloc_addresses.borrow_mut();
|
||||||
let global_state = &mut *global_state;
|
let global_state = &mut *global_state;
|
||||||
@ -283,16 +287,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a relative (tcx) pointer to a Miri pointer.
|
/// Convert a relative (tcx) pointer to a Miri pointer.
|
||||||
fn ptr_from_rel_ptr(
|
fn adjust_alloc_base_pointer(
|
||||||
&self,
|
&self,
|
||||||
ptr: Pointer<CtfeProvenance>,
|
ptr: Pointer<CtfeProvenance>,
|
||||||
tag: BorTag,
|
tag: BorTag,
|
||||||
|
kind: MemoryKind,
|
||||||
) -> InterpResult<'tcx, Pointer<Provenance>> {
|
) -> InterpResult<'tcx, Pointer<Provenance>> {
|
||||||
let ecx = self.eval_context_ref();
|
let ecx = self.eval_context_ref();
|
||||||
|
|
||||||
let (prov, offset) = ptr.into_parts(); // offset is relative (AllocId provenance)
|
let (prov, offset) = ptr.into_parts(); // offset is relative (AllocId provenance)
|
||||||
let alloc_id = prov.alloc_id();
|
let alloc_id = prov.alloc_id();
|
||||||
let base_addr = ecx.addr_from_alloc_id(alloc_id)?;
|
let base_addr = ecx.addr_from_alloc_id(alloc_id, kind)?;
|
||||||
|
|
||||||
// Add offset with the right kind of pointer-overflowing arithmetic.
|
// Add offset with the right kind of pointer-overflowing arithmetic.
|
||||||
let dl = ecx.data_layout();
|
let dl = ecx.data_layout();
|
||||||
@ -314,9 +319,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
ecx.alloc_id_from_addr(addr.bytes())?
|
ecx.alloc_id_from_addr(addr.bytes())?
|
||||||
};
|
};
|
||||||
|
|
||||||
// This cannot fail: since we already have a pointer with that provenance, rel_ptr_to_addr
|
// This cannot fail: since we already have a pointer with that provenance, adjust_alloc_base_pointer
|
||||||
// must have been called in the past, so we can just look up the address in the map.
|
// must have been called in the past, so we can just look up the address in the map.
|
||||||
let base_addr = ecx.addr_from_alloc_id(alloc_id).unwrap();
|
let base_addr = *ecx.machine.alloc_addresses.borrow().base_addr.get(&alloc_id).unwrap();
|
||||||
|
|
||||||
// Wrapping "addr - base_addr"
|
// Wrapping "addr - base_addr"
|
||||||
#[allow(clippy::cast_possible_wrap)] // we want to wrap here
|
#[allow(clippy::cast_possible_wrap)] // we want to wrap here
|
||||||
|
@ -1090,7 +1090,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
|||||||
alloc: Cow<'b, Allocation>,
|
alloc: Cow<'b, Allocation>,
|
||||||
kind: Option<MemoryKind>,
|
kind: Option<MemoryKind>,
|
||||||
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra>>> {
|
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra>>> {
|
||||||
let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
|
let kind = kind.expect("we set our GLOBAL_KIND so this cannot be None");
|
||||||
if ecx.machine.tracked_alloc_ids.contains(&id) {
|
if ecx.machine.tracked_alloc_ids.contains(&id) {
|
||||||
ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
|
ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(
|
||||||
id,
|
id,
|
||||||
@ -1151,7 +1151,9 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
|||||||
fn adjust_alloc_base_pointer(
|
fn adjust_alloc_base_pointer(
|
||||||
ecx: &MiriInterpCx<'mir, 'tcx>,
|
ecx: &MiriInterpCx<'mir, 'tcx>,
|
||||||
ptr: Pointer<CtfeProvenance>,
|
ptr: Pointer<CtfeProvenance>,
|
||||||
|
kind: Option<MemoryKind>,
|
||||||
) -> InterpResult<'tcx, Pointer<Provenance>> {
|
) -> InterpResult<'tcx, Pointer<Provenance>> {
|
||||||
|
let kind = kind.expect("we set our GLOBAL_KIND so this cannot be None");
|
||||||
let alloc_id = ptr.provenance.alloc_id();
|
let alloc_id = ptr.provenance.alloc_id();
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
// The machine promises to never call us on thread-local or extern statics.
|
// The machine promises to never call us on thread-local or extern statics.
|
||||||
@ -1172,7 +1174,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
|||||||
// Value does not matter, SB is disabled
|
// Value does not matter, SB is disabled
|
||||||
BorTag::default()
|
BorTag::default()
|
||||||
};
|
};
|
||||||
ecx.ptr_from_rel_ptr(ptr, tag)
|
ecx.adjust_alloc_base_pointer(ptr, tag, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called on `usize as ptr` casts.
|
/// Called on `usize as ptr` casts.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user