crucible-debug-0.1.0: src/Lang/Crucible/Debug/Command/Base.hs
{-|
Copyright : (c) Galois, Inc. 2025
Maintainer : Langston Barrett <langston@galois.com>
-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-}
module Lang.Crucible.Debug.Command.Base
( BaseCommand(..)
, name
, abbrev
, detail
, help
, regex
-- * Regular expressions
, rBacktrace
, rBlock
, rBreak
, rCall
, rCfg
, rClear
, rComment
, rDelete
, rDone
, rFinish
, rFrame
, rHelp
, rLoad
, rLocation
, rObligation
, rPathCondition
, rProve
, rQuit
, rRegister
, rRun
, SecretRegex
, rSecret
, rSource
, rStep
, rTrace
, rUsage
) where
import Data.Parameterized.Classes (knownRepr)
import Data.Parameterized.Some (Some(Some))
import Data.Text (Text)
import Lang.Crucible.Debug.Arg.Type (ArgTypeRepr)
import Lang.Crucible.Debug.Arg.Type qualified as AType
import Lang.Crucible.Debug.Regex qualified as Rgx
import Prettyprinter qualified as PP
data BaseCommand
= Backtrace
| Block
| Break
| Call
| Cfg
| Clear
| Comment
| Delete
| Done
| Finish
| Frame
| Help
| Load
| Location
| Obligation
| PathCondition
| Prove
| Quit
| Register
| Run
| Secret
| Source
| Step
| Trace
| Usage
deriving (Bounded, Enum, Show)
instance PP.Pretty BaseCommand where
pretty = PP.pretty . name
name :: BaseCommand -> Text
name =
\case
Backtrace -> "backtrace"
Block -> "block"
Break -> "break"
Call -> "call"
Cfg -> "cfg"
Clear -> "clear"
Comment -> "#"
Delete -> "delete"
Done -> "done"
Finish -> "finish"
Frame -> "frame"
Help -> "help"
Load -> "load"
Location -> "location"
Obligation -> "obligation"
PathCondition -> "path-condition"
Prove -> "prove"
Quit -> "quit"
Register -> "register"
Run -> "run"
Secret -> "secret"
Step -> "step"
Source -> "source"
Trace -> "trace"
Usage -> "usage"
abbrev :: BaseCommand -> Text
abbrev =
\case
Backtrace -> "bt"
Block -> "blk"
Break -> "b"
Call -> "cl"
Cfg -> "cg"
Clear -> "cr"
Comment -> "#"
Delete -> "d"
Done -> "done"
Finish -> "fh"
Frame -> "fr"
Help -> "h"
Load -> "l"
Location -> "loc"
Obligation -> "o"
PathCondition -> "pcond"
Prove -> "p"
Quit -> "q"
Register -> "reg"
Run -> "r"
Secret -> "."
Step -> "s"
Source -> "src"
Trace -> "trace"
Usage -> "u"
-- | See 'Lang.Crucible.Debug.Command.extDetail'
detail :: BaseCommand -> Maybe Text
detail =
\case
Backtrace -> Nothing
Block -> Nothing
Break -> Nothing
Call -> Nothing
Cfg -> Nothing
Clear -> Nothing
Comment -> Nothing
Delete -> Nothing
Done -> Nothing
Finish -> Nothing
Frame -> Nothing
Help -> Nothing
Load -> Nothing
Location -> Nothing
Obligation -> Nothing
PathCondition -> Nothing
Prove -> Nothing
Quit -> Nothing
Register -> Just "\
\When given no arguments, prints all values in scope. \
\Otherwise, prints the values with the given numbers, one per line.\
\\n\n\
\The value numbering scheme is based on the structure of Crucible CFGs. \
\A Crucible CFG (function) is made up of *basic blocks*. \
\Each basic block takes a list of arguments. \
\The first block in the function is the *entry* block; \
\the entry block takes the same arguments as the function. \
\Each block contains a number of *statements*, which may define values. \
\The value defined by a statement is in scope for the rest of the block.\
\\n\n\
\Values are then numbered as follows: \
\The first argument to the current block is numbered 0. \
\Increasing numbers refer to later arguments. \
\After arguments, higher numbers refer to values defined by statements.\
\"
Run -> Nothing
Secret -> Nothing
Step -> Nothing
Source -> Nothing
Trace -> Nothing
Usage -> Nothing
-- | See 'Lang.Crucible.Debug.Command.extHelp'
help :: BaseCommand -> Text
help =
\case
Backtrace -> "Print the backtrace (AKA stack trace)"
Block -> "Print the statements in the current block"
Break -> "Set a breakpoint at the entry to a function"
Call -> "Call a function (must take no arguments and return the unit type)"
Cfg -> "Print the CFG of a function (the current function if none is provided)"
Clear -> "Drop the current proof obligations"
Comment -> "Ignore all arguments and do nothing"
Delete -> "Remove a breakpoint"
Done -> "Like `quit`, but only applies when symbolic execution has finished"
Finish -> "Execute to the end of the current function"
Frame -> "Print information about the active stack frame"
Help -> "Display help text"
Load -> "Load a Crucible S-expression program from a file"
Location -> "Print the current program location"
Obligation -> "Print the current proof obligations"
PathCondition -> "Print the current path condition"
Prove -> "Prove the current goals"
Quit -> "Exit the debugger"
Register -> "Print registers (including block/function arguments)"
Run -> "Continue to the next breakpoint or the end of execution"
Secret -> "Maintenance commands, used for testing"
Step -> "Continue N steps of execution (default: 1)"
Source -> "Execute a file containing debugger commands"
Trace -> "Print the N most recently executed basic blocks (default: 2)"
Usage -> "Display command usage hint"
regex :: BaseCommand -> Some (Rgx.RegexRepr ArgTypeRepr)
regex =
\case
Backtrace -> Some rBacktrace
Block -> Some rBlock
Break -> Some rBreak
Call -> Some rCall
Cfg -> Some rCfg
Clear -> Some rClear
Comment -> Some rComment
Delete -> Some rDelete
Done -> Some rDone
Finish -> Some rFinish
Frame -> Some rFrame
Help -> Some rHelp
Load -> Some rLoad
Location -> Some rLocation
Obligation -> Some rObligation
PathCondition -> Some rPathCondition
Prove -> Some rProve
Quit -> Some rQuit
Register -> Some rRegister
Run -> Some rRun
Secret -> Some rSecret
Step -> Some rStep
Source -> Some rSource
Trace -> Some rTrace
Usage -> Some rUsage
rBacktrace :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rBacktrace = knownRepr
rBlock :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rBlock = knownRepr
rBreak :: Rgx.RegexRepr ArgTypeRepr AType.Function
rBreak = knownRepr
rCall :: Rgx.RegexRepr ArgTypeRepr AType.Function
rCall = knownRepr
rCfg :: Rgx.RegexRepr ArgTypeRepr (Rgx.Empty Rgx.:| AType.Function)
rCfg = knownRepr
rClear :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rClear = knownRepr
rComment :: Rgx.RegexRepr ArgTypeRepr (Rgx.Star AType.Text)
rComment = knownRepr
rDelete :: Rgx.RegexRepr ArgTypeRepr AType.Breakpoint
rDelete = knownRepr
rDone :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rDone = knownRepr
rFinish :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rFinish = knownRepr
rFrame :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rFrame = knownRepr
rHelp :: Rgx.RegexRepr ArgTypeRepr (Rgx.Empty Rgx.:| AType.Command)
rHelp = knownRepr
rLoad :: Rgx.RegexRepr ArgTypeRepr AType.Path
rLoad = knownRepr
rLocation :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rLocation = knownRepr
rObligation :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rObligation = knownRepr
rPathCondition :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rPathCondition = knownRepr
rProve :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rProve = knownRepr
rQuit :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rQuit = knownRepr
rRegister :: Rgx.RegexRepr ArgTypeRepr (Rgx.Star AType.Int)
rRegister = knownRepr
rRun :: Rgx.RegexRepr ArgTypeRepr Rgx.Empty
rRun = knownRepr
type CompleteRegex
= Rgx.Then (AType.Exactly "complete") (Rgx.Then AType.Command (Rgx.Star AType.Text))
type StyleRegex
= Rgx.Then (AType.Exactly "style") (Rgx.Then AType.Command (Rgx.Star AType.Text))
type SecretRegex
= CompleteRegex Rgx.:| StyleRegex
rSecret :: Rgx.RegexRepr ArgTypeRepr SecretRegex
rSecret = knownRepr
rSource :: Rgx.RegexRepr ArgTypeRepr AType.Path
rSource = knownRepr
rStep :: Rgx.RegexRepr ArgTypeRepr (Rgx.Empty Rgx.:| AType.Int)
rStep = knownRepr
rTrace :: Rgx.RegexRepr ArgTypeRepr (Rgx.Empty Rgx.:| AType.Int)
rTrace = knownRepr
rUsage :: Rgx.RegexRepr ArgTypeRepr AType.Command
rUsage = knownRepr