-
Notifications
You must be signed in to change notification settings - Fork 77
Add a way do declare that names should be kept opaque during LLVM symbolic simulation #2686
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
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
e1c00c2
Add a way do declare that names should be kept opaque during LLVM sym…
yav 7f1b4d7
Factor common code and add `*_unint` commands to backends
yav 354f34f
Update saw-central/src/SAWCentral/Crucible/Common/Setup/Builtins.hs
yav 719e44c
Update crucible-mir-comp/src/Mir/Compositional/State.hs
yav fbb39a6
Update saw-central/src/SAWCentral/Crucible/Common/ResolveSetupValue.hs
yav 442ba92
Update saw-central/src/SAWCentral/Crucible/Common/ResolveSetupValue.hs
yav 9615c4e
Document function precondition
yav d292b8f
Make the `*_unint` functions take `[String]` instead of `Term`
yav 75805bc
Check types early. Fix up error message
yav b418141
Make it build
yav 9ef4391
Reuse `crucibleSetupTopLevel`
yav b2decc8
Fix typo
yav 4466829
Update CHANGES
yav 2a41a1e
Add a test case for 2674
yav 03cca1b
Fix tests
yav 7ec95c1
Typos
yav 3e88aeb
Update help for `*_unint` commands
yav eae0ed9
Test for no `*_uninterp` in post-condition
yav 073c51b
Update CHANGES.md
yav 9a3e2b0
Merge branch 'master' into issue_2674
yav File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module Example where | ||
|
||
cry_ID : [8] -> [8] | ||
cry_ID x = x | ||
|
||
cry_FIVE : [8] -> [8] | ||
cry_FIVE y = cry_ID 5 + y |
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
unsigned char c_ID(unsigned char x) { return x; } | ||
unsigned char c_FIVE(unsigned char y) { return c_ID(5)+y; } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
m <- llvm_load_module "example.bc"; | ||
|
||
import "Example.cry"; | ||
|
||
thm_id <- llvm_verify | ||
m "c_ID" [] false | ||
do { | ||
X <- llvm_fresh_var "X" (llvm_int 8); | ||
llvm_execute_func [llvm_term X]; | ||
llvm_return (llvm_term {{ cry_ID X }} ); | ||
} | ||
rme; | ||
|
||
fails (llvm_verify | ||
m "c_FIVE" [thm_id] false | ||
do { | ||
Y <- llvm_fresh_var "Y" (llvm_int 8); | ||
llvm_execute_func [llvm_term Y]; | ||
llvm_return (llvm_term {{ cry_FIVE Y }}); | ||
} | ||
do { | ||
w4_unint_rme ["cry_ID"]; | ||
}); | ||
|
||
|
||
fails (llvm_verify | ||
m "c_FIVE" [thm_id] false | ||
do { | ||
Y <- llvm_fresh_var "Y" (llvm_int 8); | ||
llvm_execute_func [llvm_term Y]; | ||
llvm_unint ["cry_ID"]; | ||
llvm_return (llvm_term {{ cry_FIVE Y }}); | ||
} | ||
do { | ||
w4_unint_rme []; | ||
}); | ||
|
||
thm_five <- llvm_verify | ||
m "c_FIVE" [thm_id] false | ||
do { | ||
llvm_unint ["cry_ID"]; | ||
Y <- llvm_fresh_var "Y" (llvm_int 8); | ||
llvm_execute_func [llvm_term Y]; | ||
llvm_return (llvm_term {{ cry_FIVE Y }}); | ||
} | ||
do { | ||
w4_unint_rme ["cry_ID"]; | ||
}; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
set -e | ||
$SAW test.saw |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 135 additions & 31 deletions
166
saw-central/src/SAWCentral/Crucible/Common/ResolveSetupValue.hs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,153 @@ | ||
-- | Utilities for resolving 'SetupValue's that are used across language | ||
-- backends. | ||
{-# Language DataKinds, TypeOperators, GADTs, TypeApplications #-} | ||
{-# Language ImplicitParams #-} | ||
module SAWCentral.Crucible.Common.ResolveSetupValue ( | ||
resolveBoolTerm, | ||
checkBooleanType | ||
resolveBoolTerm, resolveBoolTerm', | ||
resolveBitvectorTerm, resolveBitvectorTerm', | ||
ResolveRewrite(..), | ||
) where | ||
|
||
import qualified Data.Map as Map | ||
import Data.Set(Set) | ||
import qualified Data.BitVector.Sized as BV | ||
import Data.Parameterized.Some (Some(..)) | ||
import Data.Parameterized.NatRepr | ||
|
||
import qualified What4.BaseTypes as W4 | ||
import qualified What4.Interface as W4 | ||
|
||
|
||
import SAWCore.SharedTerm | ||
import SAWCore.Name | ||
import qualified SAWCore.Prim as Prim | ||
|
||
import qualified SAWCore.Simulator.Concrete as Concrete | ||
import qualified Lang.Crucible.Types as Crucible | ||
import qualified Lang.Crucible.Simulator.RegValue as Crucible | ||
|
||
import SAWCoreWhat4.ReturnTrip | ||
|
||
import SAWCentral.Crucible.Common | ||
|
||
import Cryptol.TypeCheck.Type (tIsBit) | ||
import CryptolSAWCore.TypedTerm (mkTypedTerm, ttType, ttIsMono) | ||
import SAWCentral.Proof (TheoremNonce) | ||
import SAWCore.Rewriter (Simpset, rewriteSharedTerm) | ||
import qualified CryptolSAWCore.Simpset as Cryptol | ||
import SAWCoreWhat4.What4(w4EvalAny, valueToSymExpr) | ||
|
||
import Cryptol.TypeCheck.Type (tIsBit, tIsSeq, tIsNum) | ||
import CryptolSAWCore.TypedTerm (mkTypedTerm, ttType, ttIsMono, ppTypedTermType) | ||
import qualified Cryptol.Utils.PP as PP | ||
|
||
-- | Resolve a SAWCore 'Term' into a What4 'W4.Pred'. | ||
resolveBoolTerm :: Sym -> Term -> IO (W4.Pred Sym) | ||
resolveBoolTerm sym tm = | ||
do st <- sawCoreState sym | ||
let sc = saw_ctx st | ||
mx <- case getAllExts tm of | ||
-- concretely evaluate if it is a closed term | ||
[] -> | ||
do modmap <- scGetModuleMap sc | ||
let v = Concrete.evalSharedTerm modmap mempty mempty tm | ||
pure (Just (Concrete.toBool v)) | ||
_ -> return Nothing | ||
case mx of | ||
Just x -> return (W4.backendPred sym x) | ||
Nothing -> bindSAWTerm sym st W4.BaseBoolRepr tm | ||
|
||
-- | Ensure that the term has Cryptol type @Bit@. | ||
checkBooleanType :: SharedContext -> Term -> IO () | ||
checkBooleanType sc tm = do | ||
tt <- mkTypedTerm sc tm | ||
case ttIsMono (ttType tt) of | ||
Just ty | tIsBit ty -> pure () | ||
| otherwise -> fail $ unlines | ||
[ "Expected type: Bit" | ||
, "Actual type: " ++ show (PP.pp ty) | ||
] | ||
Nothing -> fail "Expected monomorphic Cryptol type, got polymorphic or unrecognized type" | ||
|
||
-- | Optional rewrites to do when resolving a term | ||
data ResolveRewrite = ResolveRewrite { | ||
rrBasicSS :: Maybe (Simpset TheoremNonce), | ||
-- ^ Rewrite terms using these rewrites | ||
|
||
rrWhat4Eval :: Bool | ||
-- ^ Also simplify terms using What4 evaluation | ||
} | ||
|
||
-- | Don't do any rewriting | ||
noResolveRewrite :: ResolveRewrite | ||
noResolveRewrite = ResolveRewrite { rrBasicSS = Nothing, rrWhat4Eval = False } | ||
|
||
-- Convert a term to a What4 expression, trying to simplify it in the process. | ||
RyanGlScott marked this conversation as resolved.
Show resolved
Hide resolved
|
||
-- Currently this expects the terms to be either boolean or bit-vectors, as | ||
-- that's all we use it for. It should be fairly straightforward to generalize | ||
-- if need be. | ||
resolveTerm :: | ||
Sym {- ^ Backend state -} -> | ||
Set VarIndex {- ^ Keep these opaque -} -> | ||
W4.BaseTypeRepr t {- ^ Type of term -} -> | ||
ResolveRewrite {- ^ Optional rewrites to do on the term -} -> | ||
Term {- ^ Term to process -} -> | ||
IO (Crucible.RegValue Sym (Crucible.BaseToType t)) | ||
resolveTerm sym unint bt rr tm = | ||
do | ||
st <- sawCoreState sym | ||
checkType st | ||
tm' <- basicRewrite st tm | ||
case () of | ||
_ | isConstFoldTerm unint tm' -> | ||
do -- Evaluate as constant | ||
modmap <- scGetModuleMap (saw_ctx st) | ||
let v = Concrete.evalSharedTerm modmap mempty mempty tm' | ||
case bt of | ||
W4.BaseBoolRepr -> pure (W4.backendPred sym (Concrete.toBool v)) | ||
W4.BaseBVRepr w -> W4.bvLit sym w (BV.mkBV w (Prim.unsigned (Concrete.toWord v))) | ||
_ -> fail "resolveTerm: expected `Bool` or bit-vector" | ||
|
||
| rrWhat4Eval rr -> | ||
do -- Try to use rewrites to simplify the term | ||
let sc = saw_ctx st | ||
cryptol_ss <- Cryptol.mkCryptolSimpset @TheoremNonce sc | ||
tm'' <- snd <$> rewriteSharedTerm sc cryptol_ss tm' | ||
tm''' <- basicRewrite st tm'' | ||
if all isPreludeName (Map.elems (getConstantSet tm''')) then | ||
do | ||
(_, _, _, p) <- w4EvalAny sym st sc mempty unint tm''' | ||
case valueToSymExpr p of | ||
Just (Some y) | ||
| Just Refl <- testEquality bt ty -> pure y | ||
| otherwise -> typeError (show ty) | ||
where ty = W4.exprType y | ||
_ -> fail ("resolveTerm: unexpected w4Eval result " ++ show p) | ||
else | ||
bindSAWTerm sym st bt tm''' | ||
|
||
-- Just bind the term | ||
| otherwise -> bindSAWTerm sym st bt tm' | ||
|
||
where | ||
basicRewrite st = | ||
case rrBasicSS rr of | ||
Nothing -> pure | ||
Just ss -> \t -> snd <$> rewriteSharedTerm (saw_ctx st) ss t | ||
|
||
isPreludeName nm = | ||
case nm of | ||
ModuleIdentifier ident -> identModule ident == preludeName | ||
_ -> False | ||
|
||
checkType st = | ||
do | ||
sc <- ttType <$> mkTypedTerm (saw_ctx st) tm | ||
case ttIsMono sc of | ||
Just ty | ||
| tIsBit ty, W4.BaseBoolRepr <- bt -> pure () | ||
| Just (n,el) <- (tIsSeq ty) | ||
, tIsBit el, Just i <- tIsNum n, W4.BaseBVRepr w <- bt | ||
, intValue w == i -> pure () | ||
| otherwise -> typeError (show (PP.pp ty)) :: IO () | ||
Nothing -> typeError (show (ppTypedTermType sc)) | ||
|
||
typeError :: String -> IO a | ||
typeError t = fail $ unlines [ | ||
"Expected type: " ++ ( | ||
case bt of | ||
W4.BaseBoolRepr -> "Bit" | ||
W4.BaseBVRepr w -> "[" ++ show w ++ "]" | ||
_ -> show bt), | ||
"Actual type: " ++ t | ||
] | ||
|
||
-- 'resolveTerm' specialized to booleans. | ||
resolveBoolTerm' :: Sym -> Set VarIndex -> ResolveRewrite -> Term -> IO (W4.Pred Sym) | ||
resolveBoolTerm' sym unint = resolveTerm sym unint W4.BaseBoolRepr | ||
|
||
-- 'resolveTerm' specialized to booleans, without rewriting. | ||
resolveBoolTerm :: Sym -> Set VarIndex -> Term -> IO (W4.Pred Sym) | ||
resolveBoolTerm sym unint = resolveBoolTerm' sym unint noResolveRewrite | ||
|
||
-- 'resolveTerm' specialized to bit-vectors. | ||
resolveBitvectorTerm' :: | ||
(1 W4.<= w) => Sym -> Set VarIndex -> W4.NatRepr w -> ResolveRewrite -> Term -> IO (W4.SymBV Sym w) | ||
resolveBitvectorTerm' sym unint w = resolveTerm sym unint (W4.BaseBVRepr w) | ||
|
||
-- 'resolveTerm' specialized to bit-vectors, without rewriting. | ||
resolveBitvectorTerm :: | ||
(1 W4.<= w) => Sym -> Set VarIndex -> W4.NatRepr w -> Term -> IO (W4.SymBV Sym w) | ||
resolveBitvectorTerm sym unint w = resolveBitvectorTerm' sym unint w noResolveRewrite | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.