summaryrefslogtreecommitdiff
path: root/tools/standalone_miri/miri.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/standalone_miri/miri.cpp')
-rw-r--r--tools/standalone_miri/miri.cpp101
1 files changed, 87 insertions, 14 deletions
diff --git a/tools/standalone_miri/miri.cpp b/tools/standalone_miri/miri.cpp
index 97343714..55ac81bb 100644
--- a/tools/standalone_miri/miri.cpp
+++ b/tools/standalone_miri/miri.cpp
@@ -341,6 +341,7 @@ struct MirHelpers
auto len = vr.m_metadata->read_usize(0);
LOG_ASSERT(idx < len, "Slice index out of range");
vr.m_offset += ty.get_size() * idx;
+ vr.m_metadata.reset();
}
else
{
@@ -433,8 +434,8 @@ struct MirHelpers
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 ) {
- LOG_ERROR("Deref of a value with no relocation - " << vr);
+ if( !alloc && size > 0 ) {
+ LOG_ERROR("Deref of a non-ZST pointer with no relocation - " << vr);
}
}
@@ -502,7 +503,11 @@ struct MirHelpers
ty = ::HIR::TypeRef(ce.t);
Value val = Value(ty);
val.write_bytes(0, &ce.v, ::std::min(ty.get_size(), sizeof(ce.v))); // TODO: Endian
- // TODO: i128/u128 need the upper bytes cleared+valid
+ // i128/u128 need the upper bytes cleared+valid
+ if( ce.t.raw_type == RawType::U128 ) {
+ uint64_t zero = 0;
+ val.write_bytes(8, &zero, 8);
+ }
return val;
} break;
TU_ARM(c, Bool, ce) {
@@ -799,8 +804,8 @@ bool InterpreterThread::step_one(Value& out_thread_result)
case RawType::Bool: throw "ERROR";
case RawType::F32: throw "BUG";
case RawType::F64: dst_val = static_cast<float>( src_value.read_f64(0) ); break;
- case RawType::USize: throw "TODO";// /*dst_val = src_value.read_usize();*/ break;
- case RawType::ISize: throw "TODO";// /*dst_val = src_value.read_isize();*/ break;
+ case RawType::USize: LOG_TODO("f32 from " << src_ty);// /*dst_val = src_value.read_usize();*/ break;
+ case RawType::ISize: LOG_TODO("f32 from " << src_ty);// /*dst_val = src_value.read_isize();*/ break;
case RawType::U8: dst_val = static_cast<float>( src_value.read_u8 (0) ); break;
case RawType::I8: dst_val = static_cast<float>( src_value.read_i8 (0) ); break;
case RawType::U16: dst_val = static_cast<float>( src_value.read_u16(0) ); break;
@@ -809,8 +814,8 @@ bool InterpreterThread::step_one(Value& out_thread_result)
case RawType::I32: dst_val = static_cast<float>( src_value.read_i32(0) ); break;
case RawType::U64: dst_val = static_cast<float>( src_value.read_u64(0) ); break;
case RawType::I64: dst_val = static_cast<float>( src_value.read_i64(0) ); break;
- case RawType::U128: throw "TODO";// /*dst_val = src_value.read_u128();*/ break;
- case RawType::I128: throw "TODO";// /*dst_val = src_value.read_i128();*/ break;
+ case RawType::U128: LOG_TODO("f32 from " << src_ty);// /*dst_val = src_value.read_u128();*/ break;
+ case RawType::I128: LOG_TODO("f32 from " << src_ty);// /*dst_val = src_value.read_i128();*/ break;
}
new_val.write_f32(0, dst_val);
} break;
@@ -990,6 +995,13 @@ bool InterpreterThread::step_one(Value& out_thread_result)
if(0)
case RawType::I64:
dst_val = static_cast<uint64_t>( src_value.read_i64(0) );
+ if(0)
+ case RawType::U128:
+ dst_val = static_cast<uint64_t>( src_value.read_u128(0) );
+ if(0)
+ case RawType::I128:
+ LOG_TODO("Cast i128 to " << re.type);
+ //dst_val = static_cast<uint64_t>( src_value.read_i128(0) );
switch(re.type.inner_type)
{
@@ -1027,13 +1039,20 @@ bool InterpreterThread::step_one(Value& out_thread_result)
throw "";
}
break;
- case RawType::U128: throw "TODO"; /*dst_val = src_value.read_u128();*/ break;
- case RawType::I128: throw "TODO"; /*dst_val = src_value.read_i128();*/ break;
}
} break;
case RawType::U128:
- case RawType::I128:
- LOG_TODO("Cast to " << re.type);
+ case RawType::I128: {
+ U128 dst_val;
+ switch(src_ty.inner_type)
+ {
+ case RawType::U8: dst_val = src_value.read_u8 (0); break;
+ case RawType::I8: dst_val = src_value.read_i8 (0); break;
+ default:
+ LOG_TODO("Cast " << src_ty << " to " << re.type);
+ }
+ new_val.write_u128(0, dst_val);
+ } break;
}
}
} break;
@@ -1150,6 +1169,8 @@ bool InterpreterThread::step_one(Value& out_thread_result)
case RawType::ISize: res = res != 0 ? res : Ops::do_compare(v_l.read_isize(0), v_r.read_isize(0)); break;
case RawType::Char: res = res != 0 ? res : Ops::do_compare(v_l.read_u32(0), v_r.read_u32(0)); break;
case RawType::Bool: res = res != 0 ? res : Ops::do_compare(v_l.read_u8(0), v_r.read_u8(0)); break; // TODO: `read_bool` that checks for bool values?
+ case RawType::U128: res = res != 0 ? res : Ops::do_compare(v_l.read_u128(0), v_r.read_u128(0)); break;
+ case RawType::I128: res = res != 0 ? res : Ops::do_compare(v_l.read_i128(0), v_r.read_i128(0)); break;
default:
LOG_TODO("BinOp comparisons - " << se.src << " w/ " << ty_l);
}
@@ -1197,6 +1218,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
switch(ty_l.inner_type)
{
// TODO: U128
+ case RawType::U128: new_val.write_u128(0, Ops::do_bitwise(v_l.read_u128(0), U128(shift), re.op)); break;
case RawType::U64: new_val.write_u64(0, Ops::do_bitwise(v_l.read_u64(0), static_cast<uint64_t>(shift), re.op)); break;
case RawType::U32: new_val.write_u32(0, Ops::do_bitwise(v_l.read_u32(0), static_cast<uint32_t>(shift), re.op)); break;
case RawType::U16: new_val.write_u16(0, Ops::do_bitwise(v_l.read_u16(0), static_cast<uint16_t>(shift), re.op)); break;
@@ -1217,7 +1239,10 @@ bool InterpreterThread::step_one(Value& out_thread_result)
new_val = Value(ty_l);
switch(ty_l.inner_type)
{
- // TODO: U128/I128
+ case RawType::U128:
+ case RawType::I128:
+ new_val.write_u128( 0, Ops::do_bitwise(v_l.read_u128(0), v_r.read_u128(0), re.op) );
+ break;
case RawType::U64:
case RawType::I64:
new_val.write_u64( 0, Ops::do_bitwise(v_l.read_u64(0), v_r.read_u64(0), re.op) );
@@ -1621,6 +1646,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
case RawType::U64: switch_val = v.read_u64(0); break;
case RawType::U128: LOG_TODO("Terminator::SwitchValue::Unsigned with u128");
case RawType::USize: switch_val = v.read_usize(0); break;
+ case RawType::Char: switch_val = v.read_u32(0); break;
default:
LOG_ERROR("Terminator::SwitchValue::Unsigned with unexpected type - " << ty);
}
@@ -1913,7 +1939,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
return reinterpret_cast<const char*>(v.read_pointer_const(0, len + 1)); // Final read will trigger an error if the NUL isn't there
}
};
- if( link_name == "__rust_allocate" || link_name == "__rust_alloc" )
+ if( link_name == "__rust_allocate" || link_name == "__rust_alloc" || link_name == "__rust_alloc_zeroed" )
{
static unsigned s_alloc_count = 0;
@@ -1921,11 +1947,16 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
auto alloc_name = FMT_STRING("__rust_alloc#" << alloc_idx);
auto size = args.at(0).read_usize(0);
auto align = args.at(1).read_usize(0);
- LOG_DEBUG("__rust_allocate(size=" << size << ", align=" << align << "): name=" << alloc_name);
+ LOG_DEBUG(link_name << "(size=" << size << ", align=" << align << "): name=" << alloc_name);
auto alloc = Allocation::new_alloc(size, ::std::move(alloc_name));
LOG_TRACE("- alloc=" << alloc << " (" << alloc->size() << " bytes)");
auto rty = ::HIR::TypeRef(RawType::Unit).wrap( TypeWrapper::Ty::Pointer, 0 );
+ if( link_name == "__rust_alloc_zeroed" )
+ {
+ alloc->mark_bytes_valid(0, size);
+ }
+
// TODO: Use the alignment when making an allocation?
rv = Value::new_pointer(rty, Allocation::PTR_BASE, RelocationPtr::new_alloc(::std::move(alloc)));
}
@@ -2412,6 +2443,23 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
{
rv = Value::new_i32(-1);
}
+ else if( link_name == "memcmp" )
+ {
+ auto n = args.at(2).read_usize(0);
+ int rv_i;
+ if( n > 0 )
+ {
+ const void* ptr_b = args.at(1).read_pointer_const(0, n);
+ const void* ptr_a = args.at(0).read_pointer_const(0, n);
+
+ rv_i = memcmp(ptr_a, ptr_b, n);
+ }
+ else
+ {
+ rv_i = 0;
+ }
+ rv = Value::new_i32(rv_i);
+ }
// - `void *memchr(const void *s, int c, size_t n);`
else if( link_name == "memchr" )
{
@@ -2696,6 +2744,31 @@ bool InterpreterThread::call_intrinsic(Value& rv, const RcString& name, const ::
rv = ::std::move(args.at(0));
rv.write_ptr(0, Allocation::PTR_BASE + new_ofs, ptr_alloc);
}
+ else if( name == "arith_offset" ) // Doesn't check validity, and allows wrapping
+ {
+ auto ptr_alloc = args.at(0).get_relocation(0);
+ auto ptr_ofs = args.at(0).read_usize(0);
+ //LOG_ASSERT(ptr_ofs >= Allocation::PTR_BASE, "`offset` with invalid pointer - " << args.at(0));
+ //ptr_ofs -= Allocation::PTR_BASE;
+ auto& ofs_val = args.at(1);
+
+ auto delta_counts = ofs_val.read_usize(0);
+ auto new_ofs = ptr_ofs + delta_counts * ty_params.tys.at(0).get_size();
+ if(POINTER_SIZE != 8) {
+ new_ofs &= 0xFFFFFFFF;
+ }
+ //new_ofs += Allocation::PTR_BASE;
+
+ rv = ::std::move(args.at(0));
+ if( ptr_alloc )
+ {
+ rv.write_ptr(0, new_ofs, ptr_alloc);
+ }
+ else
+ {
+ rv.write_usize(0, new_ofs);
+ }
+ }
// effectively ptr::write
else if( name == "move_val_init" )
{