Update for parameterized-utils compat.

This commit is contained in:
Joe Hendrix 2018-01-02 17:31:42 -08:00
parent 3f32b82943
commit deab99869d
No known key found for this signature in database
GPG Key ID: 8DFA5FF784098C4F
6 changed files with 130 additions and 113 deletions

View File

@ -21,7 +21,7 @@ library
hs-source-dirs: src hs-source-dirs: src
exposed-modules: exposed-modules:
Data.Macaw.Symbolic.App Data.Macaw.Symbolic.CrucGen
Data.Macaw.Symbolic.PersistentState Data.Macaw.Symbolic.PersistentState
Data.Macaw.Symbolic Data.Macaw.Symbolic

View File

@ -1,14 +1,19 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE KindSignatures #-} {-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
module Data.Macaw.Symbolic module Data.Macaw.Symbolic
( ArchTranslateFunctions(..) ( Data.Macaw.Symbolic.CrucGen.CrucGenArchFunctions(..)
, Data.Macaw.Symbolic.CrucGen.CrucGen
, MacawSimulatorState , MacawSimulatorState
, stepBlocks , stepBlocks
, Data.Macaw.Symbolic.PersistentState.ArchRegContext
, Data.Macaw.Symbolic.PersistentState.ToCrucibleType
) where ) where
import Control.Monad.Except import Control.Monad.Except
@ -16,8 +21,7 @@ import Control.Monad.ST
import Control.Monad.State.Strict import Control.Monad.State.Strict
import Data.Map.Strict (Map) import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Data.Parameterized.Ctx import Data.Parameterized.Context as Ctx
import qualified Data.Parameterized.Context as Ctx
import qualified Data.Parameterized.Map as MapF import qualified Data.Parameterized.Map as MapF
import Data.Parameterized.TraversableFC import Data.Parameterized.TraversableFC
import qualified Data.Set as Set import qualified Data.Set as Set
@ -42,7 +46,7 @@ import qualified Data.Macaw.CFG.Core as M
import qualified Data.Macaw.Memory as M import qualified Data.Macaw.Memory as M
import qualified Data.Macaw.Types as M import qualified Data.Macaw.Types as M
import Data.Macaw.Symbolic.App import Data.Macaw.Symbolic.CrucGen
import Data.Macaw.Symbolic.PersistentState import Data.Macaw.Symbolic.PersistentState
data MacawSimulatorState sym = MacawSimulatorState data MacawSimulatorState sym = MacawSimulatorState
@ -54,16 +58,19 @@ regVars :: (IsSymInterface sym, M.HasRepr reg M.TypeRepr)
-> Ctx.Assignment reg ctx -> Ctx.Assignment reg ctx
-> IO (Ctx.Assignment (C.RegValue' sym) (CtxToCrucibleType ctx)) -> IO (Ctx.Assignment (C.RegValue' sym) (CtxToCrucibleType ctx))
regVars sym nameFn a = regVars sym nameFn a =
case Ctx.view a of case a of
Ctx.AssignEmpty -> pure Ctx.empty Empty -> pure Ctx.empty
Ctx.AssignExtend b reg -> do b :> reg -> do
varAssign <- regVars sym nameFn b varAssign <- regVars sym nameFn b
c <- freshConstant sym (nameFn reg) (typeToCrucibleBase (M.typeRepr reg)) c <- freshConstant sym (nameFn reg) (typeToCrucibleBase (M.typeRepr reg))
pure (varAssign Ctx.%> C.RV c) pure (varAssign :> C.RV c)
#if !MIN_VERSION_base(4,10,0)
_ -> error "internal: regVars encountered case non-exhaustive pattern"
#endif
runFreshSymOverride :: M.TypeRepr tp runFreshSymOverride :: M.TypeRepr tp
-> C.OverrideSim MacawSimulatorState sym ret -> C.OverrideSim MacawSimulatorState sym ret
Ctx.EmptyCtx EmptyCtx
(ToCrucibleType tp) (ToCrucibleType tp)
(C.RegValue sym (ToCrucibleType tp)) (C.RegValue sym (ToCrucibleType tp))
runFreshSymOverride = undefined runFreshSymOverride = undefined
@ -135,7 +142,7 @@ mkMemBaseVarMap halloc mem = do
stepBlocks :: forall sym arch ids stepBlocks :: forall sym arch ids
. (IsSymInterface sym, M.ArchConstraints arch) . (IsSymInterface sym, M.ArchConstraints arch)
=> sym => sym
-> ArchTranslateFunctions arch -> CrucGenArchFunctions arch
-> M.Memory (M.ArchAddrWidth arch) -> M.Memory (M.ArchAddrWidth arch)
-- ^ Memory image for executable -- ^ Memory image for executable
-> Text -> Text
@ -151,11 +158,11 @@ stepBlocks :: forall sym arch ids
sym sym
(C.RegEntry sym (C.StructType (CtxToCrucibleType (ArchRegContext arch))))) (C.RegEntry sym (C.StructType (CtxToCrucibleType (ArchRegContext arch)))))
stepBlocks sym sinfo mem binPath nm addr macawBlocks = do stepBlocks sym sinfo mem binPath nm addr macawBlocks = do
let regAssign = archRegAssignment sinfo let regAssign = crucGenRegAssignment sinfo
let crucRegTypes = typeCtxToCrucible (fmapFC M.typeRepr regAssign) let crucRegTypes = typeCtxToCrucible (fmapFC M.typeRepr regAssign)
let macawStructRepr = C.StructRepr crucRegTypes let macawStructRepr = C.StructRepr crucRegTypes
halloc <- C.newHandleAllocator halloc <- C.newHandleAllocator
let argTypes = Ctx.empty Ctx.%> macawStructRepr let argTypes = Empty :> macawStructRepr
h <- stToIO $ C.mkHandle' halloc nm argTypes macawStructRepr h <- stToIO $ C.mkHandle' halloc nm argTypes macawStructRepr
-- Map block map to Crucible CFG -- Map block map to Crucible CFG
let blockLabelMap :: Map Word64 (CR.Label RealWorld) let blockLabelMap :: Map Word64 (CR.Label RealWorld)
@ -197,7 +204,7 @@ stepBlocks sym sinfo mem binPath nm addr macawBlocks = do
let s = C.initSimState ctx C.emptyGlobals C.defaultErrorHandler let s = C.initSimState ctx C.emptyGlobals C.defaultErrorHandler
-- Define the arguments to call the Reopt CFG with. -- Define the arguments to call the Reopt CFG with.
-- This should be a symbolic variable for each register in the architecture. -- This should be a symbolic variable for each register in the architecture.
regStruct <- regVars sym (archRegNameFn sinfo) regAssign regStruct <- regVars sym (crucGenArchRegName sinfo) regAssign
let args :: C.RegMap sym (MacawFunctionArgs arch) let args :: C.RegMap sym (MacawFunctionArgs arch)
args = C.RegMap (Ctx.singleton (C.RegEntry macawStructRepr regStruct)) args = C.RegMap (Ctx.singleton (C.RegEntry macawStructRepr regStruct))
-- Run the symbolic simulator. -- Run the symbolic simulator.

