Skip to content

Commit

Permalink
Auto merge of rust-lang#2782 - RalfJung:rustup, r=RalfJung
Browse files Browse the repository at this point in the history
Rustup
  • Loading branch information
bors committed Feb 9, 2023
2 parents 04a5e18 + 2d8addb commit fb38aea
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 23 deletions.
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
dffea43fc1102bdfe16d88ed412c23d4f0f08d9d
e7acd078f443156b95cee11759a735db1cfc796e
35 changes: 26 additions & 9 deletions src/intptrcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,14 @@ impl<'mir, 'tcx> GlobalStateInner {
Ok(Pointer::new(Some(Provenance::Wildcard), Size::from_bytes(addr)))
}

fn alloc_base_addr(ecx: &MiriInterpCx<'mir, 'tcx>, alloc_id: AllocId) -> u64 {
fn alloc_base_addr(
ecx: &MiriInterpCx<'mir, 'tcx>,
alloc_id: AllocId,
) -> InterpResult<'tcx, u64> {
let mut global_state = ecx.machine.intptrcast.borrow_mut();
let global_state = &mut *global_state;

match global_state.base_addr.entry(alloc_id) {
Ok(match global_state.base_addr.entry(alloc_id) {
Entry::Occupied(entry) => *entry.get(),
Entry::Vacant(entry) => {
// There is nothing wrong with a raw pointer being cast to an integer only after
Expand All @@ -181,7 +184,10 @@ impl<'mir, 'tcx> GlobalStateInner {
rng.gen_range(0..16)
};
// From next_base_addr + slack, round up to adjust for alignment.
let base_addr = global_state.next_base_addr.checked_add(slack).unwrap();
let base_addr = global_state
.next_base_addr
.checked_add(slack)
.ok_or_else(|| err_exhaust!(AddressSpaceFull))?;
let base_addr = Self::align_addr(base_addr, align.bytes());
entry.insert(base_addr);
trace!(
Expand All @@ -197,24 +203,33 @@ impl<'mir, 'tcx> GlobalStateInner {
// 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)).unwrap();
global_state.next_base_addr = base_addr
.checked_add(max(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 > ecx.machine_usize_max() {
throw_exhaust!(AddressSpaceFull);
}
// Given that `next_base_addr` increases in each allocation, pushing the
// corresponding tuple keeps `int_to_ptr_map` sorted
global_state.int_to_ptr_map.push((base_addr, alloc_id));

base_addr
}
}
})
}

/// Convert a relative (tcx) pointer to an absolute address.
pub fn rel_ptr_to_addr(ecx: &MiriInterpCx<'mir, 'tcx>, ptr: Pointer<AllocId>) -> u64 {
pub fn rel_ptr_to_addr(
ecx: &MiriInterpCx<'mir, 'tcx>,
ptr: Pointer<AllocId>,
) -> InterpResult<'tcx, u64> {
let (alloc_id, offset) = ptr.into_parts(); // offset is relative (AllocId provenance)
let base_addr = GlobalStateInner::alloc_base_addr(ecx, alloc_id);
let base_addr = GlobalStateInner::alloc_base_addr(ecx, alloc_id)?;

// Add offset with the right kind of pointer-overflowing arithmetic.
let dl = ecx.data_layout();
dl.overflowing_offset(base_addr, offset.bytes()).0
Ok(dl.overflowing_offset(base_addr, offset.bytes()).0)
}

/// When a pointer is used for a memory access, this computes where in which allocation the
Expand All @@ -232,7 +247,9 @@ impl<'mir, 'tcx> GlobalStateInner {
GlobalStateInner::alloc_id_from_addr(ecx, addr.bytes())?
};

let base_addr = GlobalStateInner::alloc_base_addr(ecx, alloc_id);
// This cannot fail: since we already have a pointer with that provenance, rel_ptr_to_addr
// must have been called in the past.
let base_addr = GlobalStateInner::alloc_base_addr(ecx, alloc_id).unwrap();

// Wrapping "addr - base_addr"
let dl = ecx.data_layout();
Expand Down
24 changes: 15 additions & 9 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ pub struct MiriMachine<'mir, 'tcx> {

impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
pub(crate) fn new(config: &MiriConfig, layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Self {
let local_crates = helpers::get_local_crates(layout_cx.tcx);
let tcx = layout_cx.tcx;
let local_crates = helpers::get_local_crates(tcx);
let layouts =
PrimitiveLayouts::new(layout_cx).expect("Couldn't get layouts of primitive types");
let profiler = config.measureme_out.as_ref().map(|out| {
Expand All @@ -486,10 +487,13 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
let rng = StdRng::seed_from_u64(config.seed.unwrap_or(0));
let borrow_tracker = config.borrow_tracker.map(|bt| bt.instanciate_global_state(config));
let data_race = config.data_race_detector.then(|| data_race::GlobalState::new(config));
// Determinine page size, stack address, and stack size.
// These values are mostly meaningless, but the stack address is also where we start
// allocating physical integer addresses for all allocations.
let page_size = if let Some(page_size) = config.page_size {
page_size
} else {
let target = &layout_cx.tcx.sess.target;
let target = &tcx.sess.target;
match target.arch.as_ref() {
"wasm32" | "wasm64" => 64 * 1024, // https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances
"aarch64" =>
Expand All @@ -504,10 +508,12 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
_ => 4 * 1024,
}
};
let stack_addr = page_size * 32;
let stack_size = page_size * 16;
// On 16bit targets, 32 pages is more than the entire address space!
let stack_addr = if tcx.pointer_size().bits() < 32 { page_size } else { page_size * 32 };
let stack_size =
if tcx.pointer_size().bits() < 32 { page_size * 4 } else { page_size * 16 };
MiriMachine {
tcx: layout_cx.tcx,
tcx,
borrow_tracker,
data_race,
intptrcast: RefCell::new(intptrcast::GlobalStateInner::new(config, stack_addr)),
Expand Down Expand Up @@ -971,7 +977,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
fn adjust_alloc_base_pointer(
ecx: &MiriInterpCx<'mir, 'tcx>,
ptr: Pointer<AllocId>,
) -> Pointer<Provenance> {
) -> InterpResult<'tcx, Pointer<Provenance>> {
if cfg!(debug_assertions) {
// The machine promises to never call us on thread-local or extern statics.
let alloc_id = ptr.provenance;
Expand All @@ -985,17 +991,17 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
_ => {}
}
}
let absolute_addr = intptrcast::GlobalStateInner::rel_ptr_to_addr(ecx, ptr);
let absolute_addr = intptrcast::GlobalStateInner::rel_ptr_to_addr(ecx, ptr)?;
let tag = if let Some(borrow_tracker) = &ecx.machine.borrow_tracker {
borrow_tracker.borrow_mut().base_ptr_tag(ptr.provenance, &ecx.machine)
} else {
// Value does not matter, SB is disabled
BorTag::default()
};
Pointer::new(
Ok(Pointer::new(
Provenance::Concrete { alloc_id: ptr.provenance, tag },
Size::from_bytes(absolute_addr),
)
))
}

#[inline(always)]
Expand Down
4 changes: 2 additions & 2 deletions src/shims/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
0 => {
// These are "mutable" allocations as we consider them to be owned by the callee.
let name_alloc =
this.allocate_str(&name, MiriMemoryKind::Rust.into(), Mutability::Mut);
this.allocate_str(&name, MiriMemoryKind::Rust.into(), Mutability::Mut)?;
let filename_alloc =
this.allocate_str(&filename, MiriMemoryKind::Rust.into(), Mutability::Mut);
this.allocate_str(&filename, MiriMemoryKind::Rust.into(), Mutability::Mut)?;

this.write_immediate(
name_alloc.to_ref(this),
Expand Down
2 changes: 1 addition & 1 deletion src/shims/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let this = self.eval_context_mut();

// First arg: message.
let msg = this.allocate_str(msg, MiriMemoryKind::Machine.into(), Mutability::Not);
let msg = this.allocate_str(msg, MiriMemoryKind::Machine.into(), Mutability::Not)?;

// Call the lang item.
let panic = this.tcx.lang_items().panic_fn().unwrap();
Expand Down
1 change: 0 additions & 1 deletion tests/pass-dep/shims/pthreads.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@ignore-target-windows: No libc on Windows
#![feature(cstr_from_bytes_until_nul)]
use std::ffi::{CStr, CString};
use std::thread;

Expand Down

0 comments on commit fb38aea

Please sign in to comment.