Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New algorithm for bounds calculation and changes to cap encoding #76

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 15 additions & 42 deletions properties/props.sail
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,6 @@ function encodeDecode(c : Capability) -> Capability = capBitsToCapability(c.tag
*/
function capEncodable(c : Capability) -> bool = c == encodeDecode(c)

// $property
/*
* THIS is not actually an invariant but is useful for characterising unusable
* encodings. Ideally we'd like an encoding that ensures base is less than or
* equal to top, but sadly this isn't true. Counterexamples are unusable
* encodings. This can happen when a_top ends up being zero and T < B because
* the attempted corrections can underflow a_top. There are other unusable
* encodings too, for example those with top larger than 2**32.
*/
function prop_base_lteq_top(b : CapBits) -> bool = {
vmurali marked this conversation as resolved.
Show resolved Hide resolved
let c = capBitsToCapability(false, b);
let (base, top) = getCapBoundsBits(c);
a_top = c.address >> (unsigned(c.E) + cap_mantissa_width);
(a_top != zeros() | (c.B <_u c.T)) --> ((0b0 @ base) <=_u top)
}

$property
/*!
* Check that null_cap as defined in the Sail encodes to all zeros.
Expand Down Expand Up @@ -81,24 +65,6 @@ function prop_decEnc(t : bool, c : CapBits) -> bool = {
(c == b) & (cap.tag == t)
}

// $counterexample
/*!
* THIS property attempts to prove that it is possible to recover T and B bits
* from the decoded base and top. This would be important in an implementation
* that decodes fully on load and recompresses on store. It fails when E is
* cap_max_E because base is only 32-bits and we lose the top bit of B, but I
* think it would hold if getCapBoundsBits returned a 33-bit base.
*/
function prop_decEnc2(c : CapBits) -> bool = {
let cap = capBitsToCapability(false, c);
let (base, top) = getCapBoundsBits(cap);
let newB = truncate(base >> unsigned(cap.E), cap_mantissa_width);
let newT = truncate(top >> unsigned(cap.E), cap_mantissa_width);
let cap2 = {cap with B=newB, T=newT};
let c2 = capToBits(cap2);
(c == c2)
}

$property
/*!
* THIS checks that for any capability and permissions mask [CAndPerm]
Expand Down Expand Up @@ -128,7 +94,8 @@ $property
function prop_setbounds(reqBase : CapAddrBits, reqLen : CapAddrBits) -> bool = {
let (exact, c) = setCapBounds(root_cap_mem, reqBase, reqLen);
let encodable = capEncodable(c);
let (b2, t2) = getCapBoundsBits(c);
let (b2, l2) = getCapBoundsBits(c);
let t2 = (0b0 @ b2) + l2;
let reqTop = (0b0 @ reqBase) + (0b0 @ reqLen);
let saneTop = reqTop <=_u 0b1@0x00000000;
saneTop --> (
Expand All @@ -155,13 +122,15 @@ function prop_setbounds_monotonic(
reqBase1 : CapAddrBits, reqLen1 : CapAddrBits,
reqBase2 : CapAddrBits, reqLen2 : CapAddrBits) -> bool = {
let (exact1, c1) = setCapBounds(root_cap_mem, reqBase1, reqLen1);
let (b1, t1) = getCapBoundsBits(c1);
let (b1, l1) = getCapBoundsBits(c1);
let t1 = (0b0 @ b1) + l1;
let reqTop1 = (0b0 @ reqBase1) + (0b0 @ reqLen1);
let saneTop1 = reqTop1 <=_u 0b1@0x00000000;
let reqTop2 = (0b0 @ reqBase2) + (0b0 @ reqLen2);
let saneTop2 = reqTop2 <=_u 0b1@0x00000000;
let (exact2, c2) = setCapBounds(c1, reqBase2, reqLen2);
let (b2, t2) = getCapBoundsBits(c2);
let (b2, l2) = getCapBoundsBits(c2);
let t2 = (0b0 @ b2) + l2;
let requestMonotonic = (b1 <=_u reqBase2) & (reqTop2 <=_u t1);
let resultMonotonic = (b1 <=_u b2) & (t2 <=_u t1);
(saneTop1 & saneTop2 & requestMonotonic) --> resultMonotonic
Expand All @@ -176,10 +145,12 @@ $property
function prop_setbounds_precise(reqBase1 : CapAddrBits, reqLen1 : CapAddrBits,
c2 : CapBits) -> bool = {
let (exact, c1) = setCapBounds(root_cap_mem, reqBase1, reqLen1);
let (b1, t1) = getCapBoundsBits(c1);
let (b1, l1) = getCapBoundsBits(c1);
let t1 = (0b0 @ b1) + l1;
let reqTop1 = (0b0 @ reqBase1) + (0b0 @ reqLen1);
let saneTop1 = reqTop1 <=_u 0b1@0x00000000;
let (b2, t2) = getCapBoundsBits(capBitsToCapability(false, c2));
let (b2, l2) = getCapBoundsBits(capBitsToCapability(false, c2));
let t2 = (0b0 @ b2) + l2;
let validBase = b2 <=_u reqBase1;
let betterBase = b1 <_u b2;
let validTop = reqTop1 <=_u t2;
Expand Down Expand Up @@ -211,7 +182,8 @@ function prop_repbounds_c(reqBase : CapAddrBits, reqLen : CapAddrBits, newAddr :
let (exact, c) = setCapBounds(root_cap_mem, reqBase, reqLen);
let reqTop = (0b0 @ reqBase) + (0b0 @ reqLen);
let saneTop = reqTop <=_u 0b1@0x00000000;
let (b, t) = getCapBoundsBits(c);
let (b, l) = getCapBoundsBits(c);
let t = (0b0 @ b) + l;
let (representable, newCap) = setCapAddr(c, newAddr);
let inCBounds = (b <=_u newAddr) & ((0b0 @ newAddr) <=_u t);
(saneTop & inCBounds) --> representable
Expand All @@ -226,7 +198,8 @@ function prop_repbounds(reqBase : CapAddrBits, reqLen : CapAddrBits, newAddr : C
let (exact, c) = setCapBounds(root_cap_mem, reqBase, reqLen);
let reqTop = (0b0 @ reqBase) + (0b0 @ reqLen);
let saneTop = reqTop <=_u 0b1@0x00000000;
let (b, t) = getCapBoundsBits(c);
let (b, l) = getCapBoundsBits(c);
let t = (0b0 @ b) + l;
let (representable, newCap) = setCapAddr(c, newAddr);
let repTop = (0b0 @ b) + ((to_bits(33,1) << unsigned(c.E)) << 9);
/* The representable bounds check: either E is max or address is in range */
Expand Down Expand Up @@ -266,4 +239,4 @@ function prop_crrl_cram_usage(reqLen : CapAddrBits) -> bool = {
let mask = getRepresentableAlignmentMask(newLen);
let mask2 = getRepresentableAlignmentMask(reqLen);
((reqLen == zeros()) | (newLen != zeros())) --> (mask == mask2)
}
}
4 changes: 2 additions & 2 deletions qtest/qtest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ let gen_sailbits_geom n s =

let test_cap_decode capbits =
let cap = Cheri_cc.zcapBitsToCapability(false, capbits) in
let (bot, top)= Cheri_cc.zgetCapBounds(cap) in
let (bot, length)= Cheri_cc.zgetCapBounds(cap) in
begin
print (Cheri_cc.string_of_zbits capbits);
print (",0x");
print (Z.format "08x" bot);
print (",0x");
print (Z.format "09x" top);
print (Z.format "09x" length);
print ",";
print (Cheri_cc.string_of_zbits (Cheri_cc.zgetCapPerms cap));
print (",");
Expand Down
Loading
Loading