summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-08-08 18:53:19 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-08-08 18:53:19 +0800
commitc1fe76bfbe373207c531519a9345cafb4166c667 (patch)
tree2eb8bde99296bfe5ea15af078fcc0c90c56cd02e /tools
parentb01ccc9f2b5bd051535a9757756091c3680940a2 (diff)
downloadmrust-c1fe76bfbe373207c531519a9345cafb4166c667.tar.gz
Standalone MIRI - Fix size of allocations
Diffstat (limited to 'tools')
-rw-r--r--tools/standalone_miri/miri.cpp4
-rw-r--r--tools/standalone_miri/value.cpp61
-rw-r--r--tools/standalone_miri/value.hpp18
3 files changed, 41 insertions, 42 deletions
diff --git a/tools/standalone_miri/miri.cpp b/tools/standalone_miri/miri.cpp
index e7280476..c8326283 100644
--- a/tools/standalone_miri/miri.cpp
+++ b/tools/standalone_miri/miri.cpp
@@ -430,6 +430,7 @@ struct MirHelpers
}
else
{
+ LOG_DEBUG("sizeof(" << ty << ") = " << ty.get_size());
LOG_ASSERT(vr.m_size == POINTER_SIZE, "Deref of a value that isn't a pointer-sized value (size=" << vr << ") - " << vr << ": " << ptr_ty);
size = ty.get_size();
if( !alloc ) {
@@ -1943,8 +1944,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
LOG_ASSERT(alloc_ptr.is_alloc(), "__rust_reallocate with no backing allocation attached to pointer");
auto& alloc = alloc_ptr.alloc();
// TODO: Check old size and alignment against allocation.
- alloc.data.resize( (newsize + 8-1) / 8 );
- alloc.mask.resize( (newsize + 8-1) / 8 );
+ alloc.resize(newsize);
// TODO: Should this instead make a new allocation to catch use-after-free?
rv = ::std::move(args.at(0));
}
diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp
index 16842d82..7c3e205a 100644
--- a/tools/standalone_miri/value.cpp
+++ b/tools/standalone_miri/value.cpp
@@ -66,8 +66,9 @@ AllocationHandle Allocation::new_alloc(size_t size, ::std::string tag)
Allocation* rv = new Allocation();
rv->m_tag = ::std::move(tag);
rv->refcount = 1;
- rv->data.resize( (size + 8-1) / 8 ); // QWORDS
- rv->mask.resize( (size + 8-1) / 8 ); // bitmap bytes
+ rv->m_size = size;
+ rv->m_data.resize( (size + 8-1) / 8 ); // QWORDS
+ rv->m_mask.resize( (size + 8-1) / 8 ); // bitmap bytes
//LOG_DEBUG(rv << " ALLOC");
LOG_DEBUG(rv);
return AllocationHandle(rv);
@@ -337,8 +338,9 @@ void Allocation::resize(size_t new_size)
//size_t old_size = this->size();
//size_t extra_bytes = (new_size > old_size ? new_size - old_size : 0);
- this->data.resize( (new_size + 8-1) / 8 );
- this->mask.resize( (new_size + 8-1) / 8 );
+ this->m_size = new_size;
+ this->m_data.resize( (new_size + 8-1) / 8 );
+ this->m_mask.resize( (new_size + 8-1) / 8 );
}
void Allocation::check_bytes_valid(size_t ofs, size_t size) const
@@ -348,7 +350,7 @@ void Allocation::check_bytes_valid(size_t ofs, size_t size) const
}
for(size_t i = ofs; i < ofs + size; i++)
{
- if( !(this->mask[i/8] & (1 << (i%8))) )
+ if( !(this->m_mask[i/8] & (1 << (i%8))) )
{
LOG_ERROR("Invalid bytes in value - " << ofs << "+" << size << " - " << *this);
throw "ERROR";
@@ -357,16 +359,16 @@ void Allocation::check_bytes_valid(size_t ofs, size_t size) const
}
void Allocation::mark_bytes_valid(size_t ofs, size_t size)
{
- assert( ofs+size <= this->mask.size() * 8 );
+ assert( ofs+size <= this->m_mask.size() * 8 );
for(size_t i = ofs; i < ofs + size; i++)
{
- this->mask[i/8] |= (1 << (i%8));
+ this->m_mask[i/8] |= (1 << (i%8));
}
}
Value Allocation::read_value(size_t ofs, size_t size) const
{
Value rv;
- TRACE_FUNCTION_R("Allocation::read_value " << this << " " << ofs << "+" << size, *this << " | " << rv);
+ //TRACE_FUNCTION_R("Allocation::read_value " << this << " " << ofs << "+" << size, *this << " | " << size << "=" << rv);
if( this->is_freed )
LOG_ERROR("Use of freed memory " << this);
LOG_DEBUG(*this);
@@ -401,10 +403,10 @@ Value Allocation::read_value(size_t ofs, size_t size) const
size_t j = ofs + i;
const uint8_t test_mask = (1 << (j%8));
const uint8_t set_mask = (1 << (i%8));
- bool v = (this->mask[j/8] & test_mask) != 0;
+ bool v = (this->m_mask[j/8] & test_mask) != 0;
if( v )
{
- rv.allocation->mask[i/8] |= set_mask;
+ rv.allocation->m_mask[i/8] |= set_mask;
}
}
}
@@ -422,7 +424,7 @@ Value Allocation::read_value(size_t ofs, size_t size) const
size_t j = ofs + i;
const uint8_t tst_mask = 1 << (j%8);
const uint8_t set_mask = 1 << (i%8);
- bool v = (this->mask[j/8] & tst_mask) != 0;
+ bool v = (this->m_mask[j/8] & tst_mask) != 0;
if( v )
{
rv.direct_data.mask[i/8] |= set_mask;
@@ -436,7 +438,7 @@ void Allocation::read_bytes(size_t ofs, void* dst, size_t count) const
if( this->is_freed )
LOG_ERROR("Use of freed memory " << this);
- LOG_DEBUG("Allocation::read_bytes " << this << " " << ofs << "+" << count);
+ //LOG_DEBUG("Allocation::read_bytes " << this << " " << ofs << "+" << count);
if(count == 0)
return ;
@@ -461,7 +463,7 @@ void Allocation::write_value(size_t ofs, Value v)
size_t v_size = v.allocation->size();
const auto& src_alloc = *v.allocation;
// Take a copy of the source mask
- auto s_mask = src_alloc.mask;
+ auto s_mask = src_alloc.m_mask;
// Save relocations first, because `Foo = Foo` is valid.
::std::vector<Relocation> new_relocs = src_alloc.relocations;
@@ -489,9 +491,9 @@ void Allocation::write_value(size_t ofs, Value v)
{
uint8_t dbit = 1 << ((ofs+i) % 8);
if( s_mask[i/8] & (1 << (i %8)) )
- this->mask[ (ofs+i) / 8 ] |= dbit;
+ this->m_mask[ (ofs+i) / 8 ] |= dbit;
else
- this->mask[ (ofs+i) / 8 ] &= ~dbit;
+ this->m_mask[ (ofs+i) / 8 ] &= ~dbit;
}
}
else
@@ -499,7 +501,7 @@ void Allocation::write_value(size_t ofs, Value v)
// Copy the mask bytes directly
for(size_t i = 0; i < v_size / 8; i ++)
{
- this->mask[ofs/8+i] = s_mask[i];
+ this->m_mask[ofs/8+i] = s_mask[i];
}
}
}
@@ -512,9 +514,9 @@ void Allocation::write_value(size_t ofs, Value v)
{
uint8_t dbit = 1 << ((ofs+i) % 8);
if( v.direct_data.mask[i/8] & (1 << (i %8)) )
- this->mask[ (ofs+i) / 8 ] |= dbit;
+ this->m_mask[ (ofs+i) / 8 ] |= dbit;
else
- this->mask[ (ofs+i) / 8 ] &= ~dbit;
+ this->m_mask[ (ofs+i) / 8 ] &= ~dbit;
}
}
}
@@ -588,7 +590,7 @@ void Allocation::set_reloc(size_t ofs, size_t len, RelocationPtr reloc)
if( i != 0 )
os << " ";
- if( x.mask[i/8] & (1 << (i%8)) )
+ if( x.m_mask[i/8] & (1 << (i%8)) )
{
os << ::std::setw(2) << ::std::setfill('0') << (int)x.data_ptr()[i];
}
@@ -657,26 +659,21 @@ Value Value::new_fnptr(const ::HIR::Path& fn_path)
{
Value rv( ::HIR::TypeRef(::HIR::CoreType { RawType::Function }) );
assert(rv.allocation);
- rv.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_fcn(fn_path) });
- rv.allocation->data.at(0) = Allocation::PTR_BASE;
- rv.allocation->mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
+ rv.allocation->write_ptr(0, Allocation::PTR_BASE, RelocationPtr::new_fcn(fn_path));
return rv;
}
Value Value::new_ffiptr(FFIPointer ffi)
{
Value rv( ::HIR::TypeRef(::HIR::CoreType { RawType::USize }) );
rv.create_allocation();
- rv.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_ffi(ffi) });
- rv.allocation->data.at(0) = Allocation::PTR_BASE;
- rv.allocation->mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
+ rv.allocation->write_ptr(0, Allocation::PTR_BASE, RelocationPtr::new_ffi(ffi));
return rv;
}
Value Value::new_pointer(::HIR::TypeRef ty, uint64_t v, RelocationPtr r) {
assert(ty.get_wrapper());
assert(ty.get_wrapper()->type == TypeWrapper::Ty::Borrow || ty.get_wrapper()->type == TypeWrapper::Ty::Pointer);
Value rv(ty);
- rv.write_usize(0, v);
- rv.allocation->relocations.push_back(Relocation { 0, /*POINTER_SIZE,*/ ::std::move(r) });
+ rv.write_ptr(0, v, ::std::move(r));
return rv;
}
Value Value::new_usize(uint64_t v) {
@@ -710,10 +707,10 @@ void Value::create_allocation()
assert(!this->allocation);
this->allocation = Allocation::new_alloc(this->direct_data.size, "create_allocation");
if( this->direct_data.size > 0 )
- this->allocation->mask[0] = this->direct_data.mask[0];
+ this->allocation->m_mask[0] = this->direct_data.mask[0];
if( this->direct_data.size > 8 )
- this->allocation->mask[1] = this->direct_data.mask[1];
- ::std::memcpy(this->allocation->data.data(), this->direct_data.data, this->direct_data.size);
+ this->allocation->m_mask[1] = this->direct_data.mask[1];
+ ::std::memcpy(this->allocation->data_ptr(), this->direct_data.data, this->direct_data.size);
}
void Value::check_bytes_valid(size_t ofs, size_t size) const
{
@@ -900,7 +897,7 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
if( i != 0 )
os << " ";
- if( alloc.mask[i/8] & (1 << i%8) )
+ if( alloc.m_mask[i/8] & (1 << i%8) )
{
os << ::std::setw(2) << ::std::setfill('0') << (int)alloc.data_ptr()[i];
}
@@ -953,7 +950,7 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
if( i != 0 )
os << " ";
- if( alloc.mask[i/8] & (1 << i%8) )
+ if( alloc.m_mask[i/8] & (1 << i%8) )
{
os << ::std::setw(2) << ::std::setfill('0') << (int)alloc.data_ptr()[i];
}
diff --git a/tools/standalone_miri/value.hpp b/tools/standalone_miri/value.hpp
index 1ba3382e..ab7add8c 100644
--- a/tools/standalone_miri/value.hpp
+++ b/tools/standalone_miri/value.hpp
@@ -249,8 +249,14 @@ class Allocation:
friend class AllocationHandle;
::std::string m_tag;
size_t refcount;
+ size_t m_size;
// TODO: Read-only flag?
bool is_freed = false;
+
+ ::std::vector<uint64_t> m_data;
+public:
+ ::std::vector<uint8_t> m_mask;
+ ::std::vector<Relocation> relocations;
public:
virtual ~Allocation() {}
static AllocationHandle new_alloc(size_t size, ::std::string tag);
@@ -258,15 +264,11 @@ public:
// NOTE: This should match the value in the MMIR backend
static const size_t PTR_BASE = 0x1000;
- const uint8_t* data_ptr() const { return reinterpret_cast<const uint8_t*>(this->data.data()); }
- uint8_t* data_ptr() { return reinterpret_cast< uint8_t*>(this->data.data()); }
- size_t size() const { return this->data.size() * 8; }
+ const uint8_t* data_ptr() const { return reinterpret_cast<const uint8_t*>(this->m_data.data()); }
+ uint8_t* data_ptr() { return reinterpret_cast< uint8_t*>(this->m_data.data()); }
+ size_t size() const { return m_size; }
const ::std::string& tag() const { return m_tag; }
- ::std::vector<uint64_t> data;
- ::std::vector<uint8_t> mask;
- ::std::vector<Relocation> relocations;
-
RelocationPtr get_relocation(size_t ofs) const override {
for(const auto& r : relocations) {
if(r.slot_ofs == ofs)
@@ -277,7 +279,7 @@ public:
void mark_as_freed() {
is_freed = true;
relocations.clear();
- for(auto& v : mask)
+ for(auto& v : m_mask)
v = 0;
}