Freeze static memory of string constants.

This commit is contained in:
Scott Olson 2016-09-19 04:10:18 -06:00
parent 85cba42a7b
commit c679c71def
4 changed files with 31 additions and 4 deletions

View File

@ -217,11 +217,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
Char(c) => Value::ByVal(PrimVal::Char(c)),
Str(ref s) => {
let psize = self.memory.pointer_size();
// Create and freeze the allocation holding the characters.
let static_ptr = self.memory.allocate(s.len(), 1)?;
self.memory.write_bytes(static_ptr, s.as_bytes())?;
self.memory.freeze(static_ptr.alloc_id)?;
// Create an allocation to hold the fat pointer to the above char allocation.
// FIXME(solson): Introduce Value::ByValPair to remove this allocation.
let psize = self.memory.pointer_size();
let ptr = self.memory.allocate(psize * 2, psize)?;
let (ptr, extra) = self.get_fat_ptr(ptr);
self.memory.write_bytes(static_ptr, s.as_bytes())?;
self.memory.write_ptr(ptr, static_ptr)?;
self.memory.write_usize(extra, s.len() as u64)?;
Value::ByRef(ptr)
@ -230,6 +235,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
ByteStr(ref bs) => {
let ptr = self.memory.allocate(bs.len(), 1)?;
self.memory.write_bytes(ptr, bs)?;
self.memory.freeze(ptr.alloc_id)?;
Value::ByVal(PrimVal::AbstractPtr(ptr))
}

View File

@ -444,9 +444,12 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
/// Reading and writing
impl<'a, 'tcx> Memory<'a, 'tcx> {
pub fn freeze(&mut self, alloc_id: AllocId) -> EvalResult<'tcx, ()> {
self.get_mut(alloc_id)?.immutable = true;
// Never freeze the zero-sized allocation. If you do that, then getting a mutable handle to
// _any_ ZST becomes an error, since they all share the same allocation.
if alloc_id != ZST_ALLOC_ID {
self.get_mut(alloc_id)?.immutable = true;
}
Ok(())
}

View File

@ -0,0 +1,9 @@
use std::mem::transmute;
#[allow(mutable_transmutes)]
fn main() {
unsafe {
let s = "this is a test";
transmute::<&[u8], &mut [u8]>(s.as_bytes())[4] = 42; //~ ERROR: tried to modify constant memory
}
}

View File

@ -0,0 +1,9 @@
use std::mem::transmute;
#[allow(mutable_transmutes)]
fn main() {
unsafe {
let bs = b"this is a test";
transmute::<&[u8], &mut [u8]>(bs)[4] = 42; //~ ERROR: tried to modify constant memory
}
}