| Copyright | (c) Galois Inc 2018 |
|---|---|
| License | BSD3 |
| Maintainer | Joe Hendrix <jhendrix@galois.com> |
| Stability | provisional |
| Safe Haskell | None |
| Language | Haskell2010 |
Lang.Crucible.Simulator
Description
This module reexports the parts of the symbolic simulator codebase that are most relevant for users. Additional types and operations are exported from the relevant submodules if necessary.
Synopsis
- type family RegValue sym (tp :: CrucibleType) where ...
- newtype RegValue' sym (tp :: CrucibleType) = RV {}
- newtype VariantBranch sym (tp :: CrucibleType) = VB {}
- injectVariant :: forall sym (ctx :: Ctx CrucibleType) (tp :: CrucibleType). IsExprBuilder sym => sym -> CtxRepr ctx -> Index ctx tp -> RegValue sym tp -> RegValue sym (VariantType ctx)
- data AnyValue sym where
- AnyValue :: forall (tp :: CrucibleType) sym. TypeRepr tp -> RegValue sym tp -> AnyValue sym
- data FnVal sym (args :: Ctx CrucibleType) (res :: CrucibleType) where
- ClosureFnVal :: forall sym (args :: Ctx CrucibleType) (tp :: CrucibleType) (res :: CrucibleType). !(FnVal sym (args ::> tp) res) -> !(TypeRepr tp) -> !(RegValue sym tp) -> FnVal sym args res
- VarargsFnVal :: forall (args1 :: Ctx CrucibleType) (res :: CrucibleType) (addlArgs :: Ctx CrucibleType) sym. !(FnHandle (args1 ::> VectorType AnyType) res) -> !(CtxRepr addlArgs) -> FnVal sym (args1 <+> addlArgs) res
- HandleFnVal :: forall (args :: Ctx CrucibleType) (res :: CrucibleType) sym. !(FnHandle args res) -> FnVal sym args res
- fnValType :: forall sym (args :: Ctx CrucibleType) (res :: CrucibleType). FnVal sym args res -> TypeRepr (FunctionHandleType args res)
- newtype RolledType sym (nm :: Symbol) (ctx :: Ctx CrucibleType) = RolledType {
- unroll :: RegValue sym (UnrollType nm ctx)
- data RegEntry sym (tp :: CrucibleType) = RegEntry {}
- newtype RegMap sym (ctx :: Ctx CrucibleType) = RegMap {
- regMap :: Assignment (RegEntry sym) ctx
- emptyRegMap :: RegMap sym (EmptyCtx :: Ctx CrucibleType)
- regVal :: forall sym (ctx :: Ctx CrucibleType) (tp :: CrucibleType). RegMap sym ctx -> Reg ctx tp -> RegValue sym tp
- assignReg :: forall (tp :: CrucibleType) sym (ctx :: Ctx CrucibleType). TypeRepr tp -> RegValue sym tp -> RegMap sym ctx -> RegMap sym (ctx ::> tp)
- reg :: forall (n :: Nat) sym (ctx :: Ctx CrucibleType) (tp :: CrucibleType). Idx n ctx tp => RegMap sym ctx -> RegValue sym tp
- data SimErrorReason
- data SimError = SimError {}
- ppSimError :: SimError -> Doc ann
- data GlobalVar (tp :: CrucibleType) = GlobalVar {
- globalNonce :: !(Nonce GlobalNonceGenerator tp)
- globalName :: !Text
- globalType :: !(TypeRepr tp)
- data SymGlobalState sym
- emptyGlobals :: SymGlobalState sym
- data GlobalPair sym v = GlobalPair {
- _gpValue :: !v
- _gpGlobals :: !(SymGlobalState sym)
- gpValue :: forall sym u v f. Functor f => (u -> f v) -> GlobalPair sym u -> f (GlobalPair sym v)
- gpGlobals :: forall sym u f. Functor f => (SymGlobalState sym -> f (SymGlobalState sym)) -> GlobalPair sym u -> f (GlobalPair sym u)
- data AbortedResult sym ext where
- AbortedExec :: forall sym ext l (args :: Maybe (Ctx CrucibleType)). !AbortExecReason -> !(GlobalPair sym (SimFrame sym ext l args)) -> AbortedResult sym ext
- AbortedExit :: forall sym ext l (args :: Maybe (Ctx CrucibleType)). !ExitCode -> !(GlobalPair sym (SimFrame sym ext l args)) -> AbortedResult sym ext
- AbortedBranch :: forall sym ext. !ProgramLoc -> !(Pred sym) -> !(AbortedResult sym ext) -> !(AbortedResult sym ext) -> AbortedResult sym ext
- data PartialResult sym ext v
- = TotalRes !(GlobalPair sym v)
- | PartialRes !ProgramLoc !(Pred sym) !(GlobalPair sym v) !(AbortedResult sym ext)
- partialValue :: forall sym ext u v f. Functor f => (GlobalPair sym u -> f (GlobalPair sym v)) -> PartialResult sym ext u -> f (PartialResult sym ext v)
- data ExecResult p sym ext rtp
- = FinishedResult !(SimContext p sym ext) !(PartialResult sym ext rtp)
- | AbortedResult !(SimContext p sym ext) !(AbortedResult sym ext)
- | TimeoutResult !(ExecState p sym ext rtp)
- data ExecState p sym ext rtp
- = ResultState !(ExecResult p sym ext rtp)
- | AbortState !AbortExecReason !(SimState p sym ext rtp f a)
- | UnwindCallState !(ValueFromValue p sym ext rtp r) !(AbortedResult sym ext) !(SimState p sym ext rtp f a)
- | CallState !(ReturnHandler ret p sym ext rtp f a) !(ResolvedCall p sym ext ret) !(SimState p sym ext rtp f a)
- | TailCallState !(ValueFromValue p sym ext rtp ret) !(ResolvedCall p sym ext ret) !(SimState p sym ext rtp f a)
- | ReturnState !FunctionName !(ValueFromValue p sym ext rtp ret) !(RegEntry sym ret) !(SimState p sym ext rtp f a)
- | RunningState !(RunningStateInfo blocks args) !(SimState p sym ext rtp (CrucibleLang blocks r) ('Just args))
- | SymbolicBranchState !(Pred sym) !(PausedFrame p sym ext rtp f) !(PausedFrame p sym ext rtp f) !(CrucibleBranchTarget f postdom_args) !(SimState p sym ext rtp f ('Just args))
- | ControlTransferState !(ControlResumption p sym ext rtp f) !(SimState p sym ext rtp f ('Just a))
- | OverrideState !(Override p sym ext args ret) !(SimState p sym ext rtp (OverrideLang ret) ('Just args))
- | BranchMergeState !(CrucibleBranchTarget f args) !(SimState p sym ext rtp f args)
- | rtp ~ RegEntry sym ret => InitialState !(SimContext p sym ext) !(SymGlobalState sym) !(AbortHandler p sym ext (RegEntry sym ret)) !(TypeRepr ret) !(ExecCont p sym ext (RegEntry sym ret) (OverrideLang ret) ('Just (EmptyCtx :: Ctx CrucibleType)))
- type ExecCont p sym ext rtp f (args :: Maybe (Ctx CrucibleType)) = ReaderT (SimState p sym ext rtp f args) IO (ExecState p sym ext rtp)
- execResultContext :: ExecResult p sym ext r -> SimContext p sym ext
- data Override p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType) = Override {
- overrideName :: FunctionName
- overrideHandler :: forall r. ExecCont p sym ext r (OverrideLang ret) ('Just args)
- data FnState p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType)
- = UseOverride !(Override p sym ext args ret)
- | UseCFG !(CFG ext blocks args ret) !(CFGPostdom blocks)
- newtype FunctionBindings p sym ext = FnBindings {
- fnBindings :: FnHandleMap (FnState p sym ext)
- data ExtensionImpl p sym ext = ExtensionImpl {
- extensionEval :: forall bak rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType) (ctx :: Ctx CrucibleType). IsSymBackend sym bak => bak -> IntrinsicTypes sym -> (Int -> String -> IO ()) -> CrucibleState p sym ext rtp blocks r ctx -> EvalAppFunc sym (ExprExtension ext)
- extensionExec :: EvalStmtFunc p sym ext
- type EvalStmtFunc p sym ext = forall rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType) (ctx :: Ctx CrucibleType) (tp' :: CrucibleType). StmtExtension ext (RegEntry sym) tp' -> CrucibleState p sym ext rtp blocks r ctx -> IO (RegValue sym tp', CrucibleState p sym ext rtp blocks r ctx)
- emptyExtensionImpl :: ExtensionImpl p sym ()
- type IsSymInterfaceProof sym a = (IsSymInterface sym => a) -> a
- data SimContext p sym ext = SimContext {
- _ctxBackend :: !(SomeBackend sym)
- ctxSolverProof :: !(forall a. IsSymInterfaceProof sym a)
- ctxIntrinsicTypes :: !(IntrinsicTypes sym)
- simHandleAllocator :: !HandleAllocator
- printHandle :: !Handle
- extensionImpl :: ExtensionImpl p sym ext
- _functionBindings :: !(FunctionBindings p sym ext)
- _cruciblePersonality :: !p
- _profilingMetrics :: !(Map Text (Metric p sym ext))
- initSimContext :: IsSymBackend sym bak => bak -> IntrinsicTypes sym -> HandleAllocator -> Handle -> FunctionBindings personality sym ext -> ExtensionImpl personality sym ext -> personality -> SimContext personality sym ext
- ctxSymInterface :: forall p sym ext f. (Contravariant f, Functor f) => (sym -> f sym) -> SimContext p sym ext -> f (SimContext p sym ext)
- functionBindings :: forall p sym ext f. Functor f => (FunctionBindings p sym ext -> f (FunctionBindings p sym ext)) -> SimContext p sym ext -> f (SimContext p sym ext)
- cruciblePersonality :: forall p sym ext f. Functor f => (p -> f p) -> SimContext p sym ext -> f (SimContext p sym ext)
- profilingMetrics :: forall p sym ext f. Functor f => (Map Text (Metric p sym ext) -> f (Map Text (Metric p sym ext))) -> SimContext p sym ext -> f (SimContext p sym ext)
- data SimState p sym ext rtp f (args :: Maybe (Ctx CrucibleType))
- initSimState :: forall p sym ext (ret :: CrucibleType). SimContext p sym ext -> SymGlobalState sym -> AbortHandler p sym ext (RegEntry sym ret) -> TypeRepr ret -> IO (SimState p sym ext (RegEntry sym ret) (OverrideLang ret) ('Just (EmptyCtx :: Ctx CrucibleType)))
- defaultAbortHandler :: IsSymInterface sym => AbortHandler p sym ext rtp
- newtype AbortHandler p sym ext rtp = AH {
- runAH :: forall l (args :: Maybe (Ctx CrucibleType)). AbortExecReason -> ExecCont p sym ext rtp l args
- type CrucibleState p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (ret :: CrucibleType) (args :: Ctx CrucibleType) = SimState p sym ext rtp (CrucibleLang blocks ret) ('Just args)
- stateContext :: forall p sym ext r f1 (a :: Maybe (Ctx CrucibleType)) f2. Functor f2 => (SimContext p sym ext -> f2 (SimContext p sym ext)) -> SimState p sym ext r f1 a -> f2 (SimState p sym ext r f1 a)
- class IntrinsicClass sym (nm :: Symbol)
- data IntrinsicMuxFn sym (nm :: Symbol) where
- IntrinsicMuxFn :: forall sym (nm :: Symbol). IntrinsicClass sym nm => IntrinsicMuxFn sym nm
- type IntrinsicTypes sym = MapF SymbolRepr (IntrinsicMuxFn sym)
- emptyIntrinsicTypes :: IntrinsicTypes sym
- executeCrucible :: forall p sym ext rtp. (IsSymInterface sym, IsSyntaxExtension ext) => [ExecutionFeature p sym ext rtp] -> ExecState p sym ext rtp -> IO (ExecResult p sym ext rtp)
- singleStepCrucible :: (IsSymInterface sym, IsSyntaxExtension ext) => Int -> ExecState p sym ext rtp -> IO (ExecState p sym ext rtp)
- evalReg :: forall (m :: Type -> Type) (ctx :: Ctx CrucibleType) (tp :: CrucibleType) p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType). Monad m => Reg ctx tp -> ReaderT (CrucibleState p sym ext rtp blocks r ctx) m (RegValue sym tp)
- evalArgs :: forall (m :: Type -> Type) (ctx :: Ctx CrucibleType) (args :: Ctx CrucibleType) p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType). Monad m => Assignment (Reg ctx) args -> ReaderT (CrucibleState p sym ext rtp blocks r ctx) m (RegMap sym args)
- stepStmt :: forall p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType) (ctx :: Ctx CrucibleType) (ctx' :: Ctx CrucibleType). (IsSymInterface sym, IsSyntaxExtension ext) => Int -> Stmt ext ctx ctx' -> StmtSeq ext blocks r ctx' -> ExecCont p sym ext rtp (CrucibleLang blocks r) ('Just ctx)
- stepTerm :: forall p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType) (ctx :: Ctx CrucibleType). (IsSymInterface sym, IsSyntaxExtension ext) => Int -> TermStmt blocks r ctx -> ExecCont p sym ext rtp (CrucibleLang blocks r) ('Just ctx)
- stepBasicBlock :: forall sym ext p rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType) (ctx :: Ctx CrucibleType). (IsSymInterface sym, IsSyntaxExtension ext) => Int -> ExecCont p sym ext rtp (CrucibleLang blocks r) ('Just ctx)
- data ExecutionFeature p sym ext rtp
- data GenericExecutionFeature sym
- genericToExecutionFeature :: (IsSymInterface sym, IsSyntaxExtension ext) => GenericExecutionFeature sym -> ExecutionFeature p sym ext rtp
- timeoutFeature :: NominalDiffTime -> IO (GenericExecutionFeature sym)
- module Lang.Crucible.Simulator.OverrideSim
Register values
type family RegValue sym (tp :: CrucibleType) where ... Source #
Maps register types to the runtime representation.
Equations
| RegValue sym (BaseToType bt) = SymExpr sym bt | |
| RegValue sym (FloatType fi) = SymInterpretedFloat sym fi | |
| RegValue sym AnyType = AnyValue sym | |
| RegValue sym UnitType = () | |
| RegValue sym NatType = SymNat sym | |
| RegValue sym CharType = Word16 | |
| RegValue sym (FunctionHandleType a r) = FnVal sym a r | |
| RegValue sym (MaybeType tp) = PartExpr (Pred sym) (RegValue sym tp) | |
| RegValue sym (VectorType tp) = Vector (RegValue sym tp) | |
| RegValue sym (SequenceType tp) = SymSequence sym (RegValue sym tp) | |
| RegValue sym (StructType ctx) = Assignment (RegValue' sym) ctx | |
| RegValue sym (VariantType ctx) = Assignment (VariantBranch sym) ctx | |
| RegValue sym (ReferenceType tp) = MuxTree sym (RefCell tp) | |
| RegValue sym (WordMapType w tp) = WordMap sym w tp | |
| RegValue sym (RecursiveType nm ctx) = RolledType sym nm ctx | |
| RegValue sym (IntrinsicType nm ctx) = Intrinsic sym nm ctx | |
| RegValue sym (StringMapType tp) = Map Text (PartExpr (Pred sym) (RegValue sym tp)) |
newtype RegValue' sym (tp :: CrucibleType) Source #
A newtype wrapper around RegValue. This is wrapper necessary because RegValue is a type family and, as such, cannot be partially applied.
Variants
newtype VariantBranch sym (tp :: CrucibleType) Source #
Arguments
| :: forall sym (ctx :: Ctx CrucibleType) (tp :: CrucibleType). IsExprBuilder sym | |
| => sym | symbolic backend |
| -> CtxRepr ctx | Types of the variant branches |
| -> Index ctx tp | Which branch |
| -> RegValue sym tp | The value to inject |
| -> RegValue sym (VariantType ctx) |
Construct a VariantType value by identifying which branch of
the variant to construct, and providing a value of the correct type.
Any Values
data AnyValue sym where Source #
Constructors
| AnyValue :: forall (tp :: CrucibleType) sym. TypeRepr tp -> RegValue sym tp -> AnyValue sym |
Function Values
data FnVal sym (args :: Ctx CrucibleType) (res :: CrucibleType) where Source #
Represents a function closure.
Constructors
| ClosureFnVal :: forall sym (args :: Ctx CrucibleType) (tp :: CrucibleType) (res :: CrucibleType). !(FnVal sym (args ::> tp) res) -> !(TypeRepr tp) -> !(RegValue sym tp) -> FnVal sym args res | |
| VarargsFnVal :: forall (args1 :: Ctx CrucibleType) (res :: CrucibleType) (addlArgs :: Ctx CrucibleType) sym. !(FnHandle (args1 ::> VectorType AnyType) res) -> !(CtxRepr addlArgs) -> FnVal sym (args1 <+> addlArgs) res | |
| HandleFnVal :: forall (args :: Ctx CrucibleType) (res :: CrucibleType) sym. !(FnHandle args res) -> FnVal sym args res |
fnValType :: forall sym (args :: Ctx CrucibleType) (res :: CrucibleType). FnVal sym args res -> TypeRepr (FunctionHandleType args res) Source #
Extract the runtime representation of the type of the given FnVal
Recursive Values
newtype RolledType sym (nm :: Symbol) (ctx :: Ctx CrucibleType) Source #
Constructors
| RolledType | |
Fields
| |
Register maps
data RegEntry sym (tp :: CrucibleType) Source #
The value of a register.
newtype RegMap sym (ctx :: Ctx CrucibleType) Source #
A set of registers in an execution frame.
Constructors
| RegMap | |
Fields
| |
emptyRegMap :: RegMap sym (EmptyCtx :: Ctx CrucibleType) Source #
Create a new set of registers.
regVal :: forall sym (ctx :: Ctx CrucibleType) (tp :: CrucibleType). RegMap sym ctx -> Reg ctx tp -> RegValue sym tp Source #
assignReg :: forall (tp :: CrucibleType) sym (ctx :: Ctx CrucibleType). TypeRepr tp -> RegValue sym tp -> RegMap sym ctx -> RegMap sym (ctx ::> tp) Source #
reg :: forall (n :: Nat) sym (ctx :: Ctx CrucibleType) (tp :: CrucibleType). Idx n ctx tp => RegMap sym ctx -> RegValue sym tp Source #
SimError
data SimErrorReason Source #
Class for exceptions generated by simulator.
Constructors
| GenericSimError !String | |
| Unsupported !CallStack !String | We can't do that (yet?). The call stack identifies where in the Haskell code the error occured. |
| ReadBeforeWriteSimError !String | |
| AssertFailureSimError !String !String | An assertion failed. The first parameter is a short description. The second is a more detailed explanation. |
| ResourceExhausted String | A loop iteration count, or similar resource limit, was exceeded. |
Instances
| IsString SimErrorReason Source # | |
Defined in Lang.Crucible.Simulator.SimError Methods fromString :: String -> SimErrorReason # | |
| Show SimErrorReason Source # | |
Defined in Lang.Crucible.Simulator.SimError Methods showsPrec :: Int -> SimErrorReason -> ShowS # show :: SimErrorReason -> String # showList :: [SimErrorReason] -> ShowS # | |
Constructors
| SimError | |
Fields | |
Instances
| Exception SimError Source # | |
Defined in Lang.Crucible.Simulator.SimError Methods toException :: SimError -> SomeException # fromException :: SomeException -> Maybe SimError # displayException :: SimError -> String # | |
| Show SimError Source # | |
ppSimError :: SimError -> Doc ann Source #
SimGlobalState
data GlobalVar (tp :: CrucibleType) Source #
A global variable.
Constructors
| GlobalVar | |
Fields
| |
Instances
data SymGlobalState sym Source #
A map from global variables to their value.
emptyGlobals :: SymGlobalState sym Source #
The empty set of global variable bindings.
GlobalPair
data GlobalPair sym v Source #
A value of some type v together with a global state.
Type parameters:
sym: instance ofIsSymInterfacev: type of the value
Constructors
| GlobalPair | |
Fields
| |
gpValue :: forall sym u v f. Functor f => (u -> f v) -> GlobalPair sym u -> f (GlobalPair sym v) Source #
Access the value stored in the global pair.
gpGlobals :: forall sym u f. Functor f => (SymGlobalState sym -> f (SymGlobalState sym)) -> GlobalPair sym u -> f (GlobalPair sym u) Source #
Access the globals stored in the global pair.
AbortedResult
data AbortedResult sym ext where Source #
An execution path that was prematurely aborted. Note, an abort does not necessarily indicate an error condition. An execution path might abort because it became infeasible (inconsistent path conditions), because the program called an exit primitive, or because of a true error condition (e.g., a failed assertion).
Type parameters:
sym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extension
Constructors
| AbortedExec :: forall sym ext l (args :: Maybe (Ctx CrucibleType)). !AbortExecReason -> !(GlobalPair sym (SimFrame sym ext l args)) -> AbortedResult sym ext | A single aborted execution with the execution state at time of the abort and the reason. |
| AbortedExit :: forall sym ext l (args :: Maybe (Ctx CrucibleType)). !ExitCode -> !(GlobalPair sym (SimFrame sym ext l args)) -> AbortedResult sym ext | An aborted execution that was ended by a call to |
| AbortedBranch :: forall sym ext. !ProgramLoc -> !(Pred sym) -> !(AbortedResult sym ext) -> !(AbortedResult sym ext) -> AbortedResult sym ext | Two separate threads of execution aborted after a symbolic branch, possibly for different reasons. |
Partial result
data PartialResult sym ext v Source #
A PartialResult represents the result of a computation that
might be only partially defined. If the result is a TotalResult,
the the result is fully defined; however if it is a
PartialResult, then some of the computation paths that led to
this result aborted for some reason, and the resulting value is
only defined if the associated condition is true.
Type parameters:
sym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extensionv: Type of the result of the computation
Constructors
| TotalRes !(GlobalPair sym v) | A |
| PartialRes !ProgramLoc !(Pred sym) !(GlobalPair sym v) !(AbortedResult sym ext) |
|
partialValue :: forall sym ext u v f. Functor f => (GlobalPair sym u -> f (GlobalPair sym v)) -> PartialResult sym ext u -> f (PartialResult sym ext v) Source #
Access the value stored in the partial result.
Execution states
data ExecResult p sym ext rtp Source #
Executions that have completed either due to (partial or total) successful completion or by some abort condition.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extensionrtp: type of the return value
Constructors
| FinishedResult !(SimContext p sym ext) !(PartialResult sym ext rtp) | At least one execution path resulted in some return result. |
| AbortedResult !(SimContext p sym ext) !(AbortedResult sym ext) | All execution paths resulted in an abort condition, and there is no result to return. |
| TimeoutResult !(ExecState p sym ext rtp) | An execution stopped somewhere in the middle of a run because a timeout condition occurred. |
data ExecState p sym ext rtp Source #
An ExecState represents an intermediate state of executing a
Crucible program. The Crucible simulator executes by transitioning
between these different states until it results in a ResultState,
indicating the program has completed.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extensionrtp: type of the return value
Constructors
| ResultState !(ExecResult p sym ext rtp) | The |
| AbortState !AbortExecReason !(SimState p sym ext rtp f a) | An abort state indicates that the included |
| UnwindCallState !(ValueFromValue p sym ext rtp r) !(AbortedResult sym ext) !(SimState p sym ext rtp f a) | An unwind call state occurs when we are about to leave the context of a
function call because of an abort. The included |
| CallState !(ReturnHandler ret p sym ext rtp f a) !(ResolvedCall p sym ext ret) !(SimState p sym ext rtp f a) | A call state is entered when we are about to make a function call to the included call frame, which has already resolved the implementation and arguments to the function. |
| TailCallState !(ValueFromValue p sym ext rtp ret) !(ResolvedCall p sym ext ret) !(SimState p sym ext rtp f a) | A tail-call state is entered when we are about to make a function call to the included call frame, and this is the last action we need to take in the current caller. Note, we can only enter a tail-call state if there are no pending merge points in the caller. This means that sometimes calls that appear to be in tail-call position may nonetheless have to be treated as ordinary calls. |
| ReturnState !FunctionName !(ValueFromValue p sym ext rtp ret) !(RegEntry sym ret) !(SimState p sym ext rtp f a) | A return state is entered after the final return value of a function is computed, and just before we resolve injecting the return value back into the caller's context. |
| RunningState !(RunningStateInfo blocks args) !(SimState p sym ext rtp (CrucibleLang blocks r) ('Just args)) | A running state indicates the included |
| SymbolicBranchState !(Pred sym) !(PausedFrame p sym ext rtp f) !(PausedFrame p sym ext rtp f) !(CrucibleBranchTarget f postdom_args) !(SimState p sym ext rtp f ('Just args)) | A symbolic branch state indicates that the execution needs to
branch on a non-trivial symbolic condition. The included |
| ControlTransferState !(ControlResumption p sym ext rtp f) !(SimState p sym ext rtp f ('Just a)) | A control transfer state is entered just prior to invoking a control resumption. Control resumptions are responsible for transitioning from the end of one basic block to another, although there are also some intermediate states related to resolving switch statements. |
| OverrideState !(Override p sym ext args ret) !(SimState p sym ext rtp (OverrideLang ret) ('Just args)) | An override state indicates the included |
| BranchMergeState !(CrucibleBranchTarget f args) !(SimState p sym ext rtp f args) | A branch merge state occurs when the included |
| rtp ~ RegEntry sym ret => InitialState !(SimContext p sym ext) !(SymGlobalState sym) !(AbortHandler p sym ext (RegEntry sym ret)) !(TypeRepr ret) !(ExecCont p sym ext (RegEntry sym ret) (OverrideLang ret) ('Just (EmptyCtx :: Ctx CrucibleType))) | An initial state indicates the state of a simulator just before execution begins.
It specifies all the initial data necessary to begin simulating. The given
|
type ExecCont p sym ext rtp f (args :: Maybe (Ctx CrucibleType)) = ReaderT (SimState p sym ext rtp f args) IO (ExecState p sym ext rtp) Source #
An action which will construct an ExecState given a current
SimState. Such continuations correspond to a single transition
of the simulator transition system.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extensionrtp: type of the return valuef: the type of the top frame (CrucibleLangorOverrideLang)args: arguments to the current frame (seeSimFrame)
execResultContext :: ExecResult p sym ext r -> SimContext p sym ext Source #
Simulator context
Function bindings
data Override p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType) Source #
A definition of a function's semantics, given as a Haskell action.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extensionargs: types of arguments to the overrideret: return type of the override
Constructors
| Override | |
Fields
| |
data FnState p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType) Source #
State used to indicate what to do when function is called. A function
may either be defined by writing a Haskell Override or by giving
a Crucible control-flow graph representation.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extensionargs: argument typesret: return type
Constructors
| UseOverride !(Override p sym ext args ret) | |
| UseCFG !(CFG ext blocks args ret) !(CFGPostdom blocks) |
newtype FunctionBindings p sym ext Source #
A map from function handles to their semantics.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extension
Constructors
| FnBindings | |
Fields
| |
Extensions
data ExtensionImpl p sym ext Source #
In order to start executing a simulator, one must provide an implementation of the extension syntax. This includes an evaluator for the added expression forms, and an evaluator for the added statement forms.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extension
Constructors
| ExtensionImpl | |
Fields
| |
type EvalStmtFunc p sym ext = forall rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType) (ctx :: Ctx CrucibleType) (tp' :: CrucibleType). StmtExtension ext (RegEntry sym) tp' -> CrucibleState p sym ext rtp blocks r ctx -> IO (RegValue sym tp', CrucibleState p sym ext rtp blocks r ctx) Source #
The type of functions that interpret extension statements. These have access to the main simulator state, and can make fairly arbitrary changes to it.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extension
emptyExtensionImpl :: ExtensionImpl p sym () Source #
Trivial implementation for the "empty" extension, which adds no additional syntactic forms.
SimContext record
type IsSymInterfaceProof sym a = (IsSymInterface sym => a) -> a Source #
data SimContext p sym ext Source #
Top-level state record for the simulator. The state contained in this record remains persistent across all symbolic simulator actions. In particular, it is not rolled back when the simulator returns previous program points to explore additional paths, etc.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extension
Constructors
| SimContext | |
Fields
| |
Arguments
| :: IsSymBackend sym bak | |
| => bak | Symbolic backend |
| -> IntrinsicTypes sym | Implementations of intrinsic types |
| -> HandleAllocator | Handle allocator for creating new function handles |
| -> Handle | Handle to write output to |
| -> FunctionBindings personality sym ext | Initial bindings for function handles |
| -> ExtensionImpl personality sym ext | Semantics for extension syntax |
| -> personality | Initial value for custom user state |
| -> SimContext personality sym ext |
Create a new SimContext with the given bindings.
ctxSymInterface :: forall p sym ext f. (Contravariant f, Functor f) => (sym -> f sym) -> SimContext p sym ext -> f (SimContext p sym ext) Source #
Access the symbolic backend inside a SimContext.
functionBindings :: forall p sym ext f. Functor f => (FunctionBindings p sym ext -> f (FunctionBindings p sym ext)) -> SimContext p sym ext -> f (SimContext p sym ext) Source #
A map from function handles to their semantics.
cruciblePersonality :: forall p sym ext f. Functor f => (p -> f p) -> SimContext p sym ext -> f (SimContext p sym ext) Source #
Custom state inside the SimContext.
Crucible itself is entirely polymorphic over p. Downstream applications can
instantiate it to any sort of state that they would like to associate with a
SimContext.
For example, applications based on
macaw-symbolic
can instantiate this to a structure holding enough information to perform
incremental code discovery. See ambient-verifier's
AmbientSimulatorState.
Code that needs to store some state in the personality but doesn't wish to fix a particular type can use the "classy lenses" approach, e.g.,
class HasFooState p where
fooState :: Lens' p FooState
For examples of this approach, see
profilingMetrics :: forall p sym ext f. Functor f => (Map Text (Metric p sym ext) -> f (Map Text (Metric p sym ext))) -> SimContext p sym ext -> f (SimContext p sym ext) Source #
SimState
data SimState p sym ext rtp f (args :: Maybe (Ctx CrucibleType)) Source #
A SimState contains the execution context, an error handler, and the current execution tree. It captures the entire state of the symbolic simulator.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extensionrtp: type of the return valuef: the type of the top frame (CrucibleLangorOverrideLang)args: arguments to the current frame (seeSimFrame)
Instances
| MonadState (SimState p sym ext rtp (OverrideLang ret) ('Just args)) (OverrideSim p sym ext rtp args ret) Source # | |
Defined in Lang.Crucible.Simulator.OverrideSim Methods get :: OverrideSim p sym ext rtp args ret (SimState p sym ext rtp (OverrideLang ret) ('Just args)) # put :: SimState p sym ext rtp (OverrideLang ret) ('Just args) -> OverrideSim p sym ext rtp args ret () # state :: (SimState p sym ext rtp (OverrideLang ret) ('Just args) -> (a, SimState p sym ext rtp (OverrideLang ret) ('Just args))) -> OverrideSim p sym ext rtp args ret a # | |
Arguments
| :: forall p sym ext (ret :: CrucibleType). SimContext p sym ext | initial |
| -> SymGlobalState sym | state of Crucible global variables |
| -> AbortHandler p sym ext (RegEntry sym ret) | initial abort handler |
| -> TypeRepr ret | |
| -> IO (SimState p sym ext (RegEntry sym ret) (OverrideLang ret) ('Just (EmptyCtx :: Ctx CrucibleType))) |
Create an initial SimState
defaultAbortHandler :: IsSymInterface sym => AbortHandler p sym ext rtp Source #
The default abort handler calls abortExecAndLog.
newtype AbortHandler p sym ext rtp Source #
An abort handler indicates to the simulator what actions to take
when an abort occurs. Usually, one should simply use the
defaultAbortHandler from Lang.Crucible.Simulator, which
unwinds the tree context to the nearest branch point and
correctly resumes simulation. However, for some use cases, it
may be desirable to take additional or alternate actions on abort
events; in which case, the library user may replace the default
abort handler with their own.
Type parameters:
p: seecruciblePersonalitysym: instance ofIsSymInterfaceext: language extension, see Lang.Crucible.CFG.Extensionrtp: type of the return value
Constructors
| AH | |
Fields
| |
type CrucibleState p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (ret :: CrucibleType) (args :: Ctx CrucibleType) = SimState p sym ext rtp (CrucibleLang blocks ret) ('Just args) Source #
A simulator state that is currently executing Crucible instructions.
stateContext :: forall p sym ext r f1 (a :: Maybe (Ctx CrucibleType)) f2. Functor f2 => (SimContext p sym ext -> f2 (SimContext p sym ext)) -> SimState p sym ext r f1 a -> f2 (SimState p sym ext r f1 a) Source #
Access the SimContext inside a SimState
Intrinsic types
class IntrinsicClass sym (nm :: Symbol) Source #
Type family for intrinsic type representations. Intrinsic types
are identified by a type-level Symbol, and this typeclass allows
backends to define implementations for these types.
An instance of this class defines both an instance for the
Intrinsic type family (which defines the runtime representation
for this intrinsic type) and also the muxIntrinsic method
(which defines how to merge to intrinsic values when the simulator
reaches a merge point).
Note: Instances of this will typically end up as orphan instances.
This warning is normally quite important, as orphan instances allow
one to define multiple instances for a particular class. However, in
this case, IntrinsicClass contains a type family, and GHC will globally
check consistency of all type family instances. Consequently, there
can be at most one implementation of IntrinsicClass in a program.
Minimal complete definition
Instances
| IntrinsicClass sym "BoundedExecFrameData" Source # | |
Defined in Lang.Crucible.Simulator.BoundedExec Methods pushBranchIntrinsic :: forall (ctx :: Ctx CrucibleType). sym -> IntrinsicTypes sym -> SymbolRepr "BoundedExecFrameData" -> CtxRepr ctx -> Intrinsic sym "BoundedExecFrameData" ctx -> IO (Intrinsic sym "BoundedExecFrameData" ctx) Source # abortBranchIntrinsic :: forall (ctx :: Ctx CrucibleType). sym -> IntrinsicTypes sym -> SymbolRepr "BoundedExecFrameData" -> CtxRepr ctx -> Intrinsic sym "BoundedExecFrameData" ctx -> IO (Intrinsic sym "BoundedExecFrameData" ctx) Source # muxIntrinsic :: forall (ctx :: Ctx CrucibleType). sym -> IntrinsicTypes sym -> SymbolRepr "BoundedExecFrameData" -> CtxRepr ctx -> Pred sym -> Intrinsic sym "BoundedExecFrameData" ctx -> Intrinsic sym "BoundedExecFrameData" ctx -> IO (Intrinsic sym "BoundedExecFrameData" ctx) Source # | |
| IntrinsicClass sym "BoundedRecursionData" Source # | |
Defined in Lang.Crucible.Simulator.BoundedRecursion Methods pushBranchIntrinsic :: forall (ctx :: Ctx CrucibleType). sym -> IntrinsicTypes sym -> SymbolRepr "BoundedRecursionData" -> CtxRepr ctx -> Intrinsic sym "BoundedRecursionData" ctx -> IO (Intrinsic sym "BoundedRecursionData" ctx) Source # abortBranchIntrinsic :: forall (ctx :: Ctx CrucibleType). sym -> IntrinsicTypes sym -> SymbolRepr "BoundedRecursionData" -> CtxRepr ctx -> Intrinsic sym "BoundedRecursionData" ctx -> IO (Intrinsic sym "BoundedRecursionData" ctx) Source # muxIntrinsic :: forall (ctx :: Ctx CrucibleType). sym -> IntrinsicTypes sym -> SymbolRepr "BoundedRecursionData" -> CtxRepr ctx -> Pred sym -> Intrinsic sym "BoundedRecursionData" ctx -> Intrinsic sym "BoundedRecursionData" ctx -> IO (Intrinsic sym "BoundedRecursionData" ctx) Source # | |
data IntrinsicMuxFn sym (nm :: Symbol) where Source #
The IntrinsicMuxFn datatype allows an IntrinsicClass instance
to be packaged up into a value. This allows us to get access to IntrinsicClass
instance methods (the muxIntrinsic method in particular) at runtime even
for symbol names that are not known statically.
By packaging up a type class instance (rather than just providing some method with the
same signature as muxIntrinsic) we get the compiler to ensure that a single
distinguished implementation is always used for each backend/symbol name combination.
This prevents any possible confusion between different parts of the system.
Constructors
| IntrinsicMuxFn :: forall sym (nm :: Symbol). IntrinsicClass sym nm => IntrinsicMuxFn sym nm |
type IntrinsicTypes sym = MapF SymbolRepr (IntrinsicMuxFn sym) Source #
IntrinsicTypes is a map from symbol name representatives to IntrinsicMuxFn
values. Such a map is useful for providing access to intrinsic type implementations
that are not known statically at compile time.
emptyIntrinsicTypes :: IntrinsicTypes sym Source #
An empty collection of intrinsic types, for cases where no additional types are required
Evaluation
Arguments
| :: forall p sym ext rtp. (IsSymInterface sym, IsSyntaxExtension ext) | |
| => [ExecutionFeature p sym ext rtp] | Execution features to install |
| -> ExecState p sym ext rtp | Execution state to begin executing |
| -> IO (ExecResult p sym ext rtp) |
Given a SimState and an execution continuation,
apply the continuation and execute the resulting
computation until completion.
This function is responsible for catching
AbortExecReason exceptions and UserError
exceptions and invoking the errorHandler
contained in the state.
Arguments
| :: (IsSymInterface sym, IsSyntaxExtension ext) | |
| => Int | Current verbosity |
| -> ExecState p sym ext rtp | |
| -> IO (ExecState p sym ext rtp) |
Run a single step of the Crucible symbolic simulator.
evalReg :: forall (m :: Type -> Type) (ctx :: Ctx CrucibleType) (tp :: CrucibleType) p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType). Monad m => Reg ctx tp -> ReaderT (CrucibleState p sym ext rtp blocks r ctx) m (RegValue sym tp) Source #
Retrieve the value of a register.
evalArgs :: forall (m :: Type -> Type) (ctx :: Ctx CrucibleType) (args :: Ctx CrucibleType) p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType). Monad m => Assignment (Reg ctx) args -> ReaderT (CrucibleState p sym ext rtp blocks r ctx) m (RegMap sym args) Source #
Evaluate the actual arguments for a function call or block transfer.
Arguments
| :: forall p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType) (ctx :: Ctx CrucibleType) (ctx' :: Ctx CrucibleType). (IsSymInterface sym, IsSyntaxExtension ext) | |
| => Int | Current verbosity |
| -> Stmt ext ctx ctx' | Statement to evaluate |
| -> StmtSeq ext blocks r ctx' | Remaining statements in the block |
| -> ExecCont p sym ext rtp (CrucibleLang blocks r) ('Just ctx) |
Evaluation operation for evaluating a single straight-line statement of the Crucible evaluator.
This is allowed to throw user exceptions or SimError.
Arguments
| :: forall p sym ext rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType) (ctx :: Ctx CrucibleType). (IsSymInterface sym, IsSyntaxExtension ext) | |
| => Int | Verbosity |
| -> TermStmt blocks r ctx | Terminating statement to evaluate |
| -> ExecCont p sym ext rtp (CrucibleLang blocks r) ('Just ctx) |
Evaluation operation for evaluating a single block-terminator statement of the Crucible evaluator.
This is allowed to throw user exceptions or SimError.
Arguments
| :: forall sym ext p rtp (blocks :: Ctx (Ctx CrucibleType)) (r :: CrucibleType) (ctx :: Ctx CrucibleType). (IsSymInterface sym, IsSyntaxExtension ext) | |
| => Int | Current verbosity |
| -> ExecCont p sym ext rtp (CrucibleLang blocks r) ('Just ctx) |
Main evaluation operation for running a single step of basic block evaluation.
This is allowed to throw user exceptions or SimError.
data ExecutionFeature p sym ext rtp Source #
An execution feature represents a computation that is allowed to intercept
the processing of execution states to perform additional processing at
each intermediate state. A list of execution features is accepted by
executeCrucible. After each step of the simulator, the execution features
are consulted, each in turn. After all the execution features have run,
the main simulator code is executed to advance the simulator one step.
If an execution feature wishes to make changes to the execution
state before further execution happens, the return value can be
used to return a modified state. If this happens, the current
stack of execution features is abandoned and a fresh step starts
over immediately from the top of the execution features. In
essence, each execution feature can preempt all following
execution features and the main simulator loop. In other words,
the main simulator only gets reached if every execution feature
returns Nothing. It is important, therefore, that execution
features make only a bounded number of modification in a row, or
the main simulator loop will be starved out.
data GenericExecutionFeature sym Source #
A generic execution feature is an execution feature that is
agnostic to the execution environment, and is therefore
polymorphic over the p, ext and rtp variables.
genericToExecutionFeature :: (IsSymInterface sym, IsSyntaxExtension ext) => GenericExecutionFeature sym -> ExecutionFeature p sym ext rtp Source #
timeoutFeature :: NominalDiffTime -> IO (GenericExecutionFeature sym) Source #
This feature will terminate the execution of a crucible simulator
with a TimeoutResult after a given interval of wall-clock time
has elapsed.