summaryrefslogtreecommitdiff
path: root/tools/standalone_miri/value.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-05-15 21:25:47 +0800
committerJohn Hodge <tpg@mutabah.net>2018-05-15 21:25:47 +0800
commit55ea64451a81be2f797094c9a4140a7a98ba6b5d (patch)
tree2d05c8108701d660a8660a37c3c0fcbef2a8699e /tools/standalone_miri/value.cpp
parentee65f12f4aeb27238c8a2fc07fbe84eceafdde26 (diff)
downloadmrust-55ea64451a81be2f797094c9a4140a7a98ba6b5d.tar.gz
Standalone MIRI - Split AllocationPtr into AllocationHandle and RelocationPtr
Diffstat (limited to 'tools/standalone_miri/value.cpp')
-rw-r--r--tools/standalone_miri/value.cpp208
1 files changed, 131 insertions, 77 deletions
diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp
index cdace6e2..d8eeee01 100644
--- a/tools/standalone_miri/value.cpp
+++ b/tools/standalone_miri/value.cpp
@@ -9,49 +9,79 @@
#include <algorithm>
#include "debug.hpp"
-AllocationPtr Allocation::new_alloc(size_t size)
+AllocationHandle Allocation::new_alloc(size_t size)
{
Allocation* rv = new Allocation();
rv->refcount = 1;
rv->data.resize( (size + 8-1) / 8 ); // QWORDS
rv->mask.resize( (size + 8-1) / 8 ); // bitmap bytes
//LOG_DEBUG(rv << " ALLOC");
- return AllocationPtr(rv);
+ return AllocationHandle(rv);
}
-AllocationPtr AllocationPtr::new_fcn(::HIR::Path p)
+AllocationHandle::AllocationHandle(const AllocationHandle& x):
+ m_ptr(x.m_ptr)
{
- AllocationPtr rv;
+ if( m_ptr )
+ {
+ assert(m_ptr->refcount != 0);
+ assert(m_ptr->refcount != SIZE_MAX);
+ m_ptr->refcount += 1;
+ //LOG_DEBUG(m_ptr << " REF++ " << m_ptr->refcount);
+ }
+}
+AllocationHandle::~AllocationHandle()
+{
+ if( m_ptr )
+ {
+ m_ptr->refcount -= 1;
+ //LOG_DEBUG(m_ptr << " REF-- " << m_ptr->refcount);
+ if(m_ptr->refcount == 0)
+ {
+ delete m_ptr;
+ }
+ }
+}
+
+RelocationPtr RelocationPtr::new_alloc(AllocationHandle alloc)
+{
+ RelocationPtr rv;
+ auto* ptr = alloc.m_ptr;
+ alloc.m_ptr = nullptr;
+ rv.m_ptr = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(ptr) + static_cast<uintptr_t>(Ty::Allocation) );
+ return rv;
+}
+RelocationPtr RelocationPtr::new_fcn(::HIR::Path p)
+{
+ RelocationPtr rv;
auto* ptr = new ::HIR::Path(::std::move(p));
rv.m_ptr = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(ptr) + static_cast<uintptr_t>(Ty::Function) );
return rv;
}
-AllocationPtr AllocationPtr::new_string(const ::std::string* ptr)
+RelocationPtr RelocationPtr::new_string(const ::std::string* ptr)
{
- AllocationPtr rv;
+ RelocationPtr rv;
rv.m_ptr = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(ptr) + static_cast<uintptr_t>(Ty::StdString) );
return rv;
}
-AllocationPtr AllocationPtr::new_ffi(FFIPointer info)
+RelocationPtr RelocationPtr::new_ffi(FFIPointer info)
{
- AllocationPtr rv;
+ RelocationPtr rv;
auto* ptr = new FFIPointer(info);
rv.m_ptr = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(ptr) + static_cast<uintptr_t>(Ty::FfiPointer) );
return rv;
}
-AllocationPtr::AllocationPtr(const AllocationPtr& x):
+RelocationPtr::RelocationPtr(const RelocationPtr& x):
m_ptr(nullptr)
{
if( x )
{
switch(x.get_ty())
{
- case Ty::Allocation:
- m_ptr = x.m_ptr;
- assert(alloc().refcount != 0);
- assert(alloc().refcount != SIZE_MAX);
- alloc().refcount += 1;
- //LOG_DEBUG(&alloc() << " REF++ " << alloc().refcount);
- break;
+ case Ty::Allocation: {
+ auto tmp = AllocationHandle( reinterpret_cast<Allocation*>(x.get_ptr()) );
+ *this = RelocationPtr::new_alloc(tmp);
+ tmp.m_ptr = nullptr;
+ } break;
case Ty::Function: {
auto ptr_i = reinterpret_cast<uintptr_t>(new ::HIR::Path(x.fcn()));
assert( (ptr_i & 3) == 0 );
@@ -75,21 +105,15 @@ AllocationPtr::AllocationPtr(const AllocationPtr& x):
m_ptr = nullptr;
}
}
-AllocationPtr::~AllocationPtr()
+RelocationPtr::~RelocationPtr()
{
if( *this )
{
switch(get_ty())
{
- case Ty::Allocation: {
- auto* ptr = &alloc();
- ptr->refcount -= 1;
- //LOG_DEBUG(&alloc() << " REF-- " << ptr->refcount);
- if(ptr->refcount == 0)
- {
- delete ptr;
- }
- } break;
+ case Ty::Allocation:
+ (void)AllocationHandle( reinterpret_cast<Allocation*>(get_ptr()) );
+ break;
case Ty::Function: {
auto* ptr = const_cast<::HIR::Path*>(&fcn());
delete ptr;
@@ -104,7 +128,7 @@ AllocationPtr::~AllocationPtr()
}
}
}
-size_t AllocationPtr::get_size() const
+size_t RelocationPtr::get_size() const
{
if( !*this )
return 0;
@@ -123,22 +147,22 @@ size_t AllocationPtr::get_size() const
throw "Unreachable";
}
-::std::ostream& operator<<(::std::ostream& os, const AllocationPtr& x)
+::std::ostream& operator<<(::std::ostream& os, const RelocationPtr& x)
{
if( x )
{
switch(x.get_ty())
{
- case AllocationPtr::Ty::Allocation:
+ case RelocationPtr::Ty::Allocation:
os << &x.alloc();
break;
- case AllocationPtr::Ty::Function:
+ case RelocationPtr::Ty::Function:
os << x.fcn();
break;
- case AllocationPtr::Ty::StdString:
+ case RelocationPtr::Ty::StdString:
os << "\"" << x.str() << "\"";
break;
- case AllocationPtr::Ty::FfiPointer:
+ case RelocationPtr::Ty::FfiPointer:
os << "FFI " << x.ffi().source_function << " " << x.ffi().ptr_value;
break;
}
@@ -150,17 +174,17 @@ size_t AllocationPtr::get_size() const
return os;
}
-uint64_t ValueCommon::read_usize(size_t ofs) const
+uint64_t ValueCommonRead::read_usize(size_t ofs) const
{
uint64_t v = 0;
this->read_bytes(ofs, &v, POINTER_SIZE);
return v;
}
-void ValueCommon::write_usize(size_t ofs, uint64_t v)
+void ValueCommonWrite::write_usize(size_t ofs, uint64_t v)
{
this->write_bytes(ofs, &v, POINTER_SIZE);
}
-void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t& out_size, bool& out_is_mut) const
+void* ValueCommonRead::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t& out_size, bool& out_is_mut) const
{
auto ofs = read_usize(rd_ofs);
auto reloc = get_relocation(rd_ofs);
@@ -180,7 +204,7 @@ void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t&
{
switch(reloc.get_ty())
{
- case AllocationPtr::Ty::Allocation: {
+ case RelocationPtr::Ty::Allocation: {
auto& a = reloc.alloc();
if( ofs > a.size() )
LOG_FATAL("Out-of-bounds pointer");
@@ -191,7 +215,7 @@ void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t&
out_is_mut = true;
return a.data_ptr() + ofs;
}
- case AllocationPtr::Ty::StdString: {
+ case RelocationPtr::Ty::StdString: {
const auto& s = reloc.str();
if( ofs > s.size() )
LOG_FATAL("Out-of-bounds pointer");
@@ -201,9 +225,9 @@ void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t&
out_is_mut = false;
return const_cast<void*>( static_cast<const void*>(s.data() + ofs) );
}
- case AllocationPtr::Ty::Function:
+ case RelocationPtr::Ty::Function:
LOG_FATAL("read_pointer w/ function");
- case AllocationPtr::Ty::FfiPointer:
+ case RelocationPtr::Ty::FfiPointer:
if( req_valid )
LOG_FATAL("Can't request valid data from a FFI pointer");
// TODO: Have an idea of mutability and available size from FFI
@@ -214,7 +238,7 @@ void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t&
throw "";
}
}
-ValueRef ValueCommon::read_pointer_valref_mut(size_t rd_ofs, size_t size)
+ValueRef ValueCommonRead::read_pointer_valref_mut(size_t rd_ofs, size_t size)
{
auto ofs = read_usize(rd_ofs);
auto reloc = get_relocation(rd_ofs);
@@ -290,7 +314,7 @@ Value Allocation::read_value(size_t ofs, size_t size) const
{
if( ofs <= r.slot_ofs && r.slot_ofs < ofs + size )
{
- rv.allocation.alloc().relocations.push_back({ r.slot_ofs - ofs, r.backing_alloc });
+ rv.allocation->relocations.push_back({ r.slot_ofs - ofs, r.backing_alloc });
}
}
@@ -303,7 +327,7 @@ Value Allocation::read_value(size_t ofs, size_t size) const
bool v = (this->mask[j/8] & test_mask) != 0;
if( v )
{
- rv.allocation.alloc().mask[i/8] |= set_mask;
+ rv.allocation->mask[i/8] |= set_mask;
}
}
}
@@ -365,8 +389,8 @@ void Allocation::write_value(size_t ofs, Value v)
// LOG_ERROR("Writing to read-only allocation " << this);
if( v.allocation )
{
- size_t v_size = v.allocation.alloc().size();
- const auto& src_alloc = v.allocation.alloc();
+ 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;
@@ -575,18 +599,18 @@ Value Value::new_fnptr(const ::HIR::Path& fn_path)
{
Value rv( ::HIR::TypeRef(::HIR::CoreType { RawType::Function }) );
assert(rv.allocation);
- rv.allocation.alloc().relocations.push_back(Relocation { 0, AllocationPtr::new_fcn(fn_path) });
- rv.allocation.alloc().data.at(0) = 0;
- rv.allocation.alloc().mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
+ rv.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_fcn(fn_path) });
+ rv.allocation->data.at(0) = 0;
+ rv.allocation->mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
return rv;
}
Value Value::new_ffiptr(FFIPointer ffi)
{
Value rv( ::HIR::TypeRef(::HIR::CoreType { RawType::USize }) );
rv.create_allocation();
- rv.allocation.alloc().relocations.push_back(Relocation { 0, AllocationPtr::new_ffi(ffi) });
- rv.allocation.alloc().data.at(0) = 0;
- rv.allocation.alloc().mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
+ rv.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_ffi(ffi) });
+ rv.allocation->data.at(0) = 0;
+ rv.allocation->mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
return rv;
}
@@ -595,10 +619,10 @@ void Value::create_allocation()
assert(!this->allocation);
this->allocation = Allocation::new_alloc(this->direct_data.size);
if( this->direct_data.size > 0 )
- this->allocation.alloc().mask[0] = this->direct_data.mask[0];
+ this->allocation->mask[0] = this->direct_data.mask[0];
if( this->direct_data.size > 8 )
- this->allocation.alloc().mask[1] = this->direct_data.mask[1];
- ::std::memcpy(this->allocation.alloc().data.data(), this->direct_data.data, this->direct_data.size);
+ this->allocation->mask[1] = this->direct_data.mask[1];
+ ::std::memcpy(this->allocation->data.data(), this->direct_data.data, this->direct_data.size);
}
void Value::check_bytes_valid(size_t ofs, size_t size) const
{
@@ -606,7 +630,7 @@ void Value::check_bytes_valid(size_t ofs, size_t size) const
return ;
if( this->allocation )
{
- this->allocation.alloc().check_bytes_valid(ofs, size);
+ this->allocation->check_bytes_valid(ofs, size);
}
else
{
@@ -635,7 +659,7 @@ void Value::mark_bytes_valid(size_t ofs, size_t size)
{
if( this->allocation )
{
- this->allocation.alloc().mark_bytes_valid(ofs, size);
+ this->allocation->mark_bytes_valid(ofs, size);
}
else
{
@@ -652,7 +676,7 @@ Value Value::read_value(size_t ofs, size_t size) const
//TRACE_FUNCTION_R(ofs << ", " << size << ") - " << *this, rv);
if( this->allocation )
{
- rv = this->allocation.alloc().read_value(ofs, size);
+ rv = this->allocation->read_value(ofs, size);
}
else
{
@@ -670,7 +694,7 @@ void Value::read_bytes(size_t ofs, void* dst, size_t count) const
return ;
if( this->allocation )
{
- this->allocation.alloc().read_bytes(ofs, dst, count);
+ this->allocation->read_bytes(ofs, dst, count);
}
else
{
@@ -698,7 +722,7 @@ void Value::write_bytes(size_t ofs, const void* src, size_t count)
return ;
if( this->allocation )
{
- this->allocation.alloc().write_bytes(ofs, src, count);
+ this->allocation->write_bytes(ofs, src, count);
}
else
{
@@ -719,14 +743,14 @@ void Value::write_value(size_t ofs, Value v)
{
if( this->allocation )
{
- this->allocation.alloc().write_value(ofs, ::std::move(v));
+ this->allocation->write_value(ofs, ::std::move(v));
}
else
{
- if( v.allocation && !v.allocation.alloc().relocations.empty() )
+ if( v.allocation && !v.allocation->relocations.empty() )
{
this->create_allocation();
- this->allocation.alloc().write_value(ofs, ::std::move(v));
+ this->allocation->write_value(ofs, ::std::move(v));
}
else
{
@@ -749,7 +773,7 @@ void Value::write_value(size_t ofs, Value v)
{
if( v.allocation )
{
- os << v.allocation.alloc();
+ os << *v.allocation;
}
else
{
@@ -776,13 +800,13 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
{
if( v.m_size == 0 )
return os;
- if( v.m_alloc || v.m_value->allocation )
+ if( v.m_alloc )
{
- const auto& alloc_ptr = v.m_alloc ? v.m_alloc : v.m_value->allocation;
+ const auto& alloc_ptr = v.m_alloc;;
// TODO: What if alloc_ptr isn't a data allocation?
switch(alloc_ptr.get_ty())
{
- case AllocationPtr::Ty::Allocation: {
+ case RelocationPtr::Ty::Allocation: {
const auto& alloc = alloc_ptr.alloc();
auto flags = os.flags();
@@ -813,10 +837,10 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
}
os << " }";
} break;
- case AllocationPtr::Ty::Function:
+ case RelocationPtr::Ty::Function:
LOG_TODO("ValueRef to " << alloc_ptr);
break;
- case AllocationPtr::Ty::StdString: {
+ case RelocationPtr::Ty::StdString: {
const auto& s = alloc_ptr.str();
assert(v.m_offset < s.size());
assert(v.m_size < s.size());
@@ -829,12 +853,44 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
}
os.setf(flags);
} break;
- case AllocationPtr::Ty::FfiPointer:
+ case RelocationPtr::Ty::FfiPointer:
LOG_TODO("ValueRef to " << alloc_ptr);
break;
}
}
- else
+ else if( v.m_value && v.m_value->allocation )
+ {
+ const auto& alloc = *v.m_value->allocation;
+
+ auto flags = os.flags();
+ os << ::std::hex;
+ for(size_t i = v.m_offset; i < ::std::min(alloc.size(), v.m_offset + v.m_size); i++)
+ {
+ if( i != 0 )
+ os << " ";
+
+ if( alloc.mask[i/8] & (1 << i%8) )
+ {
+ os << ::std::setw(2) << ::std::setfill('0') << (int)alloc.data_ptr()[i];
+ }
+ else
+ {
+ os << "--";
+ }
+ }
+ os.setf(flags);
+
+ os << " {";
+ for(const auto& r : alloc.relocations)
+ {
+ if( v.m_offset <= r.slot_ofs && r.slot_ofs < v.m_offset + v.m_size )
+ {
+ os << " @" << (r.slot_ofs - v.m_offset) << "=" << r.backing_alloc;
+ }
+ }
+ os << " }";
+ }
+ else if( v.m_value )
{
const auto& direct = v.m_value->direct_data;
@@ -855,6 +911,10 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
}
os.setf(flags);
}
+ else
+ {
+ // TODO: no value?
+ }
return os;
}
@@ -868,9 +928,9 @@ Value ValueRef::read_value(size_t ofs, size_t size) const
if( m_alloc ) {
switch(m_alloc.get_ty())
{
- case AllocationPtr::Ty::Allocation:
+ case RelocationPtr::Ty::Allocation:
return m_alloc.alloc().read_value(m_offset + ofs, size);
- case AllocationPtr::Ty::StdString: {
+ case RelocationPtr::Ty::StdString: {
auto rv = Value::with_size(size, false);
//ASSERT_BUG(ofs <= m_alloc.str().size(), "");
//ASSERT_BUG(size <= m_alloc.str().size(), "");
@@ -893,9 +953,3 @@ bool ValueRef::compare(const void* other, size_t other_len) const
check_bytes_valid(0, other_len);
return ::std::memcmp(data_ptr(), other, other_len) == 0;
}
-uint64_t ValueRef::read_usize(size_t ofs) const
-{
- uint64_t v = 0;
- this->read_bytes(ofs, &v, POINTER_SIZE);
- return v;
-}