diff options
-rw-r--r-- | tools/standalone_miri/main.cpp | 4 | ||||
-rw-r--r-- | tools/standalone_miri/mir.cpp | 11 | ||||
-rw-r--r-- | tools/standalone_miri/miri.cpp | 38 | ||||
-rw-r--r-- | tools/standalone_miri/module_tree.cpp | 4 | ||||
-rw-r--r-- | tools/standalone_miri/value.cpp | 4 | ||||
-rw-r--r-- | tools/standalone_miri/value.hpp | 68 |
6 files changed, 95 insertions, 34 deletions
diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp index deed08be..ed9b9267 100644 --- a/tools/standalone_miri/main.cpp +++ b/tools/standalone_miri/main.cpp @@ -74,11 +74,11 @@ int main(int argc, const char* argv[]) // Create argc/argv based on input arguments auto argv_alloc = Allocation::new_alloc((1 + opts.args.size()) * POINTER_SIZE); argv_alloc->write_usize(0 * POINTER_SIZE, 0); - argv_alloc->relocations.push_back({ 0 * POINTER_SIZE, RelocationPtr::new_ffi(FFIPointer { "", (void*)(opts.infile.c_str()), opts.infile.size() + 1 }) }); + argv_alloc->relocations.push_back({ 0 * POINTER_SIZE, RelocationPtr::new_ffi(FFIPointer::new_const_bytes(opts.infile.c_str(), opts.infile.size() + 1)) }); for(size_t i = 0; i < opts.args.size(); i ++) { argv_alloc->write_usize((1 + i) * POINTER_SIZE, 0); - argv_alloc->relocations.push_back({ (1 + i) * POINTER_SIZE, RelocationPtr::new_ffi({ "", (void*)(opts.args[0]), ::std::strlen(opts.args[0]) + 1 }) }); + argv_alloc->relocations.push_back({ (1 + i) * POINTER_SIZE, RelocationPtr::new_ffi(FFIPointer::new_const_bytes(opts.args[0], ::std::strlen(opts.args[0]) + 1)) }); } // Construct argc/argv values diff --git a/tools/standalone_miri/mir.cpp b/tools/standalone_miri/mir.cpp index a0601823..f1b4841e 100644 --- a/tools/standalone_miri/mir.cpp +++ b/tools/standalone_miri/mir.cpp @@ -62,10 +62,10 @@ namespace MIR { os << "\"" << e << "\""; ), (Const, - os << e.p; + os << *e.p; ), (ItemAddr, - os << "&" << e; + os << "&" << *e; ) ) return os; @@ -83,7 +83,7 @@ namespace MIR { os << "Local(" << e << ")"; ), (Static, - os << "Static(" << e << ")"; + os << "Static(" << *e << ")"; ), (Field, os << "Field(" << e.field_index << ", " << *e.val << ")"; @@ -296,5 +296,10 @@ namespace MIR { ) return os; } + + EnumCachePtr::~EnumCachePtr() + { + assert(!this->p); + } } diff --git a/tools/standalone_miri/miri.cpp b/tools/standalone_miri/miri.cpp index 8231f2c5..d5bcb024 100644 --- a/tools/standalone_miri/miri.cpp +++ b/tools/standalone_miri/miri.cpp @@ -273,7 +273,7 @@ struct MirHelpers return ValueRef(this->frame.args.at(e.idx)); } break; TU_ARM(lv, Static, e) { - /*const*/ auto& s = this->thread.m_modtree.get_static(e); + /*const*/ auto& s = this->thread.m_modtree.get_static(*e); ty = s.ty; return ValueRef(s.val); } break; @@ -482,15 +482,15 @@ struct MirHelpers // --> Accessor TU_ARM(c, ItemAddr, ce) { // Create a value with a special backing allocation of zero size that references the specified item. - if( /*const auto* fn =*/ this->thread.m_modtree.get_function_opt(ce) ) { + if( /*const auto* fn =*/ this->thread.m_modtree.get_function_opt(*ce) ) { ty = ::HIR::TypeRef(RawType::Function); - return Value::new_fnptr(ce); + return Value::new_fnptr(*ce); } - if( const auto* s = this->thread.m_modtree.get_static_opt(ce) ) { + if( const auto* s = this->thread.m_modtree.get_static_opt(*ce) ) { ty = s->ty.wrapped(TypeWrapper::Ty::Borrow, 0); return Value::new_pointer(ty, 0, RelocationPtr::new_alloc(s->val.allocation)); } - LOG_ERROR("Constant::ItemAddr - " << ce << " - not found"); + LOG_ERROR("Constant::ItemAddr - " << *ce << " - not found"); } break; } throw ""; @@ -1031,19 +1031,20 @@ bool InterpreterThread::step_one(Value& out_thread_result) LOG_ASSERT(ty_r.get_wrapper() == nullptr, "Bitwise operator with non-primitive - " << ty_r); size_t max_bits = ty_r.get_size() * 8; uint8_t shift; - auto check_cast = [&](auto v){ LOG_ASSERT(0 <= v && v <= max_bits, "Shift out of range - " << v); return static_cast<uint8_t>(v); }; + auto check_cast_u = [&](auto v){ LOG_ASSERT(0 <= v && v <= max_bits, "Shift out of range - " << v); return static_cast<uint8_t>(v); }; + auto check_cast_s = [&](auto v){ LOG_ASSERT(v <= static_cast<int64_t>(max_bits), "Shift out of range - " << v); return static_cast<uint8_t>(v); }; switch(ty_r.inner_type) { - case RawType::U64: shift = check_cast(v_r.read_u64(0)); break; - case RawType::U32: shift = check_cast(v_r.read_u32(0)); break; - case RawType::U16: shift = check_cast(v_r.read_u16(0)); break; - case RawType::U8 : shift = check_cast(v_r.read_u8 (0)); break; - case RawType::I64: shift = check_cast(v_r.read_i64(0)); break; - case RawType::I32: shift = check_cast(v_r.read_i32(0)); break; - case RawType::I16: shift = check_cast(v_r.read_i16(0)); break; - case RawType::I8 : shift = check_cast(v_r.read_i8 (0)); break; - case RawType::USize: shift = check_cast(v_r.read_usize(0)); break; - case RawType::ISize: shift = check_cast(v_r.read_isize(0)); break; + case RawType::U64: shift = check_cast_u(v_r.read_u64(0)); break; + case RawType::U32: shift = check_cast_u(v_r.read_u32(0)); break; + case RawType::U16: shift = check_cast_u(v_r.read_u16(0)); break; + case RawType::U8 : shift = check_cast_u(v_r.read_u8 (0)); break; + case RawType::I64: shift = check_cast_s(v_r.read_i64(0)); break; + case RawType::I32: shift = check_cast_s(v_r.read_i32(0)); break; + case RawType::I16: shift = check_cast_s(v_r.read_i16(0)); break; + case RawType::I8 : shift = check_cast_s(v_r.read_i8 (0)); break; + case RawType::USize: shift = check_cast_u(v_r.read_usize(0)); break; + case RawType::ISize: shift = check_cast_s(v_r.read_isize(0)); break; default: LOG_TODO("BinOp shift rhs unknown type - " << se.src << " w/ " << ty_r); } @@ -2213,9 +2214,8 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con LOG_FATAL("Attempt to copy* a function"); break; case RelocationPtr::Ty::FfiPointer: - LOG_ASSERT(src_ofs <= src_alloc.ffi().size, ""); - LOG_ASSERT(byte_count <= src_alloc.ffi().size, ""); - LOG_ASSERT(src_ofs + byte_count <= src_alloc.ffi().size, ""); + LOG_ASSERT(src_alloc.ffi().layout, ""); + LOG_ASSERT(src_alloc.ffi().layout->is_valid_read(src_ofs, byte_count), ""); dst_alloc.alloc().write_bytes(dst_ofs, reinterpret_cast<const char*>(src_alloc.ffi().ptr_value) + src_ofs, byte_count); break; } diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp index eb6b6b9e..984662fe 100644 --- a/tools/standalone_miri/module_tree.cpp +++ b/tools/standalone_miri/module_tree.cpp @@ -379,7 +379,7 @@ bool Parser::parse_one() else if( lex.next() == "::" || lex.next() == '<' ) { auto path = p.parse_path(); - lv = ::MIR::LValue( ::std::move(path) ); + lv = ::MIR::LValue( ::std::make_unique<HIR::Path>(::std::move(path)) ); } else { LOG_ERROR(lex << "Unexpected token in LValue - " << lex.next()); @@ -464,7 +464,7 @@ bool Parser::parse_one() else if( p.lex.consume_if("ADDROF") ) { auto path = p.parse_path(); - return ::MIR::Constant::make_ItemAddr({ ::std::move(path) }); + return ::MIR::Constant::make_ItemAddr({ ::std::make_unique<HIR::Path>(::std::move(path)) }); } else { LOG_BUG(p.lex << "BUG? " << p.lex.next()); diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp index 849d3a64..9007eb5c 100644 --- a/tools/standalone_miri/value.cpp +++ b/tools/standalone_miri/value.cpp @@ -167,7 +167,7 @@ size_t RelocationPtr::get_size() const os << "\"" << x.str() << "\""; break; case RelocationPtr::Ty::FfiPointer: - os << "FFI " << x.ffi().source_function << " " << x.ffi().ptr_value; + os << "FFI " << x.ffi().tag_name << " " << x.ffi().ptr_value; break; } } @@ -237,7 +237,7 @@ void* ValueCommonRead::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size //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 - out_size = f.size - ofs; + out_size = f.get_size() - ofs; out_is_mut = false; return reinterpret_cast<char*>(reloc.ffi().ptr_value) + ofs; } diff --git a/tools/standalone_miri/value.hpp b/tools/standalone_miri/value.hpp index b057b3c4..377361ce 100644 --- a/tools/standalone_miri/value.hpp +++ b/tools/standalone_miri/value.hpp @@ -21,11 +21,67 @@ class Allocation; struct Value; struct ValueRef; +struct FfiLayout +{ + struct Range { + size_t len; + bool is_valid; + bool is_writable; + }; + ::std::vector<Range> ranges; + + size_t get_size() const { + size_t rv = 0; + for(const auto& r : ranges) + rv += r.len; + return rv; + } + bool is_valid_read(size_t o, size_t s) { + for(const auto& r : ranges) + { + if( o < r.len ) { + if( !r.is_valid ) + return false; + if( o + s <= r.len ) + { + s = 0; + break; + } + s -= (r.len - o); + o = 0; + } + else { + o -= r.len; + } + } + if( s > 0 ) + { + return false; + } + return true; + } +}; struct FFIPointer { - const char* source_function; + // FFI pointers require the following: + // - A tag indicating where they're valid/from + // - A data format (e.g. size of allocation, internal data format) + // - If the data format is unspecified (null) then it's a void pointer + // - An actual pointer + + // Pointer value, returned by the FFI void* ptr_value; - size_t size; + // Tag name, used for validty checking by FFI hooks + const char* tag_name; + ::std::shared_ptr<FfiLayout> layout; + + static FFIPointer new_const_bytes(const void* s, size_t size) { + return FFIPointer { const_cast<void*>(s), "", ::std::shared_ptr<FfiLayout>() }; + }; + + size_t get_size() const { + return (layout ? layout->get_size() : 0); + } }; class AllocationHandle @@ -83,7 +139,7 @@ public: RelocationPtr(const RelocationPtr& x); ~RelocationPtr(); static RelocationPtr new_alloc(AllocationHandle h); - static RelocationPtr new_fcn(::HIR::Path p); + static RelocationPtr new_fcn(::HIR::Path p); // TODO: What if it's a FFI function? Could be encoded in here. static RelocationPtr new_string(const ::std::string* s); // NOTE: The string must have a stable pointer static RelocationPtr new_ffi(FFIPointer info); @@ -331,9 +387,9 @@ struct ValueRef: assert(ofs+size <= m_alloc.str().size()); break; case RelocationPtr::Ty::FfiPointer: - assert(ofs < m_alloc.ffi().size); - assert(size <= m_alloc.ffi().size); - assert(ofs+size <= m_alloc.ffi().size); + assert(ofs < m_alloc.ffi().get_size()); + assert(size <= m_alloc.ffi().get_size()); + assert(ofs+size <= m_alloc.ffi().get_size()); break; default: throw "TODO"; |