Komodo/verified/memset.sdfy

91 строка
3.6 KiB
Plaintext

include {:verbatim} "kom_common.i.dfy"
include "ARMdecls.sdfy"
procedure memcpy(operand dst:addr, operand src:addr, inout operand size:reg,
out operand tmp:reg)
modifies
mem;
requires/ensures
SaneState(this);
requires
DistinctRegOperands(set(@dst, @src, @size, @tmp), 4);
WordAligned(size);
ValidMemRange(dst, dst + size);
ValidMemRange(src, src + size);
dst + size <= src || src + size <= dst;
dst >= StackBase() || dst + size <= StackLimit();
ensures
SmcProcedureInvariant(old(this),this);
MemPreservingExcept(old(this), this, old(dst), old(dst + size));
//forall i :: 0 <= i < old(size) && WordAligned(i)
// ==> MemContents(this.m, old(dst) + i) == old(MemContents(this.m, src + i));
forall a :: old(dst) <= a < old(dst + size) && WordAligned(a)
==> MemContents(this.m, a) == old(MemContents(this.m, a - dst + src));
{
while (size > 0)
invariant
SaneState(this);
GlobalsInvariant(old(this),this);
SmcProcedureInvariant(old(this),this);
RegPreservingExcept(old(this), this, set(@size, @tmp));
WordAligned(size) && 0 <= size <= old(size);
dst == old(dst) && src == old(src);
MemPreservingExcept(old(this), this, dst + size, dst + old(size));
//forall i :: (size <= i < old(size)) && WordAligned(i)
// ==> MemContents(this.m, dst + i) == old(MemContents(this.m, src + i));
forall a :: dst + size <= a < dst + old(size) && WordAligned(a)
==> MemContents(this.m, a) == old(MemContents(this.m, a - dst + src));
decreases
size;
{
ghost var prevThis := this;
SUB(size, size, 4);
assert WordAligned(size);
LDR(tmp, src, size);
assert tmp == MemContents(old(this.m), src + size);
STR(tmp, dst, size);
assert MemContents(this.m, dst + size) == MemContents(old(this.m), src + size);
assert forall p :: ValidMem(p) && p != dst + size
==> MemContents(prevThis.m, p) == MemContents(this.m, p);
}
}
procedure memset(operand base:addr, operand val:word, inout operand size:reg)
modifies
mem;
requires/ensures
SaneState(this);
requires
DistinctRegOperands(set(@base, @val, @size), 3);
WordAligned(size);
ValidMemRange(base, base + size);
base >= StackBase() || base + size <= StackLimit();
ensures
SmcProcedureInvariant(old(this),this);
MemPreservingExcept(old(this), this, old(base), old(base + size));
forall a :: old(base) <= a < old(base + size) && WordAligned(a)
==> MemContents(this.m, a) == old(val);
{
while (size > 0)
invariant
SaneState(this);
GlobalsInvariant(old(this),this);
SmcProcedureInvariant(old(this),this);
RegPreservingExcept(old(this), this, set(@size));
WordAligned(size) && 0 <= size <= old(size);
MemPreservingExcept(old(this), this, base + size, base + old(size));
forall a :: (old(base) + size <= a < old(base + size)) && WordAligned(a)
==> MemContents(this.m, a) == val;
decreases
size;
{
ghost var prevThis := this;
SUB(size, size, 4);
assert WordAligned(size);
STR(val, base, size);
assert MemContents(this.m, base + size) == val;
assert forall p :: ValidMem(p) && p != base + size
==> MemContents(prevThis.m, p) == MemContents(this.m, p);
}
}