about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-08-28 14:08:55 +0200
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-08-28 14:08:55 +0200
commitac7dfcac388991c69539ce47badce030fe160109 (patch)
tree0b073eab47749d107850e7e6799792bfb86e5ba2
parent7355a1ea28a080e3d48287b208b9560bdf06aa0f (diff)
downloadrust-ac7dfcac388991c69539ce47badce030fe160109.tar.gz
rust-ac7dfcac388991c69539ce47badce030fe160109.zip
Fix #313 by correctly copying relocations when doing overlapping copies
-rw-r--r--src/librustc_mir/interpret/memory.rs30
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