diff options
| author | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2017-08-28 14:08:55 +0200 |
|---|---|---|
| committer | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2017-08-28 14:08:55 +0200 |
| commit | ac7dfcac388991c69539ce47badce030fe160109 (patch) | |
| tree | 0b073eab47749d107850e7e6799792bfb86e5ba2 | |
| parent | 7355a1ea28a080e3d48287b208b9560bdf06aa0f (diff) | |
| download | rust-ac7dfcac388991c69539ce47badce030fe160109.tar.gz rust-ac7dfcac388991c69539ce47badce030fe160109.zip | |
Fix #313 by correctly copying relocations when doing overlapping copies
| -rw-r--r-- | src/librustc_mir/interpret/memory.rs | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 4c441460cb5..34de9596f24 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -1088,6 +1088,17 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { let dest = dest.to_ptr()?; self.check_relocation_edges(src, size)?; + // 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: Vec<_> = self.relocations(src, size)? + .map(|(&offset, &alloc_id)| { + // Update relocation offsets for the new positions in the destination allocation. + (offset + dest.offset - src.offset, alloc_id) + }) + .collect(); + let src_bytes = self.get_bytes_unchecked(src, size, align)?.as_ptr(); let dest_bytes = self.get_bytes_mut(dest, size, align)?.as_mut_ptr(); @@ -1113,7 +1124,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { } self.copy_undef_mask(src, dest, size)?; - self.copy_relocations(src, dest, size)?; + // copy back the relocations + self.get_mut(dest.alloc_id)?.relocations.extend(relocations); Ok(()) } @@ -1388,22 +1400,6 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { } Ok(()) } - - fn copy_relocations( - &mut self, - src: MemoryPointer, - dest: MemoryPointer, - size: u64, - ) -> EvalResult<'tcx> { - let relocations: Vec<_> = self.relocations(src, size)? - .map(|(&offset, &alloc_id)| { - // Update relocation offsets for the new positions in the destination allocation. - (offset + dest.offset - src.offset, alloc_id) - }) - .collect(); - self.get_mut(dest.alloc_id)?.relocations.extend(relocations); - Ok(()) - } } /// Undefined bytes |
