Skip to content

Commit

Permalink
Merge pull request #4021 from RalfJung/rustup
Browse files Browse the repository at this point in the history
Rustup
  • Loading branch information
RalfJung authored Nov 10, 2024
2 parents b7839b6 + 09b8d69 commit 9c0abc4
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 23 deletions.
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
328b759142ddeae96da83176f103200009d3e3f1
668959740f97e7a22ae340742886d330ab63950f
26 changes: 15 additions & 11 deletions src/alloc_addresses/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
// entered for addresses that are not the base address, so even zero-sized
// allocations will get recognized at their base address -- but all other
// allocations will *not* be recognized at their "end" address.
let size = this.get_alloc_info(alloc_id).0;
let size = this.get_alloc_info(alloc_id).size;
if offset < size.bytes() { Some(alloc_id) } else { None }
}
}?;
Expand All @@ -157,25 +157,25 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
) -> InterpResult<'tcx, u64> {
let this = self.eval_context_ref();
let mut rng = this.machine.rng.borrow_mut();
let (size, align, kind) = this.get_alloc_info(alloc_id);
let info = this.get_alloc_info(alloc_id);
// This is either called immediately after allocation (and then cached), or when
// adjusting `tcx` pointers (which never get freed). So assert that we are looking
// at a live allocation. This also ensures that we never re-assign an address to an
// allocation that previously had an address, but then was freed and the address
// information was removed.
assert!(!matches!(kind, AllocKind::Dead));
assert!(!matches!(info.kind, AllocKind::Dead));

