mirror of
https://github.com/GaloisInc/macaw.git
synced 2024-12-28 08:34:23 +03:00
Drop support for branches within blocks.
This commit is contained in:
parent
f8c43540c1
commit
3331a19571
@ -28,8 +28,7 @@ install:
|
|||||||
|
|
||||||
# Here starts the actual work to be performed for the package under test;
|
# Here starts the actual work to be performed for the package under test;
|
||||||
# any command which exits with a non-zero exit code causes the build to fail.
|
# any command which exits with a non-zero exit code causes the build to fail.
|
||||||
script:
|
# Build packages that we do not want to check warnings on.
|
||||||
# Build crucible with no -Werror
|
|
||||||
- stack build crucible
|
- stack build crucible
|
||||||
# Build packages
|
# Build packages
|
||||||
- stack build --ghc-options="-Wall -Werror"
|
- stack build --ghc-options="-Wall -Werror"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name: macaw-base
|
name: macaw-base
|
||||||
version: 0.3.5
|
version: 0.3.6
|
||||||
author: Galois, Inc.
|
author: Galois, Inc.
|
||||||
maintainer: jhendrix@galois.com
|
maintainer: jhendrix@galois.com
|
||||||
build-type: Simple
|
build-type: Simple
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
{-|
|
{-|
|
||||||
Copyright : (c) Galois, Inc 2016
|
|
||||||
Maintainer : jhendrix@galois.com
|
|
||||||
|
|
||||||
This defines the architecture-specific information needed for code discovery.
|
This defines the architecture-specific information needed for code discovery.
|
||||||
-}
|
-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
@ -19,11 +16,9 @@ module Data.Macaw.Architecture.Info
|
|||||||
import Control.Monad.ST
|
import Control.Monad.ST
|
||||||
import Data.Parameterized.Nonce
|
import Data.Parameterized.Nonce
|
||||||
import Data.Parameterized.TraversableF
|
import Data.Parameterized.TraversableF
|
||||||
import Data.Semigroup ( (<>) )
|
|
||||||
import Data.Sequence (Seq)
|
import Data.Sequence (Seq)
|
||||||
|
|
||||||
import Data.Macaw.AbsDomain.AbsState as AbsState
|
import Data.Macaw.AbsDomain.AbsState as AbsState
|
||||||
import Data.Macaw.CFG.App
|
|
||||||
import Data.Macaw.CFG.Block
|
import Data.Macaw.CFG.Block
|
||||||
import Data.Macaw.CFG.Core
|
import Data.Macaw.CFG.Core
|
||||||
import Data.Macaw.CFG.DemandSet
|
import Data.Macaw.CFG.DemandSet
|
||||||
@ -51,7 +46,7 @@ type DisassembleFn arch
|
|||||||
-- ^ Initial values to use for registers.
|
-- ^ Initial values to use for registers.
|
||||||
-> Int
|
-> Int
|
||||||
-- ^ Maximum offset for this to read from.
|
-- ^ Maximum offset for this to read from.
|
||||||
-> ST s ([Block arch ids], Int, Maybe String)
|
-> ST s (Block arch ids, Int)
|
||||||
|
|
||||||
-- | This records architecture specific functions for analysis.
|
-- | This records architecture specific functions for analysis.
|
||||||
data ArchitectureInfo arch
|
data ArchitectureInfo arch
|
||||||
@ -174,13 +169,6 @@ rewriteTermStmt info tstmt = do
|
|||||||
case tstmt of
|
case tstmt of
|
||||||
FetchAndExecute regs ->
|
FetchAndExecute regs ->
|
||||||
FetchAndExecute <$> traverseF rewriteValue regs
|
FetchAndExecute <$> traverseF rewriteValue regs
|
||||||
Branch c t f -> do
|
|
||||||
tgtCond <- rewriteValue c
|
|
||||||
case () of
|
|
||||||
_ | Just (NotApp cn) <- valueAsApp tgtCond -> do
|
|
||||||
pure $ Branch cn f t
|
|
||||||
| otherwise ->
|
|
||||||
pure $ Branch tgtCond t f
|
|
||||||
TranslateError regs msg ->
|
TranslateError regs msg ->
|
||||||
TranslateError <$> traverseF rewriteValue regs
|
TranslateError <$> traverseF rewriteValue regs
|
||||||
<*> pure msg
|
<*> pure msg
|
||||||
@ -190,16 +178,15 @@ rewriteTermStmt info tstmt = do
|
|||||||
|
|
||||||
-- | Apply optimizations to code in the block
|
-- | Apply optimizations to code in the block
|
||||||
rewriteBlock :: ArchitectureInfo arch
|
rewriteBlock :: ArchitectureInfo arch
|
||||||
-> (RewriteContext arch s src tgt, [Block arch tgt])
|
-> RewriteContext arch s src tgt
|
||||||
-> Block arch src
|
-> Block arch src
|
||||||
-> ST s (RewriteContext arch s src tgt, [Block arch tgt])
|
-> ST s (RewriteContext arch s src tgt, Block arch tgt)
|
||||||
rewriteBlock info (rwctx,blks) b = do
|
rewriteBlock info rwctx b = do
|
||||||
(rwctx', newBlks, tgtStmts, tgtTermStmt) <- runRewriter rwctx $ do
|
(rwctx', tgtStmts, tgtTermStmt) <- runRewriter rwctx $ do
|
||||||
mapM_ rewriteStmt (blockStmts b)
|
mapM_ rewriteStmt (blockStmts b)
|
||||||
rewriteTermStmt info (blockTerm b)
|
rewriteTermStmt info (blockTerm b)
|
||||||
-- Return rewritten block and any new blocks
|
-- Return rewritten block and any new blocks
|
||||||
let rwBlock = Block { blockLabel = blockLabel b
|
let rwBlock = Block { blockStmts = tgtStmts
|
||||||
, blockStmts = tgtStmts
|
|
||||||
, blockTerm = tgtTermStmt
|
, blockTerm = tgtTermStmt
|
||||||
}
|
}
|
||||||
in pure (rwctx', rwBlock : (newBlks <> blks))
|
pure (rwctx', rwBlock)
|
||||||
|
@ -9,18 +9,16 @@ types.
|
|||||||
{-# LANGUAGE UndecidableInstances #-}
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
|
|
||||||
module Data.Macaw.CFG.Block
|
module Data.Macaw.CFG.Block
|
||||||
( Block(..), BlockLabel
|
( Block(..)
|
||||||
, ppBlock
|
, ppBlock
|
||||||
, TermStmt(..)
|
, TermStmt(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as Text
|
import qualified Data.Text as Text
|
||||||
import Data.Word
|
|
||||||
import Text.PrettyPrint.ANSI.Leijen as PP hiding ((<$>))
|
import Text.PrettyPrint.ANSI.Leijen as PP hiding ((<$>))
|
||||||
|
|
||||||
import Data.Macaw.CFG.Core
|
import Data.Macaw.CFG.Core
|
||||||
import Data.Macaw.Types
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
-- TermStmt
|
-- TermStmt
|
||||||
@ -32,8 +30,6 @@ import Data.Macaw.Types
|
|||||||
data TermStmt arch ids
|
data TermStmt arch ids
|
||||||
-- | Fetch and execute the next instruction from the given processor state.
|
-- | Fetch and execute the next instruction from the given processor state.
|
||||||
= FetchAndExecute !(RegState (ArchReg arch) (Value arch ids))
|
= FetchAndExecute !(RegState (ArchReg arch) (Value arch ids))
|
||||||
-- | Branch and execute one block or another.
|
|
||||||
| Branch !(Value arch ids BoolType) !BlockLabel !BlockLabel
|
|
||||||
-- | The block ended prematurely due to an error in instruction
|
-- | The block ended prematurely due to an error in instruction
|
||||||
-- decoding or translation.
|
-- decoding or translation.
|
||||||
--
|
--
|
||||||
@ -52,8 +48,6 @@ instance ArchConstraints arch
|
|||||||
pretty (FetchAndExecute s) =
|
pretty (FetchAndExecute s) =
|
||||||
text "fetch_and_execute" <$$>
|
text "fetch_and_execute" <$$>
|
||||||
indent 2 (pretty s)
|
indent 2 (pretty s)
|
||||||
pretty (Branch c x y) =
|
|
||||||
text "branch" <+> ppValue 0 c <+> text (show x) <+> text (show y)
|
|
||||||
pretty (TranslateError s msg) =
|
pretty (TranslateError s msg) =
|
||||||
text "ERROR: " <+> text (Text.unpack msg) <$$>
|
text "ERROR: " <+> text (Text.unpack msg) <$$>
|
||||||
indent 2 (pretty s)
|
indent 2 (pretty s)
|
||||||
@ -63,22 +57,15 @@ instance ArchConstraints arch
|
|||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
-- Block
|
-- Block
|
||||||
|
|
||||||
-- | The type of labels for each block
|
|
||||||
type BlockLabel = Word64
|
|
||||||
|
|
||||||
-- | The type for code blocks returned by the disassembler.
|
-- | The type for code blocks returned by the disassembler.
|
||||||
--
|
--
|
||||||
-- The discovery process will attempt to map each block to a suitable ParsedBlock.
|
-- The discovery process will attempt to map each block to a suitable ParsedBlock.
|
||||||
data Block arch ids
|
data Block arch ids
|
||||||
= Block { blockLabel :: !BlockLabel
|
= Block { blockStmts :: !([Stmt arch ids])
|
||||||
-- ^ Index of this block
|
|
||||||
, blockStmts :: !([Stmt arch ids])
|
|
||||||
-- ^ List of statements in the block.
|
-- ^ List of statements in the block.
|
||||||
, blockTerm :: !(TermStmt arch ids)
|
, blockTerm :: !(TermStmt arch ids)
|
||||||
-- ^ The last statement in the block.
|
-- ^ The last statement in the block.
|
||||||
}
|
}
|
||||||
|
|
||||||
ppBlock :: ArchConstraints arch => Block arch ids -> Doc
|
ppBlock :: ArchConstraints arch => Block arch ids -> Doc
|
||||||
ppBlock b =
|
ppBlock b = vcat (ppStmt (text . show) <$> blockStmts b) <$$> pretty (blockTerm b)
|
||||||
text (show (blockLabel b)) PP.<> text ":" <$$>
|
|
||||||
indent 2 (vcat (ppStmt (text . show) <$> blockStmts b) <$$> pretty (blockTerm b))
|
|
||||||
|
@ -31,7 +31,6 @@ module Data.Macaw.CFG.Rewriter
|
|||||||
, rewriteApp
|
, rewriteApp
|
||||||
, evalRewrittenArchFn
|
, evalRewrittenArchFn
|
||||||
, appendRewrittenArchStmt
|
, appendRewrittenArchStmt
|
||||||
, addNewBlockFromRewrite
|
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
@ -51,7 +50,7 @@ import Data.STRef
|
|||||||
|
|
||||||
import Data.Macaw.CFG
|
import Data.Macaw.CFG
|
||||||
import Data.Macaw.Types
|
import Data.Macaw.Types
|
||||||
import Data.Macaw.CFG.Block ( TermStmt, Block(..), BlockLabel )
|
import Data.Macaw.CFG.Block (TermStmt)
|
||||||
|
|
||||||
-- | Information needed for rewriting.
|
-- | Information needed for rewriting.
|
||||||
data RewriteContext arch s src tgt
|
data RewriteContext arch s src tgt
|
||||||
@ -90,11 +89,6 @@ data RewriteContext arch s src tgt
|
|||||||
-- of the assignments can be eliminated this
|
-- of the assignments can be eliminated this
|
||||||
-- should be done via a dead code elimination step
|
-- should be done via a dead code elimination step
|
||||||
-- rather than during rewriting.
|
-- rather than during rewriting.
|
||||||
|
|
||||||
, rwctxBlockLabel :: BlockLabel
|
|
||||||
-- ^ The next assignable BlockLabel (used for
|
|
||||||
-- rewrites that create new blocks, as would be
|
|
||||||
-- needed for Branch TermStmts.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mkRewriteContext :: RegisterInfo (ArchReg arch)
|
mkRewriteContext :: RegisterInfo (ArchReg arch)
|
||||||
@ -112,10 +106,8 @@ mkRewriteContext :: RegisterInfo (ArchReg arch)
|
|||||||
-- Discovery.hs.
|
-- Discovery.hs.
|
||||||
-> Map SectionIndex (ArchSegmentOff arch)
|
-> Map SectionIndex (ArchSegmentOff arch)
|
||||||
-- ^ Map from loaded section indices to their address.
|
-- ^ Map from loaded section indices to their address.
|
||||||
-> BlockLabel
|
|
||||||
-- ^ next BlockLabel (useable for creating new Block entries)
|
|
||||||
-> ST s (RewriteContext arch s src tgt)
|
-> ST s (RewriteContext arch s src tgt)
|
||||||
mkRewriteContext nonceGen archFn archStmt termStmt secAddrMap nextBlockLabel = do
|
mkRewriteContext nonceGen archFn archStmt termStmt secAddrMap = do
|
||||||
ref <- newSTRef MapF.empty
|
ref <- newSTRef MapF.empty
|
||||||
pure $! RewriteContext { rwctxNonceGen = nonceGen
|
pure $! RewriteContext { rwctxNonceGen = nonceGen
|
||||||
, rwctxArchFn = archFn
|
, rwctxArchFn = archFn
|
||||||
@ -124,7 +116,6 @@ mkRewriteContext nonceGen archFn archStmt termStmt secAddrMap nextBlockLabel = d
|
|||||||
, rwctxConstraints = \a -> a
|
, rwctxConstraints = \a -> a
|
||||||
, rwctxSectionAddrMap = secAddrMap
|
, rwctxSectionAddrMap = secAddrMap
|
||||||
, rwctxCache = ref
|
, rwctxCache = ref
|
||||||
, rwctxBlockLabel = nextBlockLabel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | State used by rewriter for tracking states
|
-- | State used by rewriter for tracking states
|
||||||
@ -132,21 +123,12 @@ data RewriteState arch s src tgt
|
|||||||
= RewriteState { -- | Access to the context for the rewriter
|
= RewriteState { -- | Access to the context for the rewriter
|
||||||
rwContext :: !(RewriteContext arch s src tgt)
|
rwContext :: !(RewriteContext arch s src tgt)
|
||||||
, _rwRevStmts :: ![Stmt arch tgt]
|
, _rwRevStmts :: ![Stmt arch tgt]
|
||||||
, _rwNewBlocks :: ![Block arch tgt]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | A list of statements in the current block in reverse order.
|
-- | A list of statements in the current block in reverse order.
|
||||||
rwRevStmts :: Simple Lens (RewriteState arch s src tgt) [Stmt arch tgt]
|
rwRevStmts :: Simple Lens (RewriteState arch s src tgt) [Stmt arch tgt]
|
||||||
rwRevStmts = lens _rwRevStmts (\s v -> s { _rwRevStmts = v })
|
rwRevStmts = lens _rwRevStmts (\s v -> s { _rwRevStmts = v })
|
||||||
|
|
||||||
-- | A list of newly created Blocks generated during the rewrite operation.
|
|
||||||
rwNewBlocks :: Simple Lens (RewriteState arch s src tgt) [Block arch tgt]
|
|
||||||
rwNewBlocks = lens _rwNewBlocks (\s v -> s { _rwNewBlocks = v })
|
|
||||||
|
|
||||||
-- | The next BlockLabel to use for newly created Blocks generated during the rewrite.
|
|
||||||
rwBlockLabel :: Simple Lens (RewriteState arch s src tgt) BlockLabel
|
|
||||||
rwBlockLabel = lens (rwctxBlockLabel . rwContext) (\s v -> s { rwContext = (rwContext s) { rwctxBlockLabel = v }})
|
|
||||||
|
|
||||||
-- | Monad for constant propagation within a block.
|
-- | Monad for constant propagation within a block.
|
||||||
newtype Rewriter arch s src tgt a = Rewriter { unRewriter :: StateT (RewriteState arch s src tgt) (ST s) a }
|
newtype Rewriter arch s src tgt a = Rewriter { unRewriter :: StateT (RewriteState arch s src tgt) (ST s) a }
|
||||||
deriving (Functor, Applicative, Monad)
|
deriving (Functor, Applicative, Monad)
|
||||||
@ -156,17 +138,15 @@ newtype Rewriter arch s src tgt a = Rewriter { unRewriter :: StateT (RewriteStat
|
|||||||
runRewriter :: RewriteContext arch s src tgt
|
runRewriter :: RewriteContext arch s src tgt
|
||||||
-> Rewriter arch s src tgt (TermStmt arch tgt)
|
-> Rewriter arch s src tgt (TermStmt arch tgt)
|
||||||
-> ST s ( RewriteContext arch s src tgt
|
-> ST s ( RewriteContext arch s src tgt
|
||||||
, [Block arch tgt]
|
|
||||||
, [Stmt arch tgt]
|
, [Stmt arch tgt]
|
||||||
, (TermStmt arch tgt))
|
, (TermStmt arch tgt))
|
||||||
runRewriter ctx m = do
|
runRewriter ctx m = do
|
||||||
let s = RewriteState { rwContext = ctx
|
let s = RewriteState { rwContext = ctx
|
||||||
, _rwRevStmts = []
|
, _rwRevStmts = []
|
||||||
, _rwNewBlocks = []
|
|
||||||
}
|
}
|
||||||
m' = rwctxTermStmt ctx =<< m
|
m' = rwctxTermStmt ctx =<< m
|
||||||
(r, s') <- runStateT (unRewriter m') s
|
(r, s') <- runStateT (unRewriter m') s
|
||||||
pure (rwContext s', _rwNewBlocks s', reverse (_rwRevStmts s'), r)
|
pure (rwContext s', reverse (_rwRevStmts s'), r)
|
||||||
|
|
||||||
-- | Add a statement to the list
|
-- | Add a statement to the list
|
||||||
appendRewrittenStmt :: Stmt arch tgt -> Rewriter arch s src tgt ()
|
appendRewrittenStmt :: Stmt arch tgt -> Rewriter arch s src tgt ()
|
||||||
@ -180,23 +160,6 @@ appendRewrittenStmt stmt = Rewriter $ do
|
|||||||
appendRewrittenArchStmt :: ArchStmt arch (Value arch tgt) -> Rewriter arch s src tgt ()
|
appendRewrittenArchStmt :: ArchStmt arch (Value arch tgt) -> Rewriter arch s src tgt ()
|
||||||
appendRewrittenArchStmt = appendRewrittenStmt . ExecArchStmt
|
appendRewrittenArchStmt = appendRewrittenStmt . ExecArchStmt
|
||||||
|
|
||||||
|
|
||||||
-- | If the rewriting needs to add a new 'Block' (e.g. for a 'Branch'
|
|
||||||
-- target) it does so by calling this function with that 'Block'.
|
|
||||||
addNewBlockFromRewrite :: [Stmt arch tgt]
|
|
||||||
-> TermStmt arch tgt
|
|
||||||
-> Rewriter arch s src tgt (BlockLabel)
|
|
||||||
addNewBlockFromRewrite stmts termstmt = Rewriter $ do
|
|
||||||
blkLabel <- use rwBlockLabel
|
|
||||||
let blk = Block { blockLabel = blkLabel
|
|
||||||
, blockStmts = stmts
|
|
||||||
, blockTerm = termstmt
|
|
||||||
}
|
|
||||||
rwNewBlocks %= (:) blk
|
|
||||||
rwBlockLabel += 1
|
|
||||||
return blkLabel
|
|
||||||
|
|
||||||
|
|
||||||
-- | Add an assignment statement that evaluates the right hand side and return the resulting value.
|
-- | Add an assignment statement that evaluates the right hand side and return the resulting value.
|
||||||
evalRewrittenRhs :: AssignRhs arch (Value arch tgt) tp -> Rewriter arch s src tgt (Value arch tgt tp)
|
evalRewrittenRhs :: AssignRhs arch (Value arch tgt) tp -> Rewriter arch s src tgt (Value arch tgt tp)
|
||||||
evalRewrittenRhs rhs = Rewriter $ do
|
evalRewrittenRhs rhs = Rewriter $ do
|
||||||
|
@ -169,8 +169,6 @@ addTermDemands t = do
|
|||||||
case t of
|
case t of
|
||||||
FetchAndExecute regs -> do
|
FetchAndExecute regs -> do
|
||||||
traverseF_ addValueDemands regs
|
traverseF_ addValueDemands regs
|
||||||
Branch v _ _ -> do
|
|
||||||
addValueDemands v
|
|
||||||
TranslateError regs _ -> do
|
TranslateError regs _ -> do
|
||||||
traverseF_ addValueDemands regs
|
traverseF_ addValueDemands regs
|
||||||
ArchTermStmt _ regs -> do
|
ArchTermStmt _ regs -> do
|
||||||
@ -812,8 +810,6 @@ data ParseContext arch ids =
|
|||||||
-- ^ Address of function this block is being parsed as
|
-- ^ Address of function this block is being parsed as
|
||||||
, pctxAddr :: !(ArchSegmentOff arch)
|
, pctxAddr :: !(ArchSegmentOff arch)
|
||||||
-- ^ Address of the current block
|
-- ^ Address of the current block
|
||||||
, pctxBlockMap :: !(Map BlockLabel (Block arch ids))
|
|
||||||
-- ^ Map from block indices to block code at address.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Get the memory representation associated with pointers in the
|
-- | Get the memory representation associated with pointers in the
|
||||||
@ -1142,30 +1138,6 @@ parseBlock ctx idx initRegs b absProcState = do
|
|||||||
let ainfo = pctxArchInfo ctx
|
let ainfo = pctxArchInfo ctx
|
||||||
withArchConstraints ainfo $ do
|
withArchConstraints ainfo $ do
|
||||||
case blockTerm b of
|
case blockTerm b of
|
||||||
Branch c lb rb -> do
|
|
||||||
let blockMap = pctxBlockMap ctx
|
|
||||||
-- FIXME: we should propagate c back to the initial block, not just b
|
|
||||||
let absProcState' = absEvalStmts ainfo absProcState (blockStmts b)
|
|
||||||
mapM_ (recordWriteStmt ainfo mem absProcState') (blockStmts b)
|
|
||||||
|
|
||||||
let Just l = Map.lookup lb blockMap
|
|
||||||
let l_regs = refineProcStateBounds c True $ refineProcState c absTrue absProcState'
|
|
||||||
let Just r = Map.lookup rb blockMap
|
|
||||||
let r_regs = refineProcStateBounds c False $ refineProcState c absFalse absProcState'
|
|
||||||
|
|
||||||
let l_regs' = absEvalStmts ainfo l_regs (blockStmts b)
|
|
||||||
let r_regs' = absEvalStmts ainfo r_regs (blockStmts b)
|
|
||||||
|
|
||||||
(parsedTrueBlock,trueIdx) <- parseBlock ctx (idx+1) initRegs l l_regs'
|
|
||||||
(parsedFalseBlock,falseIdx) <- parseBlock ctx trueIdx initRegs r r_regs'
|
|
||||||
|
|
||||||
let ret = StatementList { stmtsIdent = idx
|
|
||||||
, stmtsNonterm = blockStmts b
|
|
||||||
, stmtsTerm = ParsedIte c parsedTrueBlock parsedFalseBlock
|
|
||||||
, stmtsAbsState = absProcState'
|
|
||||||
}
|
|
||||||
pure (ret, falseIdx)
|
|
||||||
|
|
||||||
FetchAndExecute finalRegs -> do
|
FetchAndExecute finalRegs -> do
|
||||||
parseFetchAndExecute ctx idx initRegs (Seq.fromList (blockStmts b)) absProcState finalRegs
|
parseFetchAndExecute ctx idx initRegs (Seq.fromList (blockStmts b)) absProcState finalRegs
|
||||||
|
|
||||||
@ -1200,32 +1172,27 @@ parseBlock ctx idx initRegs b absProcState = do
|
|||||||
|
|
||||||
-- | This evaluates the statements in a block to expand the information known
|
-- | This evaluates the statements in a block to expand the information known
|
||||||
-- about control flow targets of this block.
|
-- about control flow targets of this block.
|
||||||
addBlocks :: ArchSegmentOff arch
|
addBlock :: ArchSegmentOff arch
|
||||||
-- ^ Address of these blocks
|
-- ^ Address of these blocks
|
||||||
-> FoundAddr arch
|
-> FoundAddr arch
|
||||||
-- ^ State leading to explore block
|
-- ^ State leading to explore block
|
||||||
-> RegState (ArchReg arch) (Value arch ids)
|
-> RegState (ArchReg arch) (Value arch ids)
|
||||||
-> Int
|
-> Int
|
||||||
-- ^ Number of blocks covered
|
-- ^ Number of bytes in block
|
||||||
-> Map BlockLabel (Block arch ids)
|
-> Block arch ids
|
||||||
-- ^ Map from labelIndex to associated block
|
-- ^ Map from labelIndex to associated block
|
||||||
-> FunM arch s ids ()
|
-> FunM arch s ids ()
|
||||||
addBlocks src finfo initRegs sz blockMap =
|
addBlock src finfo initRegs sz b = do
|
||||||
case Map.lookup 0 blockMap of
|
s <- use curFunCtx
|
||||||
Nothing -> do
|
let mem = memory s
|
||||||
error $ "addBlocks given empty blockRegion."
|
|
||||||
Just b -> do
|
|
||||||
mem <- uses curFunCtx memory
|
|
||||||
let regs = initAbsProcessorState mem (foundAbstractState finfo)
|
let regs = initAbsProcessorState mem (foundAbstractState finfo)
|
||||||
funAddr <- gets curFunAddr
|
funAddr <- gets curFunAddr
|
||||||
s <- use curFunCtx
|
|
||||||
|
|
||||||
let ctx = ParseContext { pctxMemory = memory s
|
let ctx = ParseContext { pctxMemory = memory s
|
||||||
, pctxArchInfo = archInfo s
|
, pctxArchInfo = archInfo s
|
||||||
, pctxKnownFnEntries = s^.trustedFunctionEntryPoints
|
, pctxKnownFnEntries = s^.trustedFunctionEntryPoints
|
||||||
, pctxFunAddr = funAddr
|
, pctxFunAddr = funAddr
|
||||||
, pctxAddr = src
|
, pctxAddr = src
|
||||||
, pctxBlockMap = blockMap
|
|
||||||
}
|
}
|
||||||
let ps0 = ParseState { _writtenCodeAddrs = []
|
let ps0 = ParseState { _writtenCodeAddrs = []
|
||||||
, _intraJumpTargets = []
|
, _intraJumpTargets = []
|
||||||
@ -1286,30 +1253,22 @@ transfer addr = do
|
|||||||
Left msg -> do
|
Left msg -> do
|
||||||
recordErrorBlock addr finfo (Just msg)
|
recordErrorBlock addr finfo (Just msg)
|
||||||
Right initRegs -> do
|
Right initRegs -> do
|
||||||
(bs0, sz, maybeError) <- liftST $ disassembleFn ainfo nonceGen addr initRegs maxSize
|
(b0, sz) <- liftST $ disassembleFn ainfo nonceGen addr initRegs maxSize
|
||||||
-- If no blocks are returned, then we just add an empty parsed block.
|
-- If no blocks are returned, then we just add an empty parsed block.
|
||||||
if null bs0 then do
|
|
||||||
recordErrorBlock addr finfo maybeError
|
|
||||||
else do
|
|
||||||
-- Rewrite returned blocks to simplify expressions
|
-- Rewrite returned blocks to simplify expressions
|
||||||
#ifdef USE_REWRITER
|
#ifdef USE_REWRITER
|
||||||
bs1 <- snd <$> do
|
(_,b) <- do
|
||||||
let archStmt = rewriteArchStmt ainfo
|
let archStmt = rewriteArchStmt ainfo
|
||||||
let secAddrMap = memSectionIndexMap mem
|
let secAddrMap = memSectionIndexMap mem
|
||||||
termStmt <- gets termStmtRewriter <*> pure addr
|
termStmt <- gets termStmtRewriter <*> pure addr
|
||||||
let maxBlockLabel = maximum $ map blockLabel bs0
|
|
||||||
liftST $ do
|
liftST $ do
|
||||||
ctx <- mkRewriteContext nonceGen (rewriteArchFn ainfo)
|
ctx <- mkRewriteContext nonceGen (rewriteArchFn ainfo) archStmt termStmt secAddrMap
|
||||||
archStmt termStmt secAddrMap (maxBlockLabel + 1)
|
rewriteBlock ainfo ctx b0
|
||||||
foldM (rewriteBlock ainfo) (ctx, []) bs0
|
|
||||||
#else
|
#else
|
||||||
bs1 <- pure bs0
|
b <- pure b0
|
||||||
#endif
|
#endif
|
||||||
-- Compute demand set
|
|
||||||
let bs = bs1 -- eliminateDeadStmts ainfo bs1
|
|
||||||
-- Call transfer blocks to calculate parsedblocks
|
-- Call transfer blocks to calculate parsedblocks
|
||||||
let blockMap = Map.fromList [ (blockLabel b, b) | b <- bs ]
|
addBlock addr finfo initRegs sz b
|
||||||
addBlocks addr finfo initRegs sz blockMap
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
-- Main loop
|
-- Main loop
|
||||||
|
@ -264,22 +264,15 @@ addBlocksCFG :: forall h s arch ids
|
|||||||
-- ^ Address of start of block
|
-- ^ Address of start of block
|
||||||
-> (M.ArchAddrWord arch -> C.Position)
|
-> (M.ArchAddrWord arch -> C.Position)
|
||||||
-- ^ Function that maps offsets from start of block to Crucible position.
|
-- ^ Function that maps offsets from start of block to Crucible position.
|
||||||
-> [M.Block arch ids]
|
-> M.Block arch ids
|
||||||
-- ^ List of blocks for this region.
|
-- ^ Macaw block for this region.
|
||||||
-> MacawMonad arch ids h s (CR.Label s, [CR.Block (MacawExt arch) s (MacawFunctionResult arch)])
|
-> MacawMonad arch ids h s (CR.Label s, [CR.Block (MacawExt arch) s (MacawFunctionResult arch)])
|
||||||
addBlocksCFG archFns baseAddrMap addr posFn macawBlocks = do
|
addBlocksCFG archFns baseAddrMap addr posFn macawBlock = do
|
||||||
crucGenArchConstraints archFns $ do
|
crucGenArchConstraints archFns $ do
|
||||||
-- Map block map to Crucible CFG
|
-- Map block map to Crucible CFG
|
||||||
blockLabelMap <- fmap Map.fromList $ sequence $
|
entry <- CR.Label <$> mmFreshNonce
|
||||||
[ mmFreshNonce >>= \n -> return (w, CR.Label n)
|
(blk,blks) <- addMacawBlock archFns baseAddrMap addr entry posFn macawBlock
|
||||||
| w <- M.blockLabel <$> macawBlocks ]
|
return (entry, blk:blks)
|
||||||
entry <-
|
|
||||||
case Map.lookup 0 blockLabelMap of
|
|
||||||
Just lbl -> return lbl
|
|
||||||
Nothing -> fail "Unable to find initial block"
|
|
||||||
blks <- forM macawBlocks $ \b -> do
|
|
||||||
addMacawBlock archFns baseAddrMap addr blockLabelMap posFn b
|
|
||||||
return (entry, concatMap (uncurry (:)) blks)
|
|
||||||
|
|
||||||
-- | Create a registerized Crucible CFG from an arbitrary list of macaw blocks
|
-- | Create a registerized Crucible CFG from an arbitrary list of macaw blocks
|
||||||
--
|
--
|
||||||
@ -303,12 +296,12 @@ mkBlocksRegCFG :: forall s arch ids
|
|||||||
-- ^ Address for start of block.
|
-- ^ Address for start of block.
|
||||||
-> (M.ArchAddrWord arch -> C.Position)
|
-> (M.ArchAddrWord arch -> C.Position)
|
||||||
-- ^ Function that maps offsets from start of block to Crucible position.
|
-- ^ Function that maps offsets from start of block to Crucible position.
|
||||||
-> [M.Block arch ids]
|
-> M.Block arch ids
|
||||||
-- ^ List of blocks for this region.
|
-- ^ List of blocks for this region.
|
||||||
-> ST s (CR.SomeCFG (MacawExt arch) (EmptyCtx ::> ArchRegStruct arch) (ArchRegStruct arch))
|
-> ST s (CR.SomeCFG (MacawExt arch) (EmptyCtx ::> ArchRegStruct arch) (ArchRegStruct arch))
|
||||||
mkBlocksRegCFG archFns halloc memBaseVarMap nm addr posFn macawBlocks = do
|
mkBlocksRegCFG archFns halloc memBaseVarMap nm addr posFn macawBlock = do
|
||||||
mkCrucRegCFG archFns halloc nm $ do
|
mkCrucRegCFG archFns halloc nm $ do
|
||||||
addBlocksCFG archFns memBaseVarMap addr posFn macawBlocks
|
addBlocksCFG archFns memBaseVarMap addr posFn macawBlock
|
||||||
|
|
||||||
-- | Create a Crucible CFG from an arbitrary list of macaw blocks
|
-- | Create a Crucible CFG from an arbitrary list of macaw blocks
|
||||||
--
|
--
|
||||||
@ -332,12 +325,12 @@ mkBlocksCFG :: forall s arch ids
|
|||||||
-- ^ Address for start of block.
|
-- ^ Address for start of block.
|
||||||
-> (M.ArchAddrWord arch -> C.Position)
|
-> (M.ArchAddrWord arch -> C.Position)
|
||||||
-- ^ Function that maps offsets from start of block to Crucible position.
|
-- ^ Function that maps offsets from start of block to Crucible position.
|
||||||
-> [M.Block arch ids]
|
-> M.Block arch ids
|
||||||
-- ^ List of blocks for this region.
|
-- ^ List of blocks for this region.
|
||||||
-> ST s (C.SomeCFG (MacawExt arch) (EmptyCtx ::> ArchRegStruct arch) (ArchRegStruct arch))
|
-> ST s (C.SomeCFG (MacawExt arch) (EmptyCtx ::> ArchRegStruct arch) (ArchRegStruct arch))
|
||||||
mkBlocksCFG archFns halloc memBaseVarMap nm addr posFn macawBlocks =
|
mkBlocksCFG archFns halloc memBaseVarMap nm addr posFn macawBlock =
|
||||||
toCoreCFG archFns <$>
|
toCoreCFG archFns <$>
|
||||||
mkBlocksRegCFG archFns halloc memBaseVarMap nm addr posFn macawBlocks
|
mkBlocksRegCFG archFns halloc memBaseVarMap nm addr posFn macawBlock
|
||||||
|
|
||||||
-- | Create a map from Macaw @(address, index)@ pairs to Crucible labels
|
-- | Create a map from Macaw @(address, index)@ pairs to Crucible labels
|
||||||
mkBlockLabelMap :: [M.ParsedBlock arch ids] -> MacawMonad arch ids h s (BlockLabelMap arch s)
|
mkBlockLabelMap :: [M.ParsedBlock arch ids] -> MacawMonad arch ids h s (BlockLabelMap arch s)
|
||||||
|
@ -1215,16 +1215,6 @@ addMacawStmt baddr stmt =
|
|||||||
crucStmt = MacawArchStateUpdate addr m
|
crucStmt = MacawArchStateUpdate addr m
|
||||||
void $ evalMacawStmt crucStmt
|
void $ evalMacawStmt crucStmt
|
||||||
|
|
||||||
lookupCrucibleLabel :: Map Word64 (CR.Label s)
|
|
||||||
-- ^ Map from block index to Crucible label
|
|
||||||
-> Word64
|
|
||||||
-- ^ Index of crucible block
|
|
||||||
-> CrucGen arch ids h s (CR.Label s)
|
|
||||||
lookupCrucibleLabel m idx = do
|
|
||||||
case Map.lookup idx m of
|
|
||||||
Nothing -> fail $ "Could not find label for block " ++ show idx
|
|
||||||
Just l -> pure l
|
|
||||||
|
|
||||||
-- | Create a crucible struct for registers from a register state.
|
-- | Create a crucible struct for registers from a register state.
|
||||||
createRegStruct :: forall arch ids h s
|
createRegStruct :: forall arch ids h s
|
||||||
. M.RegState (M.ArchReg arch) (M.Value arch ids)
|
. M.RegState (M.ArchReg arch) (M.Value arch ids)
|
||||||
@ -1261,20 +1251,13 @@ createRegUpdates regs = do
|
|||||||
Nothing -> fail "internal: Register is not bound."
|
Nothing -> fail "internal: Register is not bound."
|
||||||
Just idx -> Just . Pair (crucibleIndex idx) <$> valueToCrucible val
|
Just idx -> Just . Pair (crucibleIndex idx) <$> valueToCrucible val
|
||||||
|
|
||||||
addMacawTermStmt :: Map Word64 (CR.Label s)
|
addMacawTermStmt :: M.TermStmt arch ids
|
||||||
-- ^ Map from block index to Crucible label
|
|
||||||
-> M.TermStmt arch ids
|
|
||||||
-> CrucGen arch ids h s ()
|
-> CrucGen arch ids h s ()
|
||||||
addMacawTermStmt blockLabelMap tstmt =
|
addMacawTermStmt tstmt =
|
||||||
case tstmt of
|
case tstmt of
|
||||||
M.FetchAndExecute regs -> do
|
M.FetchAndExecute regs -> do
|
||||||
s <- createRegStruct regs
|
s <- createRegStruct regs
|
||||||
addTermStmt (CR.Return s)
|
addTermStmt (CR.Return s)
|
||||||
M.Branch macawPred macawTrueLbl macawFalseLbl -> do
|
|
||||||
p <- valueToCrucible macawPred
|
|
||||||
t <- lookupCrucibleLabel blockLabelMap macawTrueLbl
|
|
||||||
f <- lookupCrucibleLabel blockLabelMap macawFalseLbl
|
|
||||||
addTermStmt (CR.Br p t f)
|
|
||||||
M.ArchTermStmt ts regs -> do
|
M.ArchTermStmt ts regs -> do
|
||||||
fns <- translateFns <$> get
|
fns <- translateFns <$> get
|
||||||
crucGenArchTermStmt fns ts regs
|
crucGenArchTermStmt fns ts regs
|
||||||
@ -1356,8 +1339,8 @@ addMacawBlock :: M.MemWidth (M.ArchAddrWidth arch)
|
|||||||
-- ^ Base address map
|
-- ^ Base address map
|
||||||
-> M.ArchSegmentOff arch
|
-> M.ArchSegmentOff arch
|
||||||
-- ^ Address of start of block
|
-- ^ Address of start of block
|
||||||
-> Map Word64 (CR.Label s)
|
-> CR.Label s
|
||||||
-- ^ Map from block index to Crucible label
|
-- ^ Crucible label for this bloclk.
|
||||||
-> (M.ArchAddrWord arch -> C.Position)
|
-> (M.ArchAddrWord arch -> C.Position)
|
||||||
-- ^ Function for generating position from offset from start of this block.
|
-- ^ Function for generating position from offset from start of this block.
|
||||||
-> M.Block arch ids
|
-> M.Block arch ids
|
||||||
@ -1365,14 +1348,7 @@ addMacawBlock :: M.MemWidth (M.ArchAddrWidth arch)
|
|||||||
( CR.Block (MacawExt arch) s (MacawFunctionResult arch)
|
( CR.Block (MacawExt arch) s (MacawFunctionResult arch)
|
||||||
, [CR.Block (MacawExt arch) s (MacawFunctionResult arch)]
|
, [CR.Block (MacawExt arch) s (MacawFunctionResult arch)]
|
||||||
)
|
)
|
||||||
addMacawBlock archFns baseAddrMap addr blockLabelMap posFn b = do
|
addMacawBlock archFns baseAddrMap addr lbl posFn b = do
|
||||||
let idx = M.blockLabel b
|
|
||||||
lbl <-
|
|
||||||
case Map.lookup idx blockLabelMap of
|
|
||||||
Just lbl ->
|
|
||||||
pure lbl
|
|
||||||
Nothing ->
|
|
||||||
throwError $ "Internal: Could not find block with index " ++ show idx
|
|
||||||
let archRegStructRepr = C.StructRepr (crucArchRegTypes archFns)
|
let archRegStructRepr = C.StructRepr (crucArchRegTypes archFns)
|
||||||
ng <- gets nonceGen
|
ng <- gets nonceGen
|
||||||
regRegId <- mmExecST $ freshNonce ng
|
regRegId <- mmExecST $ freshNonce ng
|
||||||
@ -1389,7 +1365,7 @@ addMacawBlock archFns baseAddrMap addr blockLabelMap posFn b = do
|
|||||||
fmap (\(b', bs, _) -> (b', bs)) $ runCrucGen archFns baseAddrMap posFn 0 lbl regReg $ do
|
fmap (\(b', bs, _) -> (b', bs)) $ runCrucGen archFns baseAddrMap posFn 0 lbl regReg $ do
|
||||||
addStmt $ CR.SetReg regReg regStruct
|
addStmt $ CR.SetReg regReg regStruct
|
||||||
mapM_ (addMacawStmt addr) (M.blockStmts b)
|
mapM_ (addMacawStmt addr) (M.blockStmts b)
|
||||||
addMacawTermStmt blockLabelMap (M.blockTerm b)
|
addMacawTermStmt (M.blockTerm b)
|
||||||
|
|
||||||
parsedBlockLabel :: (Ord addr, Show addr)
|
parsedBlockLabel :: (Ord addr, Show addr)
|
||||||
=> Map (addr, Word64) (CR.Label s)
|
=> Map (addr, Word64) (CR.Label s)
|
||||||
|
@ -171,13 +171,12 @@ instance MemWidth w => Show (X86TranslateError w) where
|
|||||||
initError :: MemSegmentOff 64 -- ^ Location to explore from.
|
initError :: MemSegmentOff 64 -- ^ Location to explore from.
|
||||||
-> RegState X86Reg (Value X86_64 ids)
|
-> RegState X86Reg (Value X86_64 ids)
|
||||||
-> X86TranslateError 64
|
-> X86TranslateError 64
|
||||||
-> ST st_s (Block X86_64 ids, MemWord 64, Maybe (X86TranslateError 64))
|
-> ST st_s (Block X86_64 ids, MemWord 64)
|
||||||
initError addr s err = do
|
initError addr s err = do
|
||||||
let b = Block { blockLabel = 0
|
let b = Block { blockStmts = []
|
||||||
, blockStmts = []
|
|
||||||
, blockTerm = TranslateError s (Text.pack (show err))
|
, blockTerm = TranslateError s (Text.pack (show err))
|
||||||
}
|
}
|
||||||
return (b, segoffOffset addr, Just err)
|
return (b, segoffOffset addr)
|
||||||
|
|
||||||
-- | Disassemble memory contents using flexdis.
|
-- | Disassemble memory contents using flexdis.
|
||||||
disassembleInstruction :: MemSegmentOff 64
|
disassembleInstruction :: MemSegmentOff 64
|
||||||
@ -312,17 +311,15 @@ translateBlockImpl :: forall st_s ids
|
|||||||
-- ^ List of contents to read next.
|
-- ^ List of contents to read next.
|
||||||
-> ST st_s ( Block X86_64 ids
|
-> ST st_s ( Block X86_64 ids
|
||||||
, MemWord 64
|
, MemWord 64
|
||||||
, Maybe (X86TranslateError 64)
|
|
||||||
)
|
)
|
||||||
translateBlockImpl gen pblock curIPAddr blockOff maxSize contents = do
|
translateBlockImpl gen pblock curIPAddr blockOff maxSize contents = do
|
||||||
r <- runExceptT $ translateStep gen pblock blockOff curIPAddr contents
|
r <- runExceptT $ translateStep gen pblock blockOff curIPAddr contents
|
||||||
case r of
|
case r of
|
||||||
Left err -> do
|
Left err -> do
|
||||||
let b = Block { blockLabel = pBlockIndex pblock
|
let b = Block { blockStmts = toList (pblock^.pBlockStmts)
|
||||||
, blockStmts = toList (pblock^.pBlockStmts)
|
|
||||||
, blockTerm = TranslateError (pblock^.pBlockState) (Text.pack (show err))
|
, blockTerm = TranslateError (pblock^.pBlockState) (Text.pack (show err))
|
||||||
}
|
}
|
||||||
pure (b, blockOff, Just err)
|
pure (b, blockOff)
|
||||||
Right (_, res, instSize, nextIP, nextContents) -> do
|
Right (_, res, instSize, nextIP, nextContents) -> do
|
||||||
let blockOff' = blockOff + fromIntegral instSize
|
let blockOff' = blockOff + fromIntegral instSize
|
||||||
case unfinishedAtAddr res nextIP of
|
case unfinishedAtAddr res nextIP of
|
||||||
@ -331,7 +328,7 @@ translateBlockImpl gen pblock curIPAddr blockOff maxSize contents = do
|
|||||||
, Just nextIPSegOff <- incSegmentOff curIPAddr (toInteger instSize) -> do
|
, Just nextIPSegOff <- incSegmentOff curIPAddr (toInteger instSize) -> do
|
||||||
translateBlockImpl gen pblock' nextIPSegOff blockOff' maxSize nextContents
|
translateBlockImpl gen pblock' nextIPSegOff blockOff' maxSize nextContents
|
||||||
_ ->
|
_ ->
|
||||||
pure (finishPartialBlock res, blockOff', Nothing)
|
pure (finishPartialBlock res, blockOff')
|
||||||
|
|
||||||
{-# DEPRECATED disassembleBlock "Planned for removal." #-}
|
{-# DEPRECATED disassembleBlock "Planned for removal." #-}
|
||||||
|
|
||||||
@ -342,7 +339,7 @@ disassembleBlock :: forall s
|
|||||||
-> ExploreLoc
|
-> ExploreLoc
|
||||||
-> MemWord 64
|
-> MemWord 64
|
||||||
-- ^ Maximum number of bytes in ths block.
|
-- ^ Maximum number of bytes in ths block.
|
||||||
-> ST s (Block X86_64 s, MemWord 64, Maybe (X86TranslateError 64))
|
-> ST s (Block X86_64 s, MemWord 64)
|
||||||
disassembleBlock gen loc maxSize = do
|
disassembleBlock gen loc maxSize = do
|
||||||
let addr = loc_ip loc
|
let addr = loc_ip loc
|
||||||
let regs = initX86State loc
|
let regs = initX86State loc
|
||||||
@ -469,13 +466,13 @@ tryDisassembleBlock :: forall s ids
|
|||||||
-- ^ Maximum size of this block
|
-- ^ Maximum size of this block
|
||||||
-> ExceptT String (ST s) (Block X86_64 ids, Int, Maybe String)
|
-> ExceptT String (ST s) (Block X86_64 ids, Int, Maybe String)
|
||||||
tryDisassembleBlock gen addr initRegs maxSize = lift $ do
|
tryDisassembleBlock gen addr initRegs maxSize = lift $ do
|
||||||
(b, sz, maybeError) <-
|
(b, sz) <-
|
||||||
case segoffContentsAfter addr of
|
case segoffContentsAfter addr of
|
||||||
Left msg -> do
|
Left msg -> do
|
||||||
initError addr initRegs (FlexdisMemoryError msg)
|
initError addr initRegs (FlexdisMemoryError msg)
|
||||||
Right contents -> do
|
Right contents -> do
|
||||||
translateBlockImpl gen (emptyPreBlock addr initRegs) addr 0 (fromIntegral maxSize) contents
|
translateBlockImpl gen (emptyPreBlock addr initRegs) addr 0 (fromIntegral maxSize) contents
|
||||||
pure $! (b, fromIntegral sz, show <$> maybeError)
|
pure $! (b, fromIntegral sz, Nothing)
|
||||||
|
|
||||||
-- | Disassemble block, returning either an error, or a list of blocks
|
-- | Disassemble block, returning either an error, or a list of blocks
|
||||||
-- and ending PC.
|
-- and ending PC.
|
||||||
@ -488,15 +485,15 @@ translateBlockWithRegs :: forall s ids
|
|||||||
-> Int
|
-> Int
|
||||||
-- ^ Maximum size of this block
|
-- ^ Maximum size of this block
|
||||||
-- ^ Abstract state of processor for defining state.
|
-- ^ Abstract state of processor for defining state.
|
||||||
-> ST s ([Block X86_64 ids], Int, Maybe String)
|
-> ST s (Block X86_64 ids, Int)
|
||||||
translateBlockWithRegs gen addr initRegs maxSize = do
|
translateBlockWithRegs gen addr initRegs maxSize = do
|
||||||
(b, sz, maybeError) <-
|
(b, sz) <-
|
||||||
case segoffContentsAfter addr of
|
case segoffContentsAfter addr of
|
||||||
Left msg -> do
|
Left msg -> do
|
||||||
initError addr initRegs (FlexdisMemoryError msg)
|
initError addr initRegs (FlexdisMemoryError msg)
|
||||||
Right contents -> do
|
Right contents -> do
|
||||||
translateBlockImpl gen (emptyPreBlock addr initRegs) addr 0 (fromIntegral maxSize) contents
|
translateBlockImpl gen (emptyPreBlock addr initRegs) addr 0 (fromIntegral maxSize) contents
|
||||||
pure $! ([b], fromIntegral sz, show <$> maybeError)
|
pure $! (b, fromIntegral sz)
|
||||||
|
|
||||||
-- | Attempt to identify the write to a stack return address, returning
|
-- | Attempt to identify the write to a stack return address, returning
|
||||||
-- instructions prior to that write and return values.
|
-- instructions prior to that write and return values.
|
||||||
|
@ -36,7 +36,6 @@ module Data.Macaw.X86.Generator
|
|||||||
-- * PreBlock
|
-- * PreBlock
|
||||||
, PreBlock
|
, PreBlock
|
||||||
, emptyPreBlock
|
, emptyPreBlock
|
||||||
, pBlockIndex
|
|
||||||
, pBlockState
|
, pBlockState
|
||||||
, pBlockStmts
|
, pBlockStmts
|
||||||
, pBlockApps
|
, pBlockApps
|
||||||
@ -87,7 +86,6 @@ import Data.Sequence (Seq)
|
|||||||
import qualified Data.Sequence as Seq
|
import qualified Data.Sequence as Seq
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as Text
|
import qualified Data.Text as Text
|
||||||
import Data.Word
|
|
||||||
|
|
||||||
import Data.Macaw.X86.ArchTypes
|
import Data.Macaw.X86.ArchTypes
|
||||||
import Data.Macaw.X86.X86Reg
|
import Data.Macaw.X86.X86Reg
|
||||||
@ -153,8 +151,7 @@ asSignedBVLit _ = Nothing
|
|||||||
-- PreBlock
|
-- PreBlock
|
||||||
|
|
||||||
-- | A block that we have not yet finished.
|
-- | A block that we have not yet finished.
|
||||||
data PreBlock ids = PreBlock { pBlockIndex :: !Word64
|
data PreBlock ids = PreBlock { _pBlockStmts :: !(Seq (Stmt X86_64 ids))
|
||||||
, _pBlockStmts :: !(Seq (Stmt X86_64 ids))
|
|
||||||
, _pBlockState :: !(RegState X86Reg (Value X86_64 ids))
|
, _pBlockState :: !(RegState X86Reg (Value X86_64 ids))
|
||||||
, _pBlockApps :: !(MapF (App (Value X86_64 ids)) (Assignment X86_64 ids))
|
, _pBlockApps :: !(MapF (App (Value X86_64 ids)) (Assignment X86_64 ids))
|
||||||
, pBlockStart :: !(ArchSegmentOff X86_64)
|
, pBlockStart :: !(ArchSegmentOff X86_64)
|
||||||
@ -165,8 +162,7 @@ emptyPreBlock :: ArchSegmentOff X86_64
|
|||||||
-> RegState X86Reg (Value X86_64 ids)
|
-> RegState X86Reg (Value X86_64 ids)
|
||||||
-> PreBlock ids
|
-> PreBlock ids
|
||||||
emptyPreBlock startAddr s =
|
emptyPreBlock startAddr s =
|
||||||
PreBlock { pBlockIndex = 0
|
PreBlock { _pBlockStmts = Seq.empty
|
||||||
, _pBlockStmts = Seq.empty
|
|
||||||
, _pBlockApps = MapF.empty
|
, _pBlockApps = MapF.empty
|
||||||
, _pBlockState = s
|
, _pBlockState = s
|
||||||
, pBlockStart = startAddr
|
, pBlockStart = startAddr
|
||||||
@ -186,8 +182,7 @@ finishBlock :: PreBlock ids
|
|||||||
-> (RegState X86Reg (Value X86_64 ids) -> TermStmt X86_64 ids)
|
-> (RegState X86Reg (Value X86_64 ids) -> TermStmt X86_64 ids)
|
||||||
-> Block X86_64 ids
|
-> Block X86_64 ids
|
||||||
finishBlock preBlock term =
|
finishBlock preBlock term =
|
||||||
Block { blockLabel = pBlockIndex preBlock
|
Block { blockStmts = toList (preBlock^.pBlockStmts)
|
||||||
, blockStmts = toList (preBlock^.pBlockStmts)
|
|
||||||
, blockTerm = term (preBlock^.pBlockState)
|
, blockTerm = term (preBlock^.pBlockState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user