diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 7f7fd0e9c579..4f1531139322 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -430,7 +430,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec(); data_ctx.define(bytes.into_boxed_slice()); - for &(offset, alloc_id) in alloc.relocations().iter() { + for &(offset, alloc_id) in alloc.provenance().iter() { let addend = { let endianness = tcx.data_layout.endian; let offset = offset.bytes() as usize; diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index c0b8d21818f8..356c03ee3c18 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -127,7 +127,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { // // We could remove this hack whenever we decide to drop macOS 10.10 support. if self.tcx.sess.target.options.is_like_osx { - // The `inspect` method is okay here because we checked relocations, and + // The `inspect` method is okay here because we checked for provenance, and // because we are doing this access to inspect the final interpreter state // (not as part of the interpreter execution). // @@ -296,17 +296,17 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAllocation<'tcx>) -> RValue<'gcc> { let alloc = alloc.inner(); - let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1); + let mut llvals = Vec::with_capacity(alloc.provenance().len() + 1); let dl = cx.data_layout(); let pointer_size = dl.pointer_size.bytes() as usize; let mut next_offset = 0; - for &(offset, alloc_id) in alloc.relocations().iter() { + for &(offset, alloc_id) in alloc.provenance().iter() { let offset = offset.bytes(); assert_eq!(offset as usize as u64, offset); let offset = offset as usize; if offset > next_offset { - // This `inspect` is okay since we have checked that it is not within a relocation, it + // This `inspect` is okay since we have checked that it is not within a pointer with provenance, it // is within the bounds of the allocation, and it doesn't affect interpreter execution // (we inspect the result after interpreter execution). Any undef byte is replaced with // some arbitrary byte value. @@ -319,7 +319,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl read_target_uint( dl.endian, // This `inspect` is okay since it is within the bounds of the allocation, it doesn't // affect interpreter execution (we inspect the result after interpreter execution), - // and we properly interpret the relocation as a relocation pointer offset. + // and we properly interpret the provenance as a relocation pointer offset. alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)), ) .expect("const_alloc_to_llvm: could not read relocation pointer") @@ -336,7 +336,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl } if alloc.len() >= next_offset { let range = next_offset..alloc.len(); - // This `inspect` is okay since we have check that it is after all relocations, it is + // This `inspect` is okay since we have check that it is after all provenance, it is // within the bounds of the allocation, and it doesn't affect interpreter execution (we // inspect the result after interpreter execution). Any undef byte is replaced with some // arbitrary byte value. diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index f41ff325590a..d3e33da27993 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -27,12 +27,12 @@ use tracing::debug; pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<'_>) -> &'ll Value { let alloc = alloc.inner(); - let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1); + let mut llvals = Vec::with_capacity(alloc.provenance().len() + 1); let dl = cx.data_layout(); let pointer_size = dl.pointer_size.bytes() as usize; - // Note: this function may call `inspect_with_uninit_and_ptr_outside_interpreter`, - // so `range` must be within the bounds of `alloc` and not contain or overlap a relocation. + // Note: this function may call `inspect_with_uninit_and_ptr_outside_interpreter`, so `range` + // must be within the bounds of `alloc` and not contain or overlap a pointer provenance. fn append_chunks_of_init_and_uninit_bytes<'ll, 'a, 'b>( llvals: &mut Vec<&'ll Value>, cx: &'a CodegenCx<'ll, 'b>, @@ -79,12 +79,12 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation< } let mut next_offset = 0; - for &(offset, alloc_id) in alloc.relocations().iter() { + for &(offset, alloc_id) in alloc.provenance().iter() { let offset = offset.bytes(); assert_eq!(offset as usize as u64, offset); let offset = offset as usize; if offset > next_offset { - // This `inspect` is okay since we have checked that it is not within a relocation, it + // This `inspect` is okay since we have checked that there is no provenance, it // is within the bounds of the allocation, and it doesn't affect interpreter execution // (we inspect the result after interpreter execution). append_chunks_of_init_and_uninit_bytes(&mut llvals, cx, alloc, next_offset..offset); @@ -93,7 +93,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation< dl.endian, // This `inspect` is okay since it is within the bounds of the allocation, it doesn't // affect interpreter execution (we inspect the result after interpreter execution), - // and we properly interpret the relocation as a relocation pointer offset. + // and we properly interpret the provenance as a relocation pointer offset. alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)), ) .expect("const_alloc_to_llvm: could not read relocation pointer") @@ -121,7 +121,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation< } if alloc.len() >= next_offset { let range = next_offset..alloc.len(); - // This `inspect` is okay since we have check that it is after all relocations, it is + // This `inspect` is okay since we have check that it is after all provenance, it is // within the bounds of the allocation, and it doesn't affect interpreter execution (we // inspect the result after interpreter execution). append_chunks_of_init_and_uninit_bytes(&mut llvals, cx, alloc, range); @@ -479,7 +479,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { // // We could remove this hack whenever we decide to drop macOS 10.10 support. if self.tcx.sess.target.is_like_osx { - // The `inspect` method is okay here because we checked relocations, and + // The `inspect` method is okay here because we checked for provenance, and // because we are doing this access to inspect the final interpreter state // (not as part of the interpreter execution). // @@ -487,7 +487,7 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { // happens to be zero. Instead, we should only check the value of defined bytes // and set all undefined bytes to zero if this allocation is headed for the // BSS. - let all_bytes_are_zero = alloc.relocations().is_empty() + let all_bytes_are_zero = alloc.provenance().is_empty() && alloc .inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()) .iter() @@ -511,9 +511,9 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { section.as_str().as_ptr().cast(), section.as_str().len() as c_uint, ); - assert!(alloc.relocations().is_empty()); + assert!(alloc.provenance().is_empty()); - // The `inspect` method is okay here because we checked relocations, and + // The `inspect` method is okay here because we checked for provenance, and // because we are doing this access to inspect the final interpreter state (not // as part of the interpreter execution). let bytes = diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 376b8872c90a..66ab3f15716f 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -134,7 +134,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval: alloc.mutability = Mutability::Not; }; // link the alloc id to the actual allocation - leftover_allocations.extend(alloc.relocations().iter().map(|&(_, alloc_id)| alloc_id)); + leftover_allocations.extend(alloc.provenance().iter().map(|&(_, alloc_id)| alloc_id)); let alloc = tcx.intern_const_alloc(alloc); tcx.set_alloc_id_memory(alloc_id, alloc); None @@ -191,10 +191,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory return Ok(true); }; - // If there are no relocations in this allocation, it does not contain references + // If there is no provenance in this allocation, it does not contain references // that point to another allocation, and we can avoid the interning walk. if let Some(alloc) = self.ecx.get_ptr_alloc(mplace.ptr, size, align)? { - if !alloc.has_relocations() { + if !alloc.has_provenance() { return Ok(false); } } else { @@ -233,8 +233,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory } fn visit_value(&mut self, mplace: &MPlaceTy<'tcx>) -> InterpResult<'tcx> { - // Handle Reference types, as these are the only relocations supported by const eval. - // Raw pointers (and boxes) are handled by the `leftover_relocations` logic. + // Handle Reference types, as these are the only types with provenance supported by const eval. + // Raw pointers (and boxes) are handled by the `leftover_allocations` logic. let tcx = self.ecx.tcx; let ty = mplace.layout.ty; if let ty::Ref(_, referenced_ty, ref_mutability) = *ty.kind() { @@ -410,7 +410,7 @@ pub fn intern_const_alloc_recursive< // references and a `leftover_allocations` set (where we only have a todo-list here). // So we hand-roll the interning logic here again. match intern_kind { - // Statics may contain mutable allocations even behind relocations. + // Statics may point to mutable allocations. // Even for immutable statics it would be ok to have mutable allocations behind // raw pointers, e.g. for `static FOO: *const AtomicUsize = &AtomicUsize::new(42)`. InternKind::Static(_) => {} @@ -441,7 +441,7 @@ pub fn intern_const_alloc_recursive< } let alloc = tcx.intern_const_alloc(alloc); tcx.set_alloc_id_memory(alloc_id, alloc); - for &(_, alloc_id) in alloc.inner().relocations().iter() { + for &(_, alloc_id) in alloc.inner().provenance().iter() { if leftover_allocations.insert(alloc_id) { todo.push(alloc_id); } diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 6bed8a7a0077..ae7c0347efc0 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -326,7 +326,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// cache the result. (This relies on `AllocMap::get_or` being able to add the /// owned allocation to the map even when the map is shared.) /// - /// This must only fail if `alloc` contains relocations. + /// This must only fail if `alloc` contains provenance. fn adjust_allocation<'b>( ecx: &InterpCx<'mir, 'tcx, Self>, id: AllocId, diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index c4e937702929..f84c6017dbf6 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -214,7 +214,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.allocate_raw_ptr(alloc, kind).unwrap() } - /// This can fail only of `alloc` contains relocations. + /// This can fail only of `alloc` contains provenance. pub fn allocate_raw_ptr( &mut self, alloc: Allocation, @@ -794,10 +794,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { todo.extend(static_roots); while let Some(id) = todo.pop() { if reachable.insert(id) { - // This is a new allocation, add its relocations to `todo`. + // This is a new allocation, add the allocation it points to to `todo`. if let Some((_, alloc)) = self.memory.alloc_map.get(id) { todo.extend( - alloc.relocations().values().filter_map(|prov| prov.get_alloc_id()), + alloc.provenance().values().filter_map(|prov| prov.get_alloc_id()), ); } } @@ -833,7 +833,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a, allocs_to_print: &mut VecDeque, alloc: &Allocation, ) -> std::fmt::Result { - for alloc_id in alloc.relocations().values().filter_map(|prov| prov.get_alloc_id()) { + for alloc_id in alloc.provenance().values().filter_map(|prov| prov.get_alloc_id()) { allocs_to_print.push_back(alloc_id); } write!(fmt, "{}", display_allocation(tcx, alloc)) @@ -960,9 +960,9 @@ impl<'tcx, 'a, Prov: Provenance, Extra> AllocRef<'a, 'tcx, Prov, Extra> { .map_err(|e| e.to_interp_error(self.alloc_id))?) } - /// Returns whether the allocation has relocations for the entire range of the `AllocRef`. - pub(crate) fn has_relocations(&self) -> bool { - self.alloc.has_relocations(&self.tcx, self.range) + /// Returns whether the allocation has provenance anywhere in the range of the `AllocRef`. + pub(crate) fn has_provenance(&self) -> bool { + self.alloc.range_has_provenance(&self.tcx, self.range) } } @@ -1078,17 +1078,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(()); }; - // This checks relocation edges on the src, which needs to happen before - // `prepare_relocation_copy`. + // This checks provenance edges on the src, which needs to happen before + // `prepare_provenance_copy`. let src_bytes = src_alloc .get_bytes_with_uninit_and_ptr(&tcx, src_range) .map_err(|e| e.to_interp_error(src_alloc_id))? .as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation - // first copy the relocations to a temporary buffer, because - // `get_bytes_mut` will clear the relocations, which is correct, - // since we don't want to keep any relocations at the target. - let relocations = - src_alloc.prepare_relocation_copy(self, src_range, dest_offset, num_copies); + // first copy the provenance to a temporary buffer, because + // `get_bytes_mut` will clear the provenance, which is correct, + // since we don't want to keep any provenance at the target. + let provenance = + src_alloc.prepare_provenance_copy(self, src_range, dest_offset, num_copies); // Prepare a copy of the initialization mask. let compressed = src_alloc.compress_uninit_range(src_range); @@ -1117,7 +1117,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { dest_alloc .write_uninit(&tcx, dest_range) .map_err(|e| e.to_interp_error(dest_alloc_id))?; - // We can forget about the relocations, this is all not initialized anyway. + // We can forget about the provenance, this is all not initialized anyway. return Ok(()); } @@ -1161,8 +1161,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { alloc_range(dest_offset, size), // just a single copy (i.e., not full `dest_range`) num_copies, ); - // copy the relocations to the destination - dest_alloc.mark_relocation_range(relocations); + // copy the provenance to the destination + dest_alloc.mark_provenance_range(provenance); Ok(()) } diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 3f618106525c..cc39e434225f 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -34,11 +34,11 @@ pub struct Allocation { /// The actual bytes of the allocation. /// Note that the bytes of a pointer represent the offset of the pointer. bytes: Box<[u8]>, - /// Maps from byte addresses to extra data for each pointer. + /// Maps from byte addresses to extra provenance data for each pointer. /// Only the first byte of a pointer is inserted into the map; i.e., /// every entry in this map applies to `pointer_size` consecutive bytes starting /// at the given offset. - relocations: Relocations, + provenance: ProvenanceMap, /// Denotes which part of this allocation is initialized. init_mask: InitMask, /// The alignment of the allocation to detect unaligned reads. @@ -84,7 +84,7 @@ impl hash::Hash for Allocation { } // Hash the other fields as usual. - self.relocations.hash(state); + self.provenance.hash(state); self.init_mask.hash(state); self.align.hash(state); self.mutability.hash(state); @@ -211,7 +211,7 @@ impl Allocation { let size = Size::from_bytes(bytes.len()); Self { bytes, - relocations: Relocations::new(), + provenance: ProvenanceMap::new(), init_mask: InitMask::new(size, true), align, mutability, @@ -246,7 +246,7 @@ impl Allocation { let bytes = unsafe { bytes.assume_init() }; Ok(Allocation { bytes, - relocations: Relocations::new(), + provenance: ProvenanceMap::new(), init_mask: InitMask::new(size, false), align, mutability: Mutability::Mut, @@ -266,22 +266,22 @@ impl Allocation { ) -> Result, Err> { // Compute new pointer provenance, which also adjusts the bytes. let mut bytes = self.bytes; - let mut new_relocations = Vec::with_capacity(self.relocations.0.len()); + let mut new_provenance = Vec::with_capacity(self.provenance.0.len()); let ptr_size = cx.data_layout().pointer_size.bytes_usize(); let endian = cx.data_layout().endian; - for &(offset, alloc_id) in self.relocations.iter() { + for &(offset, alloc_id) in self.provenance.iter() { let idx = offset.bytes_usize(); let ptr_bytes = &mut bytes[idx..idx + ptr_size]; let bits = read_target_uint(endian, ptr_bytes).unwrap(); let (ptr_prov, ptr_offset) = adjust_ptr(Pointer::new(alloc_id, Size::from_bytes(bits)))?.into_parts(); write_target_uint(endian, ptr_bytes, ptr_offset.bytes().into()).unwrap(); - new_relocations.push((offset, ptr_prov)); + new_provenance.push((offset, ptr_prov)); } // Create allocation. Ok(Allocation { bytes, - relocations: Relocations::from_presorted(new_relocations), + provenance: ProvenanceMap::from_presorted(new_provenance), init_mask: self.init_mask, align: self.align, mutability: self.mutability, @@ -300,8 +300,8 @@ impl Allocation { Size::from_bytes(self.len()) } - /// Looks at a slice which may describe uninitialized bytes or describe a relocation. This differs - /// from `get_bytes_with_uninit_and_ptr` in that it does no relocation checks (even on the + /// Looks at a slice which may contain uninitialized bytes or provenance. This differs + /// from `get_bytes_with_uninit_and_ptr` in that it does no provenance checks (even on the /// edges) at all. /// This must not be used for reads affecting the interpreter execution. pub fn inspect_with_uninit_and_ptr_outside_interpreter(&self, range: Range) -> &[u8] { @@ -313,23 +313,23 @@ impl Allocation { &self.init_mask } - /// Returns the relocation list. - pub fn relocations(&self) -> &Relocations { - &self.relocations + /// Returns the provenance map. + pub fn provenance(&self) -> &ProvenanceMap { + &self.provenance } } /// Byte accessors. impl Allocation { /// This is the entirely abstraction-violating way to just grab the raw bytes without - /// caring about relocations. It just deduplicates some code between `read_scalar` + /// caring about provenance. It just deduplicates some code between `read_scalar` /// and `get_bytes_internal`. fn get_bytes_even_more_internal(&self, range: AllocRange) -> &[u8] { &self.bytes[range.start.bytes_usize()..range.end().bytes_usize()] } /// The last argument controls whether we error out when there are uninitialized or pointer - /// bytes. However, we *always* error when there are relocations overlapping the edges of the + /// bytes. However, we *always* error when there is provenance overlapping the edges of the /// range. /// /// You should never call this, call `get_bytes` or `get_bytes_with_uninit_and_ptr` instead, @@ -347,10 +347,10 @@ impl Allocation { ) -> AllocResult<&[u8]> { if check_init_and_ptr { self.check_init(range)?; - self.check_relocations(cx, range)?; + self.check_provenance(cx, range)?; } else { - // We still don't want relocations on the *edges*. - self.check_relocation_edges(cx, range)?; + // We still don't want provenance on the *edges*. + self.check_provenance_edges(cx, range)?; } Ok(self.get_bytes_even_more_internal(range)) @@ -368,7 +368,7 @@ impl Allocation { } /// It is the caller's responsibility to handle uninitialized and pointer bytes. - /// However, this still checks that there are no relocations on the *edges*. + /// However, this still checks that there is no provenance on the *edges*. /// /// It is the caller's responsibility to check bounds and alignment beforehand. #[inline] @@ -380,7 +380,7 @@ impl Allocation { self.get_bytes_internal(cx, range, false) } - /// Just calling this already marks everything as defined and removes relocations, + /// Just calling this already marks everything as defined and removes provenance, /// so be sure to actually put data there! /// /// It is the caller's responsibility to check bounds and alignment beforehand. @@ -392,7 +392,7 @@ impl Allocation { range: AllocRange, ) -> AllocResult<&mut [u8]> { self.mark_init(range, true); - self.clear_relocations(cx, range)?; + self.clear_provenance(cx, range)?; Ok(&mut self.bytes[range.start.bytes_usize()..range.end().bytes_usize()]) } @@ -404,7 +404,7 @@ impl Allocation { range: AllocRange, ) -> AllocResult<*mut [u8]> { self.mark_init(range, true); - self.clear_relocations(cx, range)?; + self.clear_provenance(cx, range)?; assert!(range.end().bytes_usize() <= self.bytes.len()); // need to do our own bounds-check let begin_ptr = self.bytes.as_mut_ptr().wrapping_add(range.start.bytes_usize()); @@ -415,7 +415,7 @@ impl Allocation { /// Reading and writing. impl Allocation { - /// Validates that this memory range is initiailized and contains no relocations. + /// Validates that this memory range is initiailized and contains no provenance. pub fn check_bytes(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult { // This implicitly does all the checking we are asking for. self.get_bytes(cx, range)?; @@ -447,17 +447,17 @@ impl Allocation { return Err(AllocError::InvalidUninitBytes(None)); } - // If we are doing a pointer read, and there is a relocation exactly where we - // are reading, then we can put data and relocation back together and return that. - if read_provenance && let Some(&prov) = self.relocations.get(&range.start) { - // We already checked init and relocations, so we can use this function. + // If we are doing a pointer read, and there is provenance exactly where we + // are reading, then we can put data and provenance back together and return that. + if read_provenance && let Some(&prov) = self.provenance.get(&range.start) { + // We already checked init and provenance, so we can use this function. let bytes = self.get_bytes_even_more_internal(range); let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap(); let ptr = Pointer::new(prov, Size::from_bytes(bits)); return Ok(Scalar::from_pointer(ptr, cx)); } - // If we are *not* reading a pointer, and we can just ignore relocations, + // If we are *not* reading a pointer, and we can just ignore provenance, // then do exactly that. if !read_provenance && Prov::OFFSET_IS_ADDR { // We just strip provenance. @@ -469,8 +469,8 @@ impl Allocation { // It's complicated. Better make sure there is no provenance anywhere. // FIXME: If !OFFSET_IS_ADDR, this is the best we can do. But if OFFSET_IS_ADDR, then // `read_pointer` is true and we ideally would distinguish the following two cases: - // - The entire `range` is covered by 2 relocations for the same provenance. - // Then we should return a pointer with that provenance. + // - The entire `range` is covered by the same provenance, stored in two separate entries of + // the provenance map. Then we should return a pointer with that provenance. // - The range has inhomogeneous provenance. Then we should return just the // underlying bits. let bytes = self.get_bytes(cx, range)?; @@ -508,9 +508,9 @@ impl Allocation { let dst = self.get_bytes_mut(cx, range)?; write_target_uint(endian, dst, bytes).unwrap(); - // See if we have to also write a relocation. + // See if we have to also store some provenance. if let Some(provenance) = provenance { - self.relocations.0.insert(range.start, provenance); + self.provenance.0.insert(range.start, provenance); } Ok(()) @@ -519,64 +519,64 @@ impl Allocation { /// Write "uninit" to the given memory range. pub fn write_uninit(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult { self.mark_init(range, false); - self.clear_relocations(cx, range)?; + self.clear_provenance(cx, range)?; return Ok(()); } } -/// Relocations. +/// Provenance. impl Allocation { - /// Returns all relocations overlapping with the given pointer-offset pair. - fn get_relocations(&self, cx: &impl HasDataLayout, range: AllocRange) -> &[(Size, Prov)] { + /// Returns all provenance overlapping with the given pointer-offset pair. + fn range_get_provenance(&self, cx: &impl HasDataLayout, range: AllocRange) -> &[(Size, Prov)] { // We have to go back `pointer_size - 1` bytes, as that one would still overlap with // the beginning of this range. let start = range.start.bytes().saturating_sub(cx.data_layout().pointer_size.bytes() - 1); - self.relocations.range(Size::from_bytes(start)..range.end()) + self.provenance.range(Size::from_bytes(start)..range.end()) } - /// Returns whether this allocation has relocations overlapping with the given range. + /// Returns whether this allocation has progrnance overlapping with the given range. /// - /// Note: this function exists to allow `get_relocations` to be private, in order to somewhat - /// limit access to relocations outside of the `Allocation` abstraction. + /// Note: this function exists to allow `range_get_provenance` to be private, in order to somewhat + /// limit access to provenance outside of the `Allocation` abstraction. /// - pub fn has_relocations(&self, cx: &impl HasDataLayout, range: AllocRange) -> bool { - !self.get_relocations(cx, range).is_empty() + pub fn range_has_provenance(&self, cx: &impl HasDataLayout, range: AllocRange) -> bool { + !self.range_get_provenance(cx, range).is_empty() } - /// Checks that there are no relocations overlapping with the given range. + /// Checks that there is no provenance overlapping with the given range. #[inline(always)] - fn check_relocations(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult { - if self.has_relocations(cx, range) { Err(AllocError::ReadPointerAsBytes) } else { Ok(()) } + fn check_provenance(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult { + if self.range_has_provenance(cx, range) { Err(AllocError::ReadPointerAsBytes) } else { Ok(()) } } - /// Removes all relocations inside the given range. - /// If there are relocations overlapping with the edges, they + /// Removes all provenance inside the given range. + /// If there is provenance overlapping with the edges, it /// are removed as well *and* the bytes they cover are marked as /// uninitialized. This is a somewhat odd "spooky action at a distance", /// but it allows strictly more code to run than if we would just error /// immediately in that case. - fn clear_relocations(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult + fn clear_provenance(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult where Prov: Provenance, { - // Find the start and end of the given range and its outermost relocations. + // Find the start and end of the given range and its outermost provenance. let (first, last) = { - // Find all relocations overlapping the given range. - let relocations = self.get_relocations(cx, range); - if relocations.is_empty() { + // Find all provenance overlapping the given range. + let provenance = self.range_get_provenance(cx, range); + if provenance.is_empty() { return Ok(()); } ( - relocations.first().unwrap().0, - relocations.last().unwrap().0 + cx.data_layout().pointer_size, + provenance.first().unwrap().0, + provenance.last().unwrap().0 + cx.data_layout().pointer_size, ) }; let start = range.start; let end = range.end(); - // We need to handle clearing the relocations from parts of a pointer. - // FIXME: Miri should preserve partial relocations; see + // We need to handle clearing the provenance from parts of a pointer. + // FIXME: Miri should preserve partial provenance; see // https://github.com/rust-lang/miri/issues/2181. if first < start { if Prov::ERR_ON_PARTIAL_PTR_OVERWRITE { @@ -599,41 +599,40 @@ impl Allocation { self.init_mask.set_range(end, last, false); } - // Forget all the relocations. - // Since relocations do not overlap, we know that removing until `last` (exclusive) is fine, - // i.e., this will not remove any other relocations just after the ones we care about. - self.relocations.0.remove_range(first..last); + // Forget all the provenance. + // Since provenance do not overlap, we know that removing until `last` (exclusive) is fine, + // i.e., this will not remove any other provenance just after the ones we care about. + self.provenance.0.remove_range(first..last); Ok(()) } - /// Errors if there are relocations overlapping with the edges of the - /// given memory range. + /// Errors if there is provenance overlapping with the edges of the given memory range. #[inline] - fn check_relocation_edges(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult { - self.check_relocations(cx, alloc_range(range.start, Size::ZERO))?; - self.check_relocations(cx, alloc_range(range.end(), Size::ZERO))?; + fn check_provenance_edges(&self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult { + self.check_provenance(cx, alloc_range(range.start, Size::ZERO))?; + self.check_provenance(cx, alloc_range(range.end(), Size::ZERO))?; Ok(()) } } -/// "Relocations" stores the provenance information of pointers stored in memory. +/// Stores the provenance information of pointers stored in memory. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] -pub struct Relocations(SortedMap); +pub struct ProvenanceMap(SortedMap); -impl Relocations { +impl ProvenanceMap { pub fn new() -> Self { - Relocations(SortedMap::new()) + ProvenanceMap(SortedMap::new()) } - // The caller must guarantee that the given relocations are already sorted + // The caller must guarantee that the given provenance list is already sorted // by address and contain no duplicates. pub fn from_presorted(r: Vec<(Size, Prov)>) -> Self { - Relocations(SortedMap::from_presorted_elements(r)) + ProvenanceMap(SortedMap::from_presorted_elements(r)) } } -impl Deref for Relocations { +impl Deref for ProvenanceMap { type Target = SortedMap; fn deref(&self) -> &Self::Target { @@ -641,36 +640,36 @@ impl Deref for Relocations { } } -/// A partial, owned list of relocations to transfer into another allocation. +/// A partial, owned list of provenance to transfer into another allocation. /// /// Offsets are already adjusted to the destination allocation. -pub struct AllocationRelocations { - dest_relocations: Vec<(Size, Prov)>, +pub struct AllocationProvenance { + dest_provenance: Vec<(Size, Prov)>, } impl Allocation { - pub fn prepare_relocation_copy( + pub fn prepare_provenance_copy( &self, cx: &impl HasDataLayout, src: AllocRange, dest: Size, count: u64, - ) -> AllocationRelocations { - let relocations = self.get_relocations(cx, src); - if relocations.is_empty() { - return AllocationRelocations { dest_relocations: Vec::new() }; + ) -> AllocationProvenance { + let provenance = self.range_get_provenance(cx, src); + if provenance.is_empty() { + return AllocationProvenance { dest_provenance: Vec::new() }; } let size = src.size; - let mut new_relocations = Vec::with_capacity(relocations.len() * (count as usize)); + let mut new_provenance = Vec::with_capacity(provenance.len() * (count as usize)); // If `count` is large, this is rather wasteful -- we are allocating a big array here, which // is mostly filled with redundant information since it's just N copies of the same `Prov`s - // at slightly adjusted offsets. The reason we do this is so that in `mark_relocation_range` + // at slightly adjusted offsets. The reason we do this is so that in `mark_provenance_range` // we can use `insert_presorted`. That wouldn't work with an `Iterator` that just produces - // the right sequence of relocations for all N copies. + // the right sequence of provenance for all N copies. for i in 0..count { - new_relocations.extend(relocations.iter().map(|&(offset, reloc)| { + new_provenance.extend(provenance.iter().map(|&(offset, reloc)| { // compute offset for current repetition let dest_offset = dest + size * i; // `Size` operations ( @@ -681,17 +680,17 @@ impl Allocation { })); } - AllocationRelocations { dest_relocations: new_relocations } + AllocationProvenance { dest_provenance: new_provenance } } - /// Applies a relocation copy. - /// The affected range, as defined in the parameters to `prepare_relocation_copy` is expected - /// to be clear of relocations. + /// Applies a provenance copy. + /// The affected range, as defined in the parameters to `prepare_provenance_copy` is expected + /// to be clear of provenance. /// /// This is dangerous to use as it can violate internal `Allocation` invariants! /// It only exists to support an efficient implementation of `mem_copy_repeatedly`. - pub fn mark_relocation_range(&mut self, relocations: AllocationRelocations) { - self.relocations.0.insert_presorted(relocations.dest_relocations); + pub fn mark_provenance_range(&mut self, provenance: AllocationProvenance) { + self.provenance.0.insert_presorted(provenance.dest_provenance); } } diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 93fe7e63710b..0fc1217d5719 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -128,7 +128,7 @@ pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar}; pub use self::allocation::{ alloc_range, AllocRange, Allocation, ConstAllocation, InitChunk, InitChunkIter, InitMask, - Relocations, + ProvenanceMap, }; pub use self::pointer::{Pointer, PointerArithmetic, Provenance}; diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index ba56c5267df0..1ba16025e321 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -130,9 +130,7 @@ pub enum Scalar { /// The raw bytes of a simple value. Int(ScalarInt), - /// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of - /// relocations, but a `Scalar` is only large enough to contain one, so we just represent the - /// relocation and its associated offset together as a `Pointer` here. + /// A pointer. /// /// We also store the size of the pointer, such that a `Scalar` always knows how big it is. /// The size is always the pointer size of the current target, but this is not information diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9da9b4e91f64..4e886ff15921 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2692,8 +2692,8 @@ fn pretty_print_const_value<'tcx>( match inner.kind() { ty::Slice(t) => { if *t == u8_type { - // The `inspect` here is okay since we checked the bounds, and there are - // no relocations (we have an active slice reference here). We don't use + // The `inspect` here is okay since we checked the bounds, and `u8` carries + // no provenance (we have an active slice reference here). We don't use // this result to affect interpreter execution. let byte_str = data .inner() @@ -2703,8 +2703,8 @@ fn pretty_print_const_value<'tcx>( } } ty::Str => { - // The `inspect` here is okay since we checked the bounds, and there are no - // relocations (we have an active `str` reference here). We don't use this + // The `inspect` here is okay since we checked the bounds, and `str` carries + // no provenance (we have an active `str` reference here). We don't use this // result to affect interpreter execution. let slice = data .inner() diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 0ce41337b910..cd566681edf2 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -676,7 +676,7 @@ pub fn write_allocations<'tcx>( fn alloc_ids_from_alloc( alloc: ConstAllocation<'_>, ) -> impl DoubleEndedIterator + '_ { - alloc.inner().relocations().values().map(|id| *id) + alloc.inner().provenance().values().map(|id| *id) } fn alloc_ids_from_const_val(val: ConstValue<'_>) -> impl Iterator + '_ { @@ -778,7 +778,7 @@ pub fn write_allocations<'tcx>( /// If the allocation is small enough to fit into a single line, no start address is given. /// After the hex dump, an ascii dump follows, replacing all unprintable characters (control /// characters or characters whose value is larger than 127) with a `.` -/// This also prints relocations adequately. +/// This also prints provenance adequately. pub fn display_allocation<'a, 'tcx, Prov, Extra>( tcx: TyCtxt<'tcx>, alloc: &'a Allocation, @@ -873,34 +873,34 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>( if i != line_start { write!(w, " ")?; } - if let Some(&prov) = alloc.relocations().get(&i) { - // Memory with a relocation must be defined + if let Some(&prov) = alloc.provenance().get(&i) { + // Memory with provenance must be defined assert!(alloc.init_mask().is_range_initialized(i, i + ptr_size).is_ok()); let j = i.bytes_usize(); let offset = alloc .inspect_with_uninit_and_ptr_outside_interpreter(j..j + ptr_size.bytes_usize()); let offset = read_target_uint(tcx.data_layout.endian, offset).unwrap(); let offset = Size::from_bytes(offset); - let relocation_width = |bytes| bytes * 3; + let provenance_width = |bytes| bytes * 3; let ptr = Pointer::new(prov, offset); let mut target = format!("{:?}", ptr); - if target.len() > relocation_width(ptr_size.bytes_usize() - 1) { + if target.len() > provenance_width(ptr_size.bytes_usize() - 1) { // This is too long, try to save some space. target = format!("{:#?}", ptr); } if ((i - line_start) + ptr_size).bytes_usize() > BYTES_PER_LINE { - // This branch handles the situation where a relocation starts in the current line + // This branch handles the situation where a provenance starts in the current line // but ends in the next one. let remainder = Size::from_bytes(BYTES_PER_LINE) - (i - line_start); let overflow = ptr_size - remainder; - let remainder_width = relocation_width(remainder.bytes_usize()) - 2; - let overflow_width = relocation_width(overflow.bytes_usize() - 1) + 1; + let remainder_width = provenance_width(remainder.bytes_usize()) - 2; + let overflow_width = provenance_width(overflow.bytes_usize() - 1) + 1; ascii.push('╾'); for _ in 0..remainder.bytes() - 1 { ascii.push('─'); } if overflow_width > remainder_width && overflow_width >= target.len() { - // The case where the relocation fits into the part in the next line + // The case where the provenance fits into the part in the next line write!(w, "╾{0:─^1$}", "", remainder_width)?; line_start = write_allocation_newline(w, line_start, &ascii, pos_width, prefix)?; @@ -921,11 +921,11 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>( i += ptr_size; continue; } else { - // This branch handles a relocation that starts and ends in the current line. - let relocation_width = relocation_width(ptr_size.bytes_usize() - 1); - oversized_ptr(&mut target, relocation_width); + // This branch handles a provenance that starts and ends in the current line. + let provenance_width = provenance_width(ptr_size.bytes_usize() - 1); + oversized_ptr(&mut target, provenance_width); ascii.push('╾'); - write!(w, "╾{0:─^1$}╼", target, relocation_width)?; + write!(w, "╾{0:─^1$}╼", target, provenance_width)?; for _ in 0..ptr_size.bytes() - 2 { ascii.push('─'); } @@ -935,7 +935,7 @@ fn write_allocation_bytes<'tcx, Prov: Provenance, Extra>( } else if alloc.init_mask().is_range_initialized(i, i + Size::from_bytes(1)).is_ok() { let j = i.bytes_usize(); - // Checked definedness (and thus range) and relocations. This access also doesn't + // Checked definedness (and thus range) and provenance. This access also doesn't // influence interpreter execution but is only for debugging. let c = alloc.inspect_with_uninit_and_ptr_outside_interpreter(j..j + 1)[0]; write!(w, "{:02x}", c)?; diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index cd00b26b8def..d1c0d62ac6e0 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -113,7 +113,7 @@ impl<'a> HashStable> for mir::interpret::AllocId { } // `Relocations` with default type parameters is a sorted map. -impl<'a, Prov> HashStable> for mir::interpret::Relocations +impl<'a, Prov> HashStable> for mir::interpret::ProvenanceMap where Prov: HashStable>, { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 82ef16a7f72f..5f5540495e93 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -461,7 +461,7 @@ fn collect_items_rec<'tcx>( recursion_depth_reset = None; if let Ok(alloc) = tcx.eval_static_initializer(def_id) { - for &id in alloc.inner().relocations().values() { + for &id in alloc.inner().provenance().values() { collect_miri(tcx, id, &mut neighbors); } } @@ -1424,7 +1424,7 @@ fn collect_miri<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIte } GlobalAlloc::Memory(alloc) => { trace!("collecting {:?} with {:#?}", alloc_id, alloc); - for &inner in alloc.inner().relocations().values() { + for &inner in alloc.inner().provenance().values() { rustc_data_structures::stack::ensure_sufficient_stack(|| { collect_miri(tcx, inner, output); }); @@ -1463,7 +1463,7 @@ fn collect_const_value<'tcx>( match value { ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => collect_miri(tcx, ptr.provenance, output), ConstValue::Slice { data: alloc, start: _, end: _ } | ConstValue::ByRef { alloc, .. } => { - for &id in alloc.inner().relocations().values() { + for &id in alloc.inner().provenance().values() { collect_miri(tcx, id, output); } } diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index fb675212e3ff..f8d839b64838 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -542,13 +542,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) { // For the wasm32 target statics with `#[link_section]` are placed into custom // sections of the final output file, but this isn't link custom sections of // other executable formats. Namely we can only embed a list of bytes, - // nothing with pointers to anything else or relocations. If any relocation - // show up, reject them here. + // nothing with provenance (pointers to anything else). If any provenance + // show up, reject it here. // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is // the consumer's responsibility to ensure all bytes that have been read // have defined values. if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id()) - && alloc.inner().relocations().len() != 0 + && alloc.inner().provenance().len() != 0 { let msg = "statics with a custom `#[link_section]` must be a \ simple list of bytes on the wasm target with no \