// This allocation does not have a base address yet, pick or reuse one.
if this.machine.native_lib.is_some() {
// In native lib mode, we use the "real" address of the bytes for this allocation.
// This ensures the interpreted program and native code have the same view of memory.
let base_ptr = match kind {
let base_ptr = match info.kind {
AllocKind::LiveData => {
if this.tcx.try_get_global_alloc(alloc_id).is_some() {
// For new global allocations, we always pre-allocate the memory to be able use the machine address directly.
let prepared_bytes = MiriAllocBytes::zeroed(size, align)
let prepared_bytes = MiriAllocBytes::zeroed(info.size, info.align)
.unwrap_or_else(|| {
panic!("Miri ran out of memory: cannot create allocation of {size:?} bytes")
panic!("Miri ran out of memory: cannot create allocation of {size:?} bytes", size = info.size)
});
let ptr = prepared_bytes.as_ptr();
// Store prepared allocation space to be picked up for use later.
Expand Down Expand Up @@ -203,9 +203,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
return interp_ok(base_ptr.expose_provenance().try_into().unwrap());
}
// We are not in native lib mode, so we control the addresses ourselves.
if let Some((reuse_addr, clock)) =
global_state.reuse.take_addr(&mut *rng, size, align, memory_kind, this.active_thread())
{
if let Some((reuse_addr, clock)) = global_state.reuse.take_addr(
&mut *rng,
info.size,
info.align,
memory_kind,
this.active_thread(),
) {
if let Some(clock) = clock {
this.acquire_clock(&clock);
}
Expand All @@ -220,14 +224,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
.next_base_addr
.checked_add(slack)
.ok_or_else(|| err_exhaust!(AddressSpaceFull))?;
let base_addr = align_addr(base_addr, align.bytes());
let base_addr = align_addr(base_addr, info.align.bytes());

// Remember next base address. If this allocation is zero-sized, leave a gap of at
// least 1 to avoid two allocations having the same base address. (The logic in
// `alloc_id_from_addr` assumes unique addresses, and different function/vtable pointers
// need to be distinguishable!)
global_state.next_base_addr = base_addr
.checked_add(max(size.bytes(), 1))
.checked_add(max(info.size.bytes(), 1))
.ok_or_else(|| err_exhaust!(AddressSpaceFull))?;
// Even if `Size` didn't overflow, we might still have filled up the address space.
if global_state.next_base_addr > this.target_usize_max() {
Expand Down
2 changes: 1 addition & 1 deletion src/borrow_tracker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// If it does exist, then we have the guarantee that the
// pointer is readable, and the implicit read access inserted
// will never cause UB on the pointer itself.
let (_, _, kind) = this.get_alloc_info(*alloc_id);
let kind = this.get_alloc_info(*alloc_id).kind;
if matches!(kind, AllocKind::LiveData) {
let alloc_extra = this.get_alloc_extra(*alloc_id)?; // can still fail for `extern static`
let alloc_borrow_tracker = &alloc_extra.borrow_tracker.as_ref().unwrap();
Expand Down
4 changes: 2 additions & 2 deletions src/borrow_tracker/stacked_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
return interp_ok(())
};

let (_size, _align, alloc_kind) = this.get_alloc_info(alloc_id);
let alloc_kind = this.get_alloc_info(alloc_id).kind;
match alloc_kind {
AllocKind::LiveData => {
// This should have alloc_extra data, but `get_alloc_extra` can still fail
Expand Down Expand Up @@ -1017,7 +1017,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Function pointers and dead objects don't have an alloc_extra so we ignore them.
// This is okay because accessing them is UB anyway, no need for any Stacked Borrows checks.
// NOT using `get_alloc_extra_mut` since this might be a read-only allocation!
let (_size, _align, kind) = this.get_alloc_info(alloc_id);
let kind = this.get_alloc_info(alloc_id).kind;
match kind {
AllocKind::LiveData => {
// This should have alloc_extra data, but `get_alloc_extra` can still fail
Expand Down
4 changes: 2 additions & 2 deletions src/borrow_tracker/tree_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
.insert(new_tag, protect);
}

let alloc_kind = this.get_alloc_info(alloc_id).2;
let alloc_kind = this.get_alloc_info(alloc_id).kind;
if !matches!(alloc_kind, AllocKind::LiveData) {
assert_eq!(ptr_size, Size::ZERO); // we did the deref check above, size has to be 0 here
// There's not actually any bytes here where accesses could even be tracked.
Expand Down Expand Up @@ -538,7 +538,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Function pointers and dead objects don't have an alloc_extra so we ignore them.
// This is okay because accessing them is UB anyway, no need for any Tree Borrows checks.
// NOT using `get_alloc_extra_mut` since this might be a read-only allocation!
let (_size, _align, kind) = this.get_alloc_info(alloc_id);
let kind = this.get_alloc_info(alloc_id).kind;
match kind {
AllocKind::LiveData => {
// This should have alloc_extra data, but `get_alloc_extra` can still fail
Expand Down
8 changes: 4 additions & 4 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1125,10 +1125,10 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
let Provenance::Concrete { alloc_id, .. } = ptr.provenance else {
panic!("extern_statics cannot contain wildcards")
};
let (shim_size, shim_align, _kind) = ecx.get_alloc_info(alloc_id);
let info = ecx.get_alloc_info(alloc_id);
let def_ty = ecx.tcx.type_of(def_id).instantiate_identity();
let extern_decl_layout = ecx.tcx.layout_of(ty::ParamEnv::empty().and(def_ty)).unwrap();
if extern_decl_layout.size != shim_size || extern_decl_layout.align.abi != shim_align {
if extern_decl_layout.size != info.size || extern_decl_layout.align.abi != info.align {
throw_unsup_format!(
"extern static `{link_name}` has been declared as `{krate}::{name}` \
with a size of {decl_size} bytes and alignment of {decl_align} bytes, \
Expand All @@ -1138,8 +1138,8 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
krate = ecx.tcx.crate_name(def_id.krate),
decl_size = extern_decl_layout.size.bytes(),
decl_align = extern_decl_layout.align.abi.bytes(),
shim_size = shim_size.bytes(),
shim_align = shim_align.bytes(),
shim_size = info.size.bytes(),
shim_align = info.align.bytes(),
)
}
interp_ok(ptr)
Expand Down
4 changes: 2 additions & 2 deletions src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
let id = this.read_scalar(id)?.to_u64()?;
let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?;
if let Some(id) = std::num::NonZero::new(id).map(AllocId)
&& this.get_alloc_info(id).2 == AllocKind::LiveData
&& this.get_alloc_info(id).kind == AllocKind::LiveData
{
this.print_borrow_state(id, show_unnamed)?;
} else {
Expand Down Expand Up @@ -409,7 +409,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
);
}
if let Ok((alloc_id, offset, ..)) = this.ptr_try_get_alloc_id(ptr, 0) {
let (_size, alloc_align, _kind) = this.get_alloc_info(alloc_id);
let alloc_align = this.get_alloc_info(alloc_id).align;
// If the newly promised alignment is bigger than the native alignment of this
// allocation, and bigger than the previously promised alignment, then set it.
if align > alloc_align
Expand Down

0 comments on commit 9c0abc4

Please sign in to comment.