Skip to content

Commit

Permalink
clean up int2ptr code a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed May 23, 2022
1 parent ab03d32 commit 697dca2
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 32 deletions.
53 changes: 35 additions & 18 deletions src/intptrcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ impl<'mir, 'tcx> GlobalStateInner {
trace!("Exposing allocation id {:?}", alloc_id);

let mut global_state = ecx.machine.intptrcast.borrow_mut();
// In legacy and strict mode, we don't need this, so we can save some cycles
// by not tracking it.
if global_state.provenance_mode == ProvenanceMode::Permissive {
global_state.exposed.insert(alloc_id);
}
Expand All @@ -118,12 +120,17 @@ impl<'mir, 'tcx> GlobalStateInner {

let global_state = ecx.machine.intptrcast.borrow();

// In legacy mode, we have to support int2ptr transmutes,
// so just pretend they do the same thing as a cast.
if global_state.provenance_mode == ProvenanceMode::Legacy {
Self::ptr_from_addr_cast(ecx, addr)
} else {
Pointer::new(None, Size::from_bytes(addr))
match global_state.provenance_mode {
ProvenanceMode::Legacy => {
// In legacy mode, we have to support int2ptr transmutes,
// so just pretend they do the same thing as a cast.
Self::ptr_from_addr_cast(ecx, addr)
}
ProvenanceMode::Permissive | ProvenanceMode::Strict => {
// Both of these modes consider transmuted pointers to be "invalid" (`None`
// provenance).
Pointer::new(None, Size::from_bytes(addr))
}
}
}

Expand All @@ -135,18 +142,26 @@ impl<'mir, 'tcx> GlobalStateInner {

let global_state = ecx.machine.intptrcast.borrow();

if global_state.provenance_mode == ProvenanceMode::Strict {
Pointer::new(None, Size::from_bytes(addr))
} else if global_state.provenance_mode == ProvenanceMode::Legacy {
let alloc_id = Self::alloc_id_from_addr(ecx, addr);

Pointer::new(
alloc_id
.map(|alloc_id| Tag::Concrete(ConcreteTag { alloc_id, sb: SbTag::Untagged })),
Size::from_bytes(addr),
)
} else {
Pointer::new(Some(Tag::Wildcard), Size::from_bytes(addr))
match global_state.provenance_mode {
ProvenanceMode::Legacy => {
// Determine the allocation this points to at cast time.
let alloc_id = Self::alloc_id_from_addr(ecx, addr);
Pointer::new(
alloc_id.map(|alloc_id| {
Tag::Concrete(ConcreteTag { alloc_id, sb: SbTag::Untagged })
}),
Size::from_bytes(addr),
)
}
ProvenanceMode::Strict => {
// We don't support int2ptr casts in this mode (i.e., we treat them like
// transmutes).
Pointer::new(None, Size::from_bytes(addr))
}
ProvenanceMode::Permissive => {
// This is how wildcard pointers are born.
Pointer::new(Some(Tag::Wildcard), Size::from_bytes(addr))
}
}
}

Expand Down Expand Up @@ -215,6 +230,8 @@ impl<'mir, 'tcx> GlobalStateInner {
let alloc_id = if let Tag::Concrete(concrete) = tag {
concrete.alloc_id
} else {
// A wildcard pointer.
assert_eq!(ecx.machine.intptrcast.borrow().provenance_mode, ProvenanceMode::Permissive);
GlobalStateInner::alloc_id_from_addr(ecx, addr.bytes())?
};

Expand Down
28 changes: 14 additions & 14 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,19 +652,18 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
intptrcast::GlobalStateInner::ptr_from_addr_transmute(ecx, addr)
}

#[inline(always)]
fn expose_ptr(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
ptr: Pointer<Self::PointerTag>,
) -> InterpResult<'tcx> {
let tag = ptr.provenance;

if let Tag::Concrete(concrete) = tag {
intptrcast::GlobalStateInner::expose_addr(ecx, concrete.alloc_id);
match ptr.provenance {
Tag::Concrete(concrete) =>
intptrcast::GlobalStateInner::expose_addr(ecx, concrete.alloc_id),
Tag::Wildcard => {
// No need to do anything for wildcard pointers as
// their provenances have already been previously exposed.
}
}

// No need to do anything for wildcard pointers as
// their provenances have already been previously exposed.
Ok(())
}

Expand All @@ -676,12 +675,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
) -> Option<(AllocId, Size, Self::TagExtra)> {
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);

let sb = match ptr.provenance {
Tag::Concrete(ConcreteTag { sb, .. }) => sb,
Tag::Wildcard => SbTag::Untagged,
};

rel.map(|(alloc_id, size)| (alloc_id, size, sb))
rel.map(|(alloc_id, size)| {
let sb = match ptr.provenance {
Tag::Concrete(ConcreteTag { sb, .. }) => sb,
Tag::Wildcard => SbTag::Untagged,
};
(alloc_id, size, sb)
})
}

#[inline(always)]
Expand Down

0 comments on commit 697dca2

Please sign in to comment.