View File

@ -16,13 +16,14 @@ This defines the core operations for mapping from Reopt to Crucible.
{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wwarn #-} {-# OPTIONS_GHC -Wwarn #-}
module Data.Macaw.Symbolic.App module Data.Macaw.Symbolic.CrucGen
( ArchTranslateFunctions(..) ( CrucGenArchFunctions(..)
, MacawMonad -- ** Operations for implementing new backends.
, CrucGen
, addMacawBlock , addMacawBlock
) where ) where
import Control.Lens import Control.Lens hiding (Empty, (:>))
import Control.Monad.Except import Control.Monad.Except
import Control.Monad.ST import Control.Monad.ST
import Control.Monad.State.Strict import Control.Monad.State.Strict
@ -32,7 +33,7 @@ import qualified Data.Macaw.CFG.Block as M
import qualified Data.Macaw.Memory as M import qualified Data.Macaw.Memory as M
import qualified Data.Macaw.Types as M import qualified Data.Macaw.Types as M
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Parameterized.Context as Ctx import Data.Parameterized.Context as Ctx
import Data.Parameterized.Map (MapF) import Data.Parameterized.Map (MapF)
import qualified Data.Parameterized.Map as MapF import qualified Data.Parameterized.Map as MapF
import Data.Parameterized.NatRepr import Data.Parameterized.NatRepr
@ -54,34 +55,38 @@ import Data.Macaw.Symbolic.PersistentState
-- CrucPersistentState -- CrucPersistentState
-- | Architecture-specific information needed to translate from Macaw to Crucible -- | Architecture-specific information needed to translate from Macaw to Crucible
data ArchTranslateFunctions arch data CrucGenArchFunctions arch
= ArchTranslateFunctions = CrucGenArchFunctions
{ archRegNameFn :: !(forall tp . M.ArchReg arch tp -> C.SolverSymbol) { crucGenArchConstraints :: !(forall a . (M.MemWidth (M.ArchAddrWidth arch) => a) -> a)
, archRegAssignment :: !(Ctx.Assignment (M.ArchReg arch) (ArchRegContext arch)) , crucGenRegAssignment :: !(Ctx.Assignment (M.ArchReg arch) (ArchRegContext arch))
-- ^ Map from indices in the ArchRegContext to the associated register. -- ^ Map from indices in the ArchRegContext to the associated register.
, archTranslateFn :: !(forall ids s tp , crucGenArchRegName :: !(forall tp . M.ArchReg arch tp -> C.SolverSymbol)
-- ^ Provides a solver name to use for referring to register.
, crucGenArchFn :: !(forall ids s tp
. M.ArchFn arch (M.Value arch ids) tp . M.ArchFn arch (M.Value arch ids) tp
-> CrucGen arch ids s (CR.Atom s (ToCrucibleType tp))) -> CrucGen arch ids s (CR.Atom s (ToCrucibleType tp)))
-- ^ Function for translating an architecture specific function -- ^ Generate crucible for architecture-specific function.
, archTranslateStmt :: !(forall ids s . M.ArchStmt arch (M.Value arch ids) -> CrucGen arch ids s ()) , crucGenArchStmt
, archTranslateTermStmt :: !(forall ids s :: !(forall ids s . M.ArchStmt arch (M.Value arch ids) -> CrucGen arch ids s ())
-- ^ Generate crucible for architecture-specific statement.
, crucGenArchTermStmt :: !(forall ids s
. M.ArchTermStmt arch ids . M.ArchTermStmt arch ids
-> M.RegState (M.ArchReg arch) (M.Value arch ids) -> M.RegState (M.ArchReg arch) (M.Value arch ids)
-> CrucGen arch ids s ()) -> CrucGen arch ids s ())
-- ^ Generate crucible for architecture-specific terminal statement.
} }
-- | State used for generating blocks -- | State used for generating blocks
data CrucGenState arch ids s data CrucGenState arch ids s
= CrucGenState = CrucGenState
{ translateFns :: !(ArchTranslateFunctions arch) { translateFns :: !(CrucGenArchFunctions arch)
, crucCtx :: !(CrucGenContext arch ids s) , crucCtx :: !(CrucGenContext arch ids s)
, crucPState :: !(CrucPersistentState arch ids s) , crucPState :: !(CrucPersistentState arch ids s)
-- ^ State that persists across blocks. -- ^ State that persists across blocks.
, blockLabel :: (CR.Label s) , blockLabel :: (CR.Label s)
-- ^ Label for this block we are translating -- ^ Label for this block we are translating
, macawBlockIndex :: !Word64 , crucPos :: !C.Position
, codeAddr :: !Word64 -- ^ Position in the crucible file.
-- ^ Address of this code
, prevStmts :: ![C.Posd (CR.Stmt s)] , prevStmts :: ![C.Posd (CR.Stmt s)]
-- ^ List of states in reverse order -- ^ List of states in reverse order
} }
@ -89,28 +94,30 @@ data CrucGenState arch ids s
crucPStateLens :: Simple Lens (CrucGenState arch ids s) (CrucPersistentState arch ids s) crucPStateLens :: Simple Lens (CrucGenState arch ids s) (CrucPersistentState arch ids s)
crucPStateLens = lens crucPState (\s v -> s { crucPState = v }) crucPStateLens = lens crucPState (\s v -> s { crucPState = v })
assignValueMapLens :: Simple Lens (CrucGenState arch ids s) assignValueMapLens :: Simple Lens (CrucPersistentState arch ids s)
(MapF (M.AssignId ids) (MacawCrucibleValue (CR.Atom s))) (MapF (M.AssignId ids) (MacawCrucibleValue (CR.Atom s)))
assignValueMapLens = crucPStateLens . lens assignValueMap (\s v -> s { assignValueMap = v }) assignValueMapLens = lens assignValueMap (\s v -> s { assignValueMap = v })
newtype CrucGen arch ids s r newtype CrucGen arch ids s r
= CrucGen { unContGen = CrucGen { unCrucGen
:: CrucGenState arch ids s :: CrucGenState arch ids s
-> (CrucGenState arch ids s -> r -> ST s (CrucPersistentState arch ids s)) -> (CrucGenState arch ids s
-> ST s (CrucPersistentState arch ids s) -> r
-> ST s (CrucPersistentState arch ids s, CR.Block s (MacawFunctionResult arch)))
-> ST s (CrucPersistentState arch ids s, CR.Block s (MacawFunctionResult arch))
} }
instance Functor (CrucGen arch ids s) where instance Functor (CrucGen arch ids s) where
fmap f m = CrucGen $ \s0 cont -> unContGen m s0 $ \s1 v -> cont s1 (f v) fmap f m = CrucGen $ \s0 cont -> unCrucGen m s0 $ \s1 v -> cont s1 (f v)
instance Applicative (CrucGen arch ids s) where instance Applicative (CrucGen arch ids s) where
pure r = CrucGen $ \s cont -> cont s r pure r = CrucGen $ \s cont -> cont s r
mf <*> ma = CrucGen $ \s0 cont -> unContGen mf s0 mf <*> ma = CrucGen $ \s0 cont -> unCrucGen mf s0
$ \s1 f -> unContGen ma s1 $ \s1 f -> unCrucGen ma s1
$ \s2 a -> cont s2 (f a) $ \s2 a -> cont s2 (f a)
instance Monad (CrucGen arch ids s) where instance Monad (CrucGen arch ids s) where
m >>= h = CrucGen $ \s0 cont -> unContGen m s0 $ \s1 r -> unContGen (h r) s1 cont m >>= h = CrucGen $ \s0 cont -> unCrucGen m s0 $ \s1 r -> unCrucGen (h r) s1 cont
instance MonadState (CrucGenState arch ids s) (CrucGen arch ids s) where instance MonadState (CrucGenState arch ids s) (CrucGen arch ids s) where
get = CrucGen $ \s cont -> cont s s get = CrucGen $ \s cont -> cont s s
@ -122,12 +129,9 @@ getCtx = gets crucCtx
liftST :: ST s r -> CrucGen arch ids s r liftST :: ST s r -> CrucGen arch ids s r
liftST m = CrucGen $ \s cont -> m >>= cont s liftST m = CrucGen $ \s cont -> m >>= cont s
-- | Get current position -- | Get current position
getPos :: CrucGen arch ids s C.Position getPos :: CrucGen arch ids s C.Position
getPos = do getPos = gets crucPos
ctx <- getCtx
C.BinaryPos (binaryPath ctx) <$> gets codeAddr
addStmt :: CR.Stmt s -> CrucGen arch ids s () addStmt :: CR.Stmt s -> CrucGen arch ids s ()
addStmt stmt = seq stmt $ do addStmt stmt = seq stmt $ do
@ -142,11 +146,11 @@ addTermStmt :: CR.TermStmt s (MacawFunctionResult arch)
addTermStmt tstmt = do addTermStmt tstmt = do
termPos <- getPos termPos <- getPos
CrucGen $ \s _ -> do CrucGen $ \s _ -> do
let lbl = CR.LabelID (blockLabel s) let lbl = blockLabel s
let stmts = Seq.fromList (reverse (prevStmts s)) let stmts = Seq.fromList (reverse (prevStmts s))
let term = C.Posd termPos tstmt let term = C.Posd termPos tstmt
let blk = CR.mkBlock lbl Set.empty stmts term let blk = CR.mkBlock (CR.LabelID lbl) Set.empty stmts term
pure $! crucPState s & seenBlockMapLens %~ Map.insert (macawBlockIndex s) blk pure $ (crucPState s, blk)
freshValueIndex :: CrucGen arch ids s Int freshValueIndex :: CrucGen arch ids s Int
freshValueIndex = do freshValueIndex = do
@ -337,11 +341,12 @@ valueToCrucible v = do
Nothing -> fail $ "internal: Register is not bound." Nothing -> fail $ "internal: Register is not bound."
M.AssignedValue asgn -> do M.AssignedValue asgn -> do
let idx = M.assignId asgn let idx = M.assignId asgn
amap <- use assignValueMapLens amap <- use $ crucPStateLens . assignValueMapLens
case MapF.lookup idx amap of case MapF.lookup idx amap of
Just (MacawCrucibleValue r) -> pure r Just (MacawCrucibleValue r) -> pure r
Nothing -> fail "internal: Assignment id is not bound." Nothing -> fail "internal: Assignment id is not bound."
-- |
mkHandleVal :: HandleId arch '(args,ret) mkHandleVal :: HandleId arch '(args,ret)
-> CrucGen arch ids s (C.FnHandle args ret) -> CrucGen arch ids s (C.FnHandle args ret)
mkHandleVal hid = do mkHandleVal hid = do
@ -380,7 +385,7 @@ readMem :: M.ArchAddrValue arch ids
readMem addr repr = do readMem addr repr = do
hndl <- mkHandleVal (ReadMemId repr) hndl <- mkHandleVal (ReadMemId repr)
caddr <- valueToCrucible addr caddr <- valueToCrucible addr
callFnHandle hndl (Ctx.empty Ctx.%> caddr) callFnHandle hndl (Empty :> caddr)
writeMem :: M.ArchAddrValue arch ids writeMem :: M.ArchAddrValue arch ids
-> M.MemRepr tp -> M.MemRepr tp
@ -390,8 +395,7 @@ writeMem addr repr val = do
hndl <- mkHandleVal (WriteMemId repr) hndl <- mkHandleVal (WriteMemId repr)
caddr <- valueToCrucible addr caddr <- valueToCrucible addr
cval <- valueToCrucible val cval <- valueToCrucible val
let args = Ctx.empty Ctx.%> caddr Ctx.%> cval void $ callFnHandle hndl (Empty :> caddr :> cval)
void $ callFnHandle hndl args
assignRhsToCrucible :: M.AssignRhs arch (M.Value arch ids) tp assignRhsToCrucible :: M.AssignRhs arch (M.Value arch ids) tp
-> CrucGen arch ids s (CR.Atom s (ToCrucibleType tp)) -> CrucGen arch ids s (CR.Atom s (ToCrucibleType tp))
@ -402,7 +406,7 @@ assignRhsToCrucible rhs =
M.ReadMem addr repr -> readMem addr repr M.ReadMem addr repr -> readMem addr repr
M.EvalArchFn f _ -> do M.EvalArchFn f _ -> do
fns <- translateFns <$> get fns <- translateFns <$> get
archTranslateFn fns f crucGenArchFn fns f
addMacawStmt :: M.Stmt arch ids -> CrucGen arch ids s () addMacawStmt :: M.Stmt arch ids -> CrucGen arch ids s ()
addMacawStmt stmt = addMacawStmt stmt =
@ -410,20 +414,22 @@ addMacawStmt stmt =
M.AssignStmt asgn -> do M.AssignStmt asgn -> do
let idx = M.assignId asgn let idx = M.assignId asgn
a <- assignRhsToCrucible (M.assignRhs asgn) a <- assignRhsToCrucible (M.assignRhs asgn)
assignValueMapLens %= MapF.insert idx (MacawCrucibleValue a) crucPStateLens . assignValueMapLens %= MapF.insert idx (MacawCrucibleValue a)
M.WriteMem addr repr val -> do M.WriteMem addr repr val -> do
writeMem addr repr val writeMem addr repr val
M.PlaceHolderStmt _vals msg -> do M.PlaceHolderStmt _vals msg -> do
cmsg <- crucibleValue (C.TextLit (Text.pack msg)) cmsg <- crucibleValue (C.TextLit (Text.pack msg))
addTermStmt (CR.ErrorStmt cmsg) addTermStmt (CR.ErrorStmt cmsg)
M.InstructionStart _addr _ -> do M.InstructionStart addr _ -> do
-- TODO: Fix this -- Update the position
pure () modify $ \s ->
crucGenArchConstraints (translateFns s) $
s { crucPos = C.BinaryPos (binaryPath (crucCtx s)) (fromIntegral addr) }
M.Comment _txt -> do M.Comment _txt -> do
pure () pure ()
M.ExecArchStmt astmt -> do M.ExecArchStmt astmt -> do
fns <- translateFns <$> get fns <- translateFns <$> get
archTranslateStmt fns astmt crucGenArchStmt fns astmt
lookupCrucibleLabel :: Word64 -> CrucGen arch ids s (CR.Label s) lookupCrucibleLabel :: Word64 -> CrucGen arch ids s (CR.Label s)
lookupCrucibleLabel idx = do lookupCrucibleLabel idx = do
@ -458,15 +464,17 @@ addMacawTermStmt tstmt =
addTermStmt (CR.Br p t f) addTermStmt (CR.Br p t f)
M.ArchTermStmt ts regs -> do M.ArchTermStmt ts regs -> do
fns <- translateFns <$> get fns <- translateFns <$> get
archTranslateTermStmt fns ts regs crucGenArchTermStmt fns ts regs
M.TranslateError _regs msg -> do M.TranslateError _regs msg -> do
cmsg <- crucibleValue (C.TextLit msg) cmsg <- crucibleValue (C.TextLit msg)
addTermStmt (CR.ErrorStmt cmsg) addTermStmt (CR.ErrorStmt cmsg)
-- | Type level monad for building blocks. -----------------
-- | Monad for adding new blocks to a state.
type MacawMonad arch ids s = ExceptT String (StateT (CrucPersistentState arch ids s) (ST s)) type MacawMonad arch ids s = ExceptT String (StateT (CrucPersistentState arch ids s) (ST s))
addMacawBlock :: ArchTranslateFunctions arch addMacawBlock :: CrucGenArchFunctions arch
-> CrucGenContext arch ids s -> CrucGenContext arch ids s
-> Word64 -> Word64
-- ^ Code address -- ^ Code address
@ -479,17 +487,17 @@ addMacawBlock tfns ctx addr b = do
case Map.lookup idx (macawIndexToLabelMap ctx) of case Map.lookup idx (macawIndexToLabelMap ctx) of
Just lbl -> pure lbl Just lbl -> pure lbl
Nothing -> throwError $ "Internal: Could not find block with index " ++ show idx Nothing -> throwError $ "Internal: Could not find block with index " ++ show idx
let s0 = CrucGenState { translateFns = tfns let s0 = CrucGenState { translateFns = tfns
, crucCtx = ctx , crucCtx = ctx
, crucPState = pstate , crucPState = pstate
, blockLabel = lbl , blockLabel = lbl
, macawBlockIndex = idx , crucPos = C.BinaryPos (binaryPath ctx) addr
, codeAddr = addr , prevStmts = []
, prevStmts = []
} }
let cont _s () = fail "Unterminated crucible block" let cont _s () = fail "Unterminated crucible block"
let action = do let action = do
mapM_ addMacawStmt (M.blockStmts b) mapM_ addMacawStmt (M.blockStmts b)
addMacawTermStmt (M.blockTerm b) addMacawTermStmt (M.blockTerm b)
r <- lift $ lift $ unContGen action s0 cont (ps, blk) <- lift $ lift $ unCrucGen action s0 cont
put r put $ ps & seenBlockMapLens %~ Map.insert idx blk

View File

@ -58,15 +58,14 @@ module Data.Macaw.Symbolic.PersistentState
, CrucSeenBlockMap , CrucSeenBlockMap
) where ) where
import Control.Lens import Control.Lens hiding (Index, (:>), Empty)
import qualified Data.Macaw.CFG as M import qualified Data.Macaw.CFG as M
import qualified Data.Macaw.Memory as M import qualified Data.Macaw.Memory as M
import qualified Data.Macaw.Types as M import qualified Data.Macaw.Types as M
import Data.Map.Strict (Map) import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Data.Parameterized.Classes import Data.Parameterized.Classes
import qualified Data.Parameterized.Context as Ctx import Data.Parameterized.Context
import Data.Parameterized.Ctx
import Data.Parameterized.Map (MapF) import Data.Parameterized.Map (MapF)
import qualified Data.Parameterized.Map as MapF import qualified Data.Parameterized.Map as MapF
import Data.Parameterized.NatRepr import Data.Parameterized.NatRepr
@ -94,6 +93,25 @@ type family CtxToCrucibleType (mtp :: Ctx M.Type) :: Ctx C.CrucibleType where
CtxToCrucibleType EmptyCtx = EmptyCtx CtxToCrucibleType EmptyCtx = EmptyCtx
CtxToCrucibleType (c ::> tp) = CtxToCrucibleType c ::> ToCrucibleType tp CtxToCrucibleType (c ::> tp) = CtxToCrucibleType c ::> ToCrucibleType tp
-- | Create the variables from a collection of registers.
macawAssignToCruc :: (forall tp . f tp -> g (ToCrucibleType tp))
-> Assignment f ctx
-> Assignment g (CtxToCrucibleType ctx)
macawAssignToCruc f a =
case a of
Empty -> empty
b :> x -> macawAssignToCruc f b :> f x
-- | Create the variables from a collection of registers.
macawAssignToCrucM :: Applicative m
=> (forall tp . f tp -> m (g (ToCrucibleType tp)))
-> Assignment f ctx
-> m (Assignment g (CtxToCrucibleType ctx))
macawAssignToCrucM f a =
case a of
Empty -> pure empty
b :> x -> (:>) <$> macawAssignToCrucM f b <*> f x
-- | Type family for arm registers -- | Type family for arm registers
type family ArchRegContext (arch :: *) :: Ctx M.Type type family ArchRegContext (arch :: *) :: Ctx M.Type
@ -109,36 +127,16 @@ type ArchAddrCrucibleType arch = C.BVType (M.ArchAddrWidth arch)
typeToCrucibleBase :: M.TypeRepr tp -> C.BaseTypeRepr (ToCrucibleBaseType tp) typeToCrucibleBase :: M.TypeRepr tp -> C.BaseTypeRepr (ToCrucibleBaseType tp)
typeToCrucibleBase tp = typeToCrucibleBase tp =
case tp of case tp of
M.BoolTypeRepr -> C.BaseBoolRepr M.BoolTypeRepr -> C.BaseBoolRepr
M.BVTypeRepr w -> C.BaseBVRepr w M.BVTypeRepr w -> C.BaseBVRepr w
-- M.TupleTypeRepr a -> C.BaseStructRepr (macawAssignToCruc tpyeToCrucibleBase a)
typeToCrucible :: M.TypeRepr tp -> C.TypeRepr (ToCrucibleType tp) typeToCrucible :: M.TypeRepr tp -> C.TypeRepr (ToCrucibleType tp)
typeToCrucible = C.baseToType . typeToCrucibleBase typeToCrucible = C.baseToType . typeToCrucibleBase
-- | Create the variables from a collection of registers.
macawAssignToCruc :: (forall tp . f tp -> g (ToCrucibleType tp))
-> Ctx.Assignment f ctx
-> Ctx.Assignment g (CtxToCrucibleType ctx)
macawAssignToCruc f a =
case Ctx.view a of
Ctx.AssignEmpty -> Ctx.empty
Ctx.AssignExtend b x -> macawAssignToCruc f b Ctx.%> f x
-- | Create the variables from a collection of registers.
macawAssignToCrucM :: Applicative m
=> (forall tp . f tp -> m (g (ToCrucibleType tp)))
-> Ctx.Assignment f ctx
-> m (Ctx.Assignment g (CtxToCrucibleType ctx))
macawAssignToCrucM f a =
case Ctx.view a of
Ctx.AssignEmpty -> pure Ctx.empty
Ctx.AssignExtend b x -> (Ctx.%>) <$> macawAssignToCrucM f b <*> f x
-- Return the types associated with a register assignment. -- Return the types associated with a register assignment.
typeCtxToCrucible :: Ctx.Assignment M.TypeRepr ctx typeCtxToCrucible :: Assignment M.TypeRepr ctx
-> Ctx.Assignment C.TypeRepr (CtxToCrucibleType ctx) -> Assignment C.TypeRepr (CtxToCrucibleType ctx)
typeCtxToCrucible = macawAssignToCruc typeToCrucible typeCtxToCrucible = macawAssignToCruc typeToCrucible
memReprToCrucible :: M.MemRepr tp -> C.TypeRepr (ToCrucibleType tp) memReprToCrucible :: M.MemRepr tp -> C.TypeRepr (ToCrucibleType tp)
@ -148,27 +146,27 @@ memReprToCrucible = typeToCrucible . M.typeRepr
-- RegIndexMap -- RegIndexMap
-- | This relates an index from macaw to Crucible. -- | This relates an index from macaw to Crucible.
data IndexPair ctx tp = IndexPair { macawIndex :: !(Ctx.Index ctx tp) data IndexPair ctx tp = IndexPair { macawIndex :: !(Index ctx tp)
, crucibleIndex :: !(Ctx.Index (CtxToCrucibleType ctx) (ToCrucibleType tp)) , crucibleIndex :: !(Index (CtxToCrucibleType ctx) (ToCrucibleType tp))
} }
-- | This extends the indices in the pair. -- | This extends the indices in the pair.
extendIndexPair :: IndexPair ctx tp -> IndexPair (ctx::>utp) tp extendIndexPair :: IndexPair ctx tp -> IndexPair (ctx::>utp) tp
extendIndexPair (IndexPair i j) = IndexPair (Ctx.extendIndex i) (Ctx.extendIndex j) extendIndexPair (IndexPair i j) = IndexPair (extendIndex i) (extendIndex j)
type RegIndexMap arch = MapF (M.ArchReg arch) (IndexPair (ArchRegContext arch)) type RegIndexMap arch = MapF (M.ArchReg arch) (IndexPair (ArchRegContext arch))
mkRegIndexMap :: OrdF r mkRegIndexMap :: OrdF r
=> Ctx.Assignment r ctx => Assignment r ctx
-> Ctx.Size (CtxToCrucibleType ctx) -> Size (CtxToCrucibleType ctx)
-> MapF r (IndexPair ctx) -> MapF r (IndexPair ctx)
mkRegIndexMap r0 csz = mkRegIndexMap r0 csz =
case (Ctx.view r0, Ctx.viewSize csz) of case (r0, viewSize csz) of
(Ctx.AssignEmpty, _) -> MapF.empty (Empty, _) -> MapF.empty
(Ctx.AssignExtend a r, Ctx.IncSize csz0) -> (a :> r, IncSize csz0) ->
let m = fmapF extendIndexPair (mkRegIndexMap a csz0) let m = fmapF extendIndexPair (mkRegIndexMap a csz0)
idx = IndexPair (Ctx.nextIndex (Ctx.size a)) (Ctx.nextIndex csz0) idx = IndexPair (nextIndex (size a)) (nextIndex csz0)
in MapF.insert r idx m in MapF.insert r idx m
------------------------------------------------------------------------ ------------------------------------------------------------------------
@ -189,7 +187,7 @@ data CrucGenContext arch ids s
= CrucGenContext = CrucGenContext
{ archConstraints :: !(forall a . (ArchConstraints arch => a) -> a) { archConstraints :: !(forall a . (ArchConstraints arch => a) -> a)
-- ^ Typeclass constraints for architecture -- ^ Typeclass constraints for architecture
, macawRegAssign :: !(Ctx.Assignment (M.ArchReg arch) (ArchRegContext arch)) , macawRegAssign :: !(Assignment (M.ArchReg arch) (ArchRegContext arch))
-- ^ Assignment from register to the context -- ^ Assignment from register to the context
, regIndexMap :: !(RegIndexMap arch) , regIndexMap :: !(RegIndexMap arch)
, handleAlloc :: !(C.HandleAllocator s) , handleAlloc :: !(C.HandleAllocator s)
@ -266,17 +264,17 @@ handleIdName h =
handleIdArgTypes :: CrucGenContext arch ids s handleIdArgTypes :: CrucGenContext arch ids s
-> HandleId arch '(args, ret) -> HandleId arch '(args, ret)
-> Ctx.Assignment C.TypeRepr args -> Assignment C.TypeRepr args
handleIdArgTypes ctx h = handleIdArgTypes ctx h =
case h of case h of
MkFreshSymId _repr -> Ctx.empty MkFreshSymId _repr -> empty
ReadMemId _repr -> archConstraints ctx $ ReadMemId _repr -> archConstraints ctx $
Ctx.empty Ctx.%> C.BVRepr (archWidthRepr ctx) empty :> C.BVRepr (archWidthRepr ctx)
WriteMemId repr -> archConstraints ctx $ WriteMemId repr -> archConstraints ctx $
Ctx.empty Ctx.%> C.BVRepr (archWidthRepr ctx) empty :> C.BVRepr (archWidthRepr ctx)
Ctx.%> memReprToCrucible repr :> memReprToCrucible repr
SyscallId -> SyscallId ->
Ctx.empty Ctx.%> regStructRepr ctx empty :> regStructRepr ctx
handleIdRetType :: CrucGenContext arch ids s handleIdRetType :: CrucGenContext arch ids s
-> HandleId arch '(args, ret) -> HandleId arch '(args, ret)
@ -326,11 +324,11 @@ data CrucPersistentState arch ids s
initCrucPersistentState :: forall arch ids s . CrucPersistentState arch ids s initCrucPersistentState :: forall arch ids s . CrucPersistentState arch ids s
initCrucPersistentState = initCrucPersistentState =
-- Infer number of arguments to function so that we have values skip inputs. -- Infer number of arguments to function so that we have values skip inputs.
let argCount :: Ctx.Size (MacawFunctionArgs arch) let argCount :: Size (MacawFunctionArgs arch)
argCount = Ctx.knownSize argCount = knownSize
in CrucPersistentState in CrucPersistentState
{ handleMap = MapF.empty { handleMap = MapF.empty
, valueCount = Ctx.sizeInt argCount , valueCount = sizeInt argCount
, assignValueMap = MapF.empty , assignValueMap = MapF.empty
, seenBlockMap = Map.empty , seenBlockMap = Map.empty
} }

View File

@ -30,6 +30,10 @@ module Data.Macaw.X86
, rootLoc , rootLoc
, disassembleBlock , disassembleBlock
, X86TranslateError(..) , X86TranslateError(..)
, Data.Macaw.X86.ArchTypes.X86_64
, Data.Macaw.X86.ArchTypes.X86PrimFn(..)
, Data.Macaw.X86.ArchTypes.X86Stmt(..)
, Data.Macaw.X86.ArchTypes.X86TermStmt(..)
, Data.Macaw.X86.X86Reg.X86Reg(..) , Data.Macaw.X86.X86Reg.X86Reg(..)
, Data.Macaw.X86.X86Reg.x86ArgumentRegs , Data.Macaw.X86.X86Reg.x86ArgumentRegs
, Data.Macaw.X86.X86Reg.x86ResultRegs , Data.Macaw.X86.X86Reg.x86ResultRegs

@ -1 +1 @@
Subproject commit f0d85b41cbcd68871b9f7557e49fdeb89c95419e Subproject commit 0d7a19fdbcefc4d7e97edb623bec549504d4f4d0