{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
module Data.Macaw.Discovery.Classifier (
isExecutableSegOff
, identifyConcreteAddresses
, branchClassifier
, callClassifier
, returnClassifier
, directJumpClassifier
, noreturnCallClassifier
, tailCallClassifier
, branchBlockState
, classifierEndBlock
) where
import Control.Applicative ( Alternative(empty) )
import Control.Lens ( (^.), (&), (.~) )
import Control.Monad ( when, unless )
import qualified Control.Monad.Reader as CMR
import qualified Data.Foldable as F
import qualified Data.Map.Strict as Map
import Data.Maybe ( maybeToList )
import qualified Data.Set as Set
import Text.Printf (printf)
import Data.Macaw.AbsDomain.AbsState
import qualified Data.Macaw.AbsDomain.JumpBounds as Jmp
import qualified Data.Macaw.AbsDomain.Refine as Refine
import Data.Macaw.Architecture.Info as Info
import Data.Macaw.CFG
import qualified Data.Macaw.Discovery.AbsEval as AbsEval
import qualified Data.Macaw.Discovery.ParsedContents as Parsed
import qualified Data.Macaw.Memory.Permissions as Perm
import Data.Macaw.Types
isExecutableSegOff :: MemSegmentOff w -> Bool
isExecutableSegOff :: forall (w :: Nat). MemSegmentOff w -> Bool
isExecutableSegOff MemSegmentOff w
sa =
MemSegment w -> Flags
forall (w :: Nat). MemSegment w -> Flags
segmentFlags (MemSegmentOff w -> MemSegment w
forall (w :: Nat). MemSegmentOff w -> MemSegment w
segoffSegment MemSegmentOff w
sa) Flags -> Flags -> Bool
`Perm.hasPerm` Flags
Perm.execute
identifyConcreteAddresses :: MemWidth w
=> Memory w
-> AbsValue w (BVType w)
-> [MemSegmentOff w]
identifyConcreteAddresses :: forall (w :: Nat).
MemWidth w =>
Memory w -> AbsValue w (BVType w) -> [MemSegmentOff w]
identifyConcreteAddresses Memory w
mem (FinSet Set Integer
s) =
let ins :: Integer -> [MemSegmentOff w] -> [MemSegmentOff w]
ins Integer
o [MemSegmentOff w]
r =
case Memory w -> MemWord w -> Maybe (MemSegmentOff w)
forall (w :: Nat). Memory w -> MemWord w -> Maybe (MemSegmentOff w)
resolveAbsoluteAddr Memory w
mem (Integer -> MemWord w
forall a. Num a => Integer -> a
fromInteger Integer
o) of
Just MemSegmentOff w
a | MemSegmentOff w -> Bool
forall (w :: Nat). MemSegmentOff w -> Bool
isExecutableSegOff MemSegmentOff w
a -> MemSegmentOff w
a MemSegmentOff w -> [MemSegmentOff w] -> [MemSegmentOff w]
forall a. a -> [a] -> [a]
: [MemSegmentOff w]
r
Maybe (MemSegmentOff w)
_ -> [MemSegmentOff w]
r
in (Integer -> [MemSegmentOff w] -> [MemSegmentOff w])
-> [MemSegmentOff w] -> Set Integer -> [MemSegmentOff w]
forall a b. (a -> b -> b) -> b -> Set a -> b
forall (t :: Type -> Type) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Integer -> [MemSegmentOff w] -> [MemSegmentOff w]
ins [] Set Integer
s
identifyConcreteAddresses Memory w
_ (CodePointers Set (MemSegmentOff w)
s Bool
_) = (MemSegmentOff w -> Bool) -> [MemSegmentOff w] -> [MemSegmentOff w]
forall a. (a -> Bool) -> [a] -> [a]
filter MemSegmentOff w -> Bool
forall (w :: Nat). MemSegmentOff w -> Bool
isExecutableSegOff ([MemSegmentOff w] -> [MemSegmentOff w])
-> [MemSegmentOff w] -> [MemSegmentOff w]
forall a b. (a -> b) -> a -> b
$ Set (MemSegmentOff w) -> [MemSegmentOff w]
forall a. Set a -> [a]
Set.toList Set (MemSegmentOff w)
s
identifyConcreteAddresses Memory w
_mem StridedInterval{} = []
identifyConcreteAddresses Memory w
_mem AbsValue w (BVType w)
_ = []
normBool :: Value arch ids BoolType -> Bool -> (Value arch ids BoolType, Bool)
normBool :: forall arch ids.
Value arch ids BoolType -> Bool -> (Value arch ids BoolType, Bool)
normBool Value arch ids BoolType
x Bool
b
| AssignedValue Assignment arch ids BoolType
a <- Value arch ids BoolType
x
, EvalApp (NotApp Value arch ids BoolType
xn) <- Assignment arch ids BoolType
-> AssignRhs arch (Value arch ids) BoolType
forall arch ids (tp :: Type).
Assignment arch ids tp -> AssignRhs arch (Value arch ids) tp
assignRhs Assignment arch ids BoolType
a =
Value arch ids BoolType -> Bool -> (Value arch ids BoolType, Bool)
forall arch ids.
Value arch ids BoolType -> Bool -> (Value arch ids BoolType, Bool)
normBool Value arch ids BoolType
xn (Bool -> Bool
not Bool
b)
| Bool
otherwise = (Value arch ids BoolType
x,Bool
b)
branchBlockState :: forall a ids t
. ( Foldable t
)
=> Info.ArchitectureInfo a
-> AbsProcessorState (ArchReg a) ids
-> t (Stmt a ids)
-> RegState (ArchReg a) (Value a ids)
-> Value a ids BoolType
-> Bool
-> AbsBlockState (ArchReg a)
branchBlockState :: forall a ids (t :: Type -> Type).
Foldable t =>
ArchitectureInfo a
-> AbsProcessorState (ArchReg a) ids
-> t (Stmt a ids)
-> RegState (ArchReg a) (Value a ids)
-> Value a ids BoolType
-> Bool
-> AbsBlockState (ArchReg a)
branchBlockState ArchitectureInfo a
ainfo AbsProcessorState (ArchReg a) ids
ps0 t (Stmt a ids)
stmts RegState (ArchReg a) (Value a ids)
regs Value a ids BoolType
c0 Bool
isTrue0 =
ArchitectureInfo a -> forall a. (ArchConstraints a => a) -> a
forall arch.
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
Info.withArchConstraints ArchitectureInfo a
ainfo ((ArchConstraints a => AbsBlockState (ArchReg a))
-> AbsBlockState (ArchReg a))
-> (ArchConstraints a => AbsBlockState (ArchReg a))
-> AbsBlockState (ArchReg a)
forall a b. (a -> b) -> a -> b
$
let (Value a ids BoolType
c,Bool
isTrue) = Value a ids BoolType -> Bool -> (Value a ids BoolType, Bool)
forall arch ids.
Value arch ids BoolType -> Bool -> (Value arch ids BoolType, Bool)
normBool Value a ids BoolType
c0 Bool
isTrue0
ps :: AbsProcessorState (ArchReg a) ids
ps = Value a ids BoolType
-> Bool
-> AbsProcessorState (ArchReg a) ids
-> AbsProcessorState (ArchReg a) ids
forall arch ids.
(RegisterInfo (ArchReg arch), OrdF (ArchReg arch),
HasRepr (ArchReg arch) TypeRepr) =>
Value arch ids BoolType
-> Bool
-> AbsProcessorState (ArchReg arch) ids
-> AbsProcessorState (ArchReg arch) ids
Refine.refineProcState Value a ids BoolType
c Bool
isTrue AbsProcessorState (ArchReg a) ids
ps0
mapReg :: ArchReg a tp -> Value a ids tp -> Value a ids tp
mapReg :: forall (tp :: Type).
ArchReg a tp -> Value a ids tp -> Value a ids tp
mapReg ArchReg a tp
_r Value a ids tp
v
| AssignedValue Assignment a ids tp
a <- Value a ids tp
v
, EvalApp (Mux TypeRepr tp
_ Value a ids BoolType
cv0 Value a ids tp
tv Value a ids tp
fv) <- Assignment a ids tp -> AssignRhs a (Value a ids) tp
forall arch ids (tp :: Type).
Assignment arch ids tp -> AssignRhs arch (Value arch ids) tp
assignRhs Assignment a ids tp
a
, (Value a ids BoolType
cv, Bool
b) <- Value a ids BoolType -> Bool -> (Value a ids BoolType, Bool)
forall arch ids.
Value arch ids BoolType -> Bool -> (Value arch ids BoolType, Bool)
normBool Value a ids BoolType
cv0 Bool
isTrue
, Value a ids BoolType
cv Value a ids BoolType -> Value a ids BoolType -> Bool
forall a. Eq a => a -> a -> Bool
== Value a ids BoolType
c =
if Bool
b then Value a ids tp
tv else Value a ids tp
fv
| Bool
otherwise =
Value a ids tp
v
refinedRegs :: RegState (ArchReg a) (Value a ids)
refinedRegs = (forall (tp :: Type).
ArchReg a tp -> Value a ids tp -> Value a ids tp)
-> RegState (ArchReg a) (Value a ids)
-> RegState (ArchReg a) (Value a ids)
forall {k} (r :: k -> Type) (f :: k -> Type) (g :: k -> Type).
(forall (tp :: k). r tp -> f tp -> g tp)
-> RegState r f -> RegState r g
mapRegsWith ArchReg a tp -> Value a ids tp -> Value a ids tp
forall (tp :: Type).
ArchReg a tp -> Value a ids tp -> Value a ids tp
mapReg RegState (ArchReg a) (Value a ids)
regs
in AbsProcessorState (ArchReg a) ids
-> RegState (ArchReg a) (Value a ids) -> AbsBlockState (ArchReg a)
forall a ids.
RegisterInfo (ArchReg a) =>
AbsProcessorState (ArchReg a) ids
-> RegState (ArchReg a) (Value a ids) -> AbsBlockState (ArchReg a)
finalAbsBlockState ((AbsProcessorState (ArchReg a) ids
-> Stmt a ids -> AbsProcessorState (ArchReg a) ids)
-> AbsProcessorState (ArchReg a) ids
-> t (Stmt a ids)
-> AbsProcessorState (ArchReg a) ids
forall b a. (b -> a -> b) -> b -> t a -> b
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' (ArchitectureInfo a
-> AbsProcessorState (ArchReg a) ids
-> Stmt a ids
-> AbsProcessorState (ArchReg a) ids
forall arch ids.
ArchitectureInfo arch
-> AbsProcessorState (ArchReg arch) ids
-> Stmt arch ids
-> AbsProcessorState (ArchReg arch) ids
AbsEval.absEvalStmt ArchitectureInfo a
ainfo) AbsProcessorState (ArchReg a) ids
ps t (Stmt a ids)
stmts) RegState (ArchReg a) (Value a ids)
refinedRegs
classifyDirectJump :: RegisterInfo (ArchReg arch)
=> ParseContext arch ids
-> String
-> Value arch ids (BVType (ArchAddrWidth arch))
-> BlockClassifierM arch ids (ArchSegmentOff arch)
classifyDirectJump :: forall arch ids.
RegisterInfo (ArchReg arch) =>
ParseContext arch ids
-> String
-> Value arch ids (BVType (ArchAddrWidth arch))
-> BlockClassifierM arch ids (ArchSegmentOff arch)
classifyDirectJump ParseContext arch ids
ctx String
nm Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
v = do
MemAddr (RegAddrWidth (ArchReg arch))
ma <- case Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> Maybe (MemAddr (RegAddrWidth (ArchReg arch)))
forall arch ids.
MemWidth (ArchAddrWidth arch) =>
BVValue arch ids (ArchAddrWidth arch) -> Maybe (ArchMemAddr arch)
valueAsMemAddr Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
v of
Maybe (MemAddr (RegAddrWidth (ArchReg arch)))
Nothing -> String
-> BlockClassifierM
arch ids (MemAddr (RegAddrWidth (ArchReg arch)))
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String
-> BlockClassifierM
arch ids (MemAddr (RegAddrWidth (ArchReg arch))))
-> String
-> BlockClassifierM
arch ids (MemAddr (RegAddrWidth (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$ String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" value " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Value arch ids (BVType (RegAddrWidth (ArchReg arch))) -> String
forall a. Show a => a -> String
show Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
v String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is not a valid address."
Just MemAddr (RegAddrWidth (ArchReg arch))
a -> MemAddr (RegAddrWidth (ArchReg arch))
-> BlockClassifierM
arch ids (MemAddr (RegAddrWidth (ArchReg arch)))
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure MemAddr (RegAddrWidth (ArchReg arch))
a
MemSegmentOff (RegAddrWidth (ArchReg arch))
a <- case Memory (RegAddrWidth (ArchReg arch))
-> MemAddr (RegAddrWidth (ArchReg arch))
-> Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall (w :: Nat). Memory w -> MemAddr w -> Maybe (MemSegmentOff w)
asSegmentOff (ParseContext arch ids -> Memory (RegAddrWidth (ArchReg arch))
forall arch ids.
ParseContext arch ids -> Memory (ArchAddrWidth arch)
pctxMemory ParseContext arch ids
ctx) MemAddr (RegAddrWidth (ArchReg arch))
ma of
Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
Nothing ->
String
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch))))
-> String
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$ String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" value " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Value arch ids (BVType (RegAddrWidth (ArchReg arch))) -> String
forall a. Show a => a -> String
show Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
v String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is not a segment offset in " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Memory (RegAddrWidth (ArchReg arch)) -> String
forall a. Show a => a -> String
show (ParseContext arch ids -> Memory (RegAddrWidth (ArchReg arch))
forall arch ids.
ParseContext arch ids -> Memory (ArchAddrWidth arch)
pctxMemory ParseContext arch ids
ctx) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"."
Just MemSegmentOff (RegAddrWidth (ArchReg arch))
sa -> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure MemSegmentOff (RegAddrWidth (ArchReg arch))
sa
Bool
-> BlockClassifierM arch ids () -> BlockClassifierM arch ids ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
unless (MemSegment (RegAddrWidth (ArchReg arch)) -> Flags
forall (w :: Nat). MemSegment w -> Flags
segmentFlags (MemSegmentOff (RegAddrWidth (ArchReg arch))
-> MemSegment (RegAddrWidth (ArchReg arch))
forall (w :: Nat). MemSegmentOff w -> MemSegment w
segoffSegment MemSegmentOff (RegAddrWidth (ArchReg arch))
a) Flags -> Flags -> Bool
`Perm.hasPerm` Flags
Perm.execute) (BlockClassifierM arch ids () -> BlockClassifierM arch ids ())
-> BlockClassifierM arch ids () -> BlockClassifierM arch ids ()
forall a b. (a -> b) -> a -> b
$ do
String -> BlockClassifierM arch ids ()
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> BlockClassifierM arch ids ())
-> String -> BlockClassifierM arch ids ()
forall a b. (a -> b) -> a -> b
$ String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" value " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MemSegmentOff (RegAddrWidth (ArchReg arch)) -> String
forall a. Show a => a -> String
show MemSegmentOff (RegAddrWidth (ArchReg arch))
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is not executable."
Bool
-> BlockClassifierM arch ids () -> BlockClassifierM arch ids ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (MemSegmentOff (RegAddrWidth (ArchReg arch))
a MemSegmentOff (RegAddrWidth (ArchReg arch))
-> MemSegmentOff (RegAddrWidth (ArchReg arch)) -> Bool
forall a. Eq a => a -> a -> Bool
== ParseContext arch ids
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
forall arch ids. ParseContext arch ids -> ArchSegmentOff arch
pctxFunAddr ParseContext arch ids
ctx) (BlockClassifierM arch ids () -> BlockClassifierM arch ids ())
-> BlockClassifierM arch ids () -> BlockClassifierM arch ids ()
forall a b. (a -> b) -> a -> b
$ do
String -> BlockClassifierM arch ids ()
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> BlockClassifierM arch ids ())
-> String -> BlockClassifierM arch ids ()
forall a b. (a -> b) -> a -> b
$ String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" value " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MemSegmentOff (RegAddrWidth (ArchReg arch)) -> String
forall a. Show a => a -> String
show MemSegmentOff (RegAddrWidth (ArchReg arch))
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" refers to function start."
Bool
-> BlockClassifierM arch ids () -> BlockClassifierM arch ids ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (MemSegmentOff (RegAddrWidth (ArchReg arch))
a MemSegmentOff (RegAddrWidth (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) NoReturnFunStatus
-> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` ParseContext arch ids
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) NoReturnFunStatus
forall arch ids.
ParseContext arch ids
-> Map (ArchSegmentOff arch) NoReturnFunStatus
pctxKnownFnEntries ParseContext arch ids
ctx) (BlockClassifierM arch ids () -> BlockClassifierM arch ids ())
-> BlockClassifierM arch ids () -> BlockClassifierM arch ids ()
forall a b. (a -> b) -> a -> b
$ do
String -> BlockClassifierM arch ids ()
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> BlockClassifierM arch ids ())
-> String -> BlockClassifierM arch ids ()
forall a b. (a -> b) -> a -> b
$ String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" value " String -> String -> String
forall a. [a] -> [a] -> [a]
++ MemSegmentOff (RegAddrWidth (ArchReg arch)) -> String
forall a. Show a => a -> String
show MemSegmentOff (RegAddrWidth (ArchReg arch))
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is a known function entry."
MemSegmentOff (RegAddrWidth (ArchReg arch))
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure MemSegmentOff (RegAddrWidth (ArchReg arch))
a
branchClassifier :: BlockClassifier arch ids
branchClassifier :: forall arch ids. BlockClassifier arch ids
branchClassifier = String
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall arch ids a.
String
-> BlockClassifierM arch ids a -> BlockClassifierM arch ids a
classifierName String
"Branch" (BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
BlockClassifierContext arch ids
bcc <- BlockClassifierM arch ids (BlockClassifierContext arch ids)
forall r (m :: Type -> Type). MonadReader r m => m r
CMR.ask
let ctx :: ParseContext arch ids
ctx = BlockClassifierContext arch ids -> ParseContext arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParseContext arch ids
classifierParseContext BlockClassifierContext arch ids
bcc
let finalRegs :: RegState (ArchReg arch) (Value arch ids)
finalRegs = BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc
let writtenAddrs :: [ArchSegmentOff arch]
writtenAddrs = BlockClassifierContext arch ids -> [ArchSegmentOff arch]
forall arch ids.
BlockClassifierContext arch ids -> [ArchSegmentOff arch]
classifierWrittenAddrs BlockClassifierContext arch ids
bcc
let absState :: AbsProcessorState (ArchReg arch) ids
absState = BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
forall arch ids.
BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
classifierAbsState BlockClassifierContext arch ids
bcc
let stmts :: Seq (Stmt arch ids)
stmts = BlockClassifierContext arch ids -> Seq (Stmt arch ids)
forall arch ids.
BlockClassifierContext arch ids -> Seq (Stmt arch ids)
classifierStmts BlockClassifierContext arch ids
bcc
let ainfo :: ArchitectureInfo arch
ainfo = ParseContext arch ids -> ArchitectureInfo arch
forall arch ids. ParseContext arch ids -> ArchitectureInfo arch
pctxArchInfo ParseContext arch ids
ctx
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
forall arch.
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
Info.withArchConstraints ArchitectureInfo arch
ainfo ((ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> (ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
let ipVal :: Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal = RegState (ArchReg arch) (Value arch ids)
finalRegsRegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
forall s a. s -> Getting a s a -> a
^.ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
ip_reg
(Value arch ids BoolType
c,Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
t,Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
f) <- case Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> Maybe
(App (Value arch ids) (BVType (RegAddrWidth (ArchReg arch))))
forall arch ids (tp :: Type).
Value arch ids tp -> Maybe (App (Value arch ids) tp)
valueAsApp Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal of
Just (Mux TypeRepr (BVType (RegAddrWidth (ArchReg arch)))
_ Value arch ids BoolType
c Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
t Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
f) -> (Value arch ids BoolType,
Value arch ids (BVType (RegAddrWidth (ArchReg arch))),
Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
-> BlockClassifierM
arch
ids
(Value arch ids BoolType,
Value arch ids (BVType (RegAddrWidth (ArchReg arch))),
Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Value arch ids BoolType
c,Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
t,Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
f)
Maybe (App (Value arch ids) (BVType (RegAddrWidth (ArchReg arch))))
_ -> String
-> BlockClassifierM
arch
ids
(Value arch ids BoolType,
Value arch ids (BVType (RegAddrWidth (ArchReg arch))),
Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String
-> BlockClassifierM
arch
ids
(Value arch ids BoolType,
Value arch ids (BVType (RegAddrWidth (ArchReg arch))),
Value arch ids (BVType (RegAddrWidth (ArchReg arch)))))
-> String
-> BlockClassifierM
arch
ids
(Value arch ids BoolType,
Value arch ids (BVType (RegAddrWidth (ArchReg arch))),
Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall a b. (a -> b) -> a -> b
$ String
"IP is not an mux:\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Doc Any -> String
forall a. Show a => a -> String
show (Value arch ids (BVType (RegAddrWidth (ArchReg arch))) -> Doc Any
forall arch ids (tp :: Type) ann.
ArchConstraints arch =>
Value arch ids tp -> Doc ann
ppValueAssignments Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal)
ArchSegmentOff arch
trueTgtAddr <- ParseContext arch ids
-> String
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> BlockClassifierM arch ids (ArchSegmentOff arch)
forall arch ids.
RegisterInfo (ArchReg arch) =>
ParseContext arch ids
-> String
-> Value arch ids (BVType (ArchAddrWidth arch))
-> BlockClassifierM arch ids (ArchSegmentOff arch)
classifyDirectJump ParseContext arch ids
ctx String
"True branch" Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
t
ArchSegmentOff arch
falseTgtAddr <- ParseContext arch ids
-> String
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> BlockClassifierM arch ids (ArchSegmentOff arch)
forall arch ids.
RegisterInfo (ArchReg arch) =>
ParseContext arch ids
-> String
-> Value arch ids (BVType (ArchAddrWidth arch))
-> BlockClassifierM arch ids (ArchSegmentOff arch)
classifyDirectJump ParseContext arch ids
ctx String
"False branch" Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
f
let trueRegs :: RegState (ArchReg arch) (Value arch ids)
trueRegs = RegState (ArchReg arch) (Value arch ids)
finalRegs RegState (ArchReg arch) (Value arch ids)
-> (RegState (ArchReg arch) (Value arch ids)
-> RegState (ArchReg arch) (Value arch ids))
-> RegState (ArchReg arch) (Value arch ids)
forall a b. a -> (a -> b) -> b
& ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
ip_reg ((Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> Identity
(Value arch ids (BVType (RegAddrWidth (ArchReg arch)))))
-> RegState (ArchReg arch) (Value arch ids)
-> Identity (RegState (ArchReg arch) (Value arch ids)))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> RegState (ArchReg arch) (Value arch ids)
-> RegState (ArchReg arch) (Value arch ids)
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
t
let falseRegs :: RegState (ArchReg arch) (Value arch ids)
falseRegs = RegState (ArchReg arch) (Value arch ids)
finalRegs RegState (ArchReg arch) (Value arch ids)
-> (RegState (ArchReg arch) (Value arch ids)
-> RegState (ArchReg arch) (Value arch ids))
-> RegState (ArchReg arch) (Value arch ids)
forall a b. a -> (a -> b) -> b
& ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
ip_reg ((Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> Identity
(Value arch ids (BVType (RegAddrWidth (ArchReg arch)))))
-> RegState (ArchReg arch) (Value arch ids)
-> Identity (RegState (ArchReg arch) (Value arch ids)))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> RegState (ArchReg arch) (Value arch ids)
-> RegState (ArchReg arch) (Value arch ids)
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
f
let trueAbsState :: AbsBlockState (ArchReg arch)
trueAbsState = ArchitectureInfo arch
-> AbsProcessorState (ArchReg arch) ids
-> Seq (Stmt arch ids)
-> RegState (ArchReg arch) (Value arch ids)
-> Value arch ids BoolType
-> Bool
-> AbsBlockState (ArchReg arch)
forall a ids (t :: Type -> Type).
Foldable t =>
ArchitectureInfo a
-> AbsProcessorState (ArchReg a) ids
-> t (Stmt a ids)
-> RegState (ArchReg a) (Value a ids)
-> Value a ids BoolType
-> Bool
-> AbsBlockState (ArchReg a)
branchBlockState ArchitectureInfo arch
ainfo AbsProcessorState (ArchReg arch) ids
absState Seq (Stmt arch ids)
stmts RegState (ArchReg arch) (Value arch ids)
trueRegs Value arch ids BoolType
c Bool
True
let falseAbsState :: AbsBlockState (ArchReg arch)
falseAbsState = ArchitectureInfo arch
-> AbsProcessorState (ArchReg arch) ids
-> Seq (Stmt arch ids)
-> RegState (ArchReg arch) (Value arch ids)
-> Value arch ids BoolType
-> Bool
-> AbsBlockState (ArchReg arch)
forall a ids (t :: Type -> Type).
Foldable t =>
ArchitectureInfo a
-> AbsProcessorState (ArchReg a) ids
-> t (Stmt a ids)
-> RegState (ArchReg a) (Value a ids)
-> Value a ids BoolType
-> Bool
-> AbsBlockState (ArchReg a)
branchBlockState ArchitectureInfo arch
ainfo AbsProcessorState (ArchReg arch) ids
absState Seq (Stmt arch ids)
stmts RegState (ArchReg arch) (Value arch ids)
falseRegs Value arch ids BoolType
c Bool
False
let jmpBounds :: IntraJumpBounds arch ids
jmpBounds = BlockClassifierContext arch ids -> IntraJumpBounds arch ids
forall arch ids.
BlockClassifierContext arch ids -> IntraJumpBounds arch ids
classifierJumpBounds BlockClassifierContext arch ids
bcc
case IntraJumpBounds arch ids
-> RegState (ArchReg arch) (Value arch ids)
-> Value arch ids BoolType
-> BranchBounds arch
forall arch ids.
RegisterInfo (ArchReg arch) =>
IntraJumpBounds arch ids
-> RegState (ArchReg arch) (Value arch ids)
-> Value arch ids BoolType
-> BranchBounds arch
Jmp.postBranchBounds IntraJumpBounds arch ids
jmpBounds RegState (ArchReg arch) (Value arch ids)
finalRegs Value arch ids BoolType
c of
Jmp.BothFeasibleBranch InitJumpBounds arch
trueJmpState InitJumpBounds arch
falseJmpState -> do
ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ Parsed.ParsedContents { parsedNonterm :: [Stmt arch ids]
Parsed.parsedNonterm = Seq (Stmt arch ids) -> [Stmt arch ids]
forall a. Seq a -> [a]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
F.toList Seq (Stmt arch ids)
stmts
, parsedTerm :: ParsedTermStmt arch ids
Parsed.parsedTerm =
RegState (ArchReg arch) (Value arch ids)
-> Value arch ids BoolType
-> ArchSegmentOff arch
-> ArchSegmentOff arch
-> ParsedTermStmt arch ids
forall arch ids.
RegState (ArchReg arch) (Value arch ids)
-> Value arch ids BoolType
-> ArchSegmentOff arch
-> ArchSegmentOff arch
-> ParsedTermStmt arch ids
Parsed.ParsedBranch RegState (ArchReg arch) (Value arch ids)
finalRegs Value arch ids BoolType
c ArchSegmentOff arch
trueTgtAddr ArchSegmentOff arch
falseTgtAddr
, writtenCodeAddrs :: [ArchSegmentOff arch]
Parsed.writtenCodeAddrs = [ArchSegmentOff arch]
writtenAddrs
, intraJumpTargets :: [IntraJumpTarget arch]
Parsed.intraJumpTargets =
[ (ArchSegmentOff arch
trueTgtAddr, AbsBlockState (ArchReg arch)
trueAbsState, InitJumpBounds arch
trueJmpState)
, (ArchSegmentOff arch
falseTgtAddr, AbsBlockState (ArchReg arch)
falseAbsState, InitJumpBounds arch
falseJmpState)
]
, newFunctionAddrs :: [ArchSegmentOff arch]
Parsed.newFunctionAddrs = []
}
Jmp.TrueFeasibleBranch InitJumpBounds arch
trueJmpState -> do
ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ Parsed.ParsedContents { parsedNonterm :: [Stmt arch ids]
Parsed.parsedNonterm = Seq (Stmt arch ids) -> [Stmt arch ids]
forall a. Seq a -> [a]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
F.toList Seq (Stmt arch ids)
stmts
, parsedTerm :: ParsedTermStmt arch ids
Parsed.parsedTerm = RegState (ArchReg arch) (Value arch ids)
-> ArchSegmentOff arch -> ParsedTermStmt arch ids
forall arch ids.
RegState (ArchReg arch) (Value arch ids)
-> ArchSegmentOff arch -> ParsedTermStmt arch ids
Parsed.ParsedJump RegState (ArchReg arch) (Value arch ids)
finalRegs ArchSegmentOff arch
trueTgtAddr
, writtenCodeAddrs :: [ArchSegmentOff arch]
Parsed.writtenCodeAddrs = [ArchSegmentOff arch]
writtenAddrs
, intraJumpTargets :: [IntraJumpTarget arch]
Parsed.intraJumpTargets =
[(ArchSegmentOff arch
trueTgtAddr, AbsBlockState (ArchReg arch)
trueAbsState, InitJumpBounds arch
trueJmpState)]
, newFunctionAddrs :: [ArchSegmentOff arch]
Parsed.newFunctionAddrs = []
}
Jmp.FalseFeasibleBranch InitJumpBounds arch
falseJmpState -> do
ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ Parsed.ParsedContents { parsedNonterm :: [Stmt arch ids]
Parsed.parsedNonterm = Seq (Stmt arch ids) -> [Stmt arch ids]
forall a. Seq a -> [a]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
F.toList Seq (Stmt arch ids)
stmts
, parsedTerm :: ParsedTermStmt arch ids
Parsed.parsedTerm = RegState (ArchReg arch) (Value arch ids)
-> ArchSegmentOff arch -> ParsedTermStmt arch ids
forall arch ids.
RegState (ArchReg arch) (Value arch ids)
-> ArchSegmentOff arch -> ParsedTermStmt arch ids
Parsed.ParsedJump RegState (ArchReg arch) (Value arch ids)
finalRegs ArchSegmentOff arch
falseTgtAddr
, writtenCodeAddrs :: [ArchSegmentOff arch]
Parsed.writtenCodeAddrs = [ArchSegmentOff arch]
writtenAddrs
, intraJumpTargets :: [IntraJumpTarget arch]
Parsed.intraJumpTargets =
[(ArchSegmentOff arch
falseTgtAddr, AbsBlockState (ArchReg arch)
falseAbsState, InitJumpBounds arch
falseJmpState)]
, newFunctionAddrs :: [ArchSegmentOff arch]
Parsed.newFunctionAddrs = []
}
BranchBounds arch
Jmp.InfeasibleBranch -> do
String -> BlockClassifierM arch ids (ParsedContents arch ids)
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail String
"Branch targets are both unreachable."
identifyCallTargets :: forall arch ids
. (RegisterInfo (ArchReg arch))
=> Memory (ArchAddrWidth arch)
-> AbsProcessorState (ArchReg arch) ids
-> RegState (ArchReg arch) (Value arch ids)
-> [ArchSegmentOff arch]
identifyCallTargets :: forall arch ids.
RegisterInfo (ArchReg arch) =>
Memory (ArchAddrWidth arch)
-> AbsProcessorState (ArchReg arch) ids
-> RegState (ArchReg arch) (Value arch ids)
-> [ArchSegmentOff arch]
identifyCallTargets Memory (RegAddrWidth (ArchReg arch))
mem AbsProcessorState (ArchReg arch) ids
absState RegState (ArchReg arch) (Value arch ids)
regs = do
let def :: [ArchSegmentOff arch]
def = Memory (RegAddrWidth (ArchReg arch))
-> AbsValue
(RegAddrWidth (ArchReg arch))
(BVType (RegAddrWidth (ArchReg arch)))
-> [ArchSegmentOff arch]
forall (w :: Nat).
MemWidth w =>
Memory w -> AbsValue w (BVType w) -> [MemSegmentOff w]
identifyConcreteAddresses Memory (RegAddrWidth (ArchReg arch))
mem (AbsValue
(RegAddrWidth (ArchReg arch))
(BVType (RegAddrWidth (ArchReg arch)))
-> [ArchSegmentOff arch])
-> AbsValue
(RegAddrWidth (ArchReg arch))
(BVType (RegAddrWidth (ArchReg arch)))
-> [ArchSegmentOff arch]
forall a b. (a -> b) -> a -> b
$ AbsProcessorState (ArchReg arch) ids
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> AbsValue
(RegAddrWidth (ArchReg arch))
(BVType (RegAddrWidth (ArchReg arch)))
forall a ids (tp :: Type).
(RegisterInfo (ArchReg a), HasCallStack) =>
AbsProcessorState (ArchReg a) ids
-> Value a ids tp -> ArchAbsValue a tp
transferValue AbsProcessorState (ArchReg arch) ids
absState (RegState (ArchReg arch) (Value arch ids)
regsRegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
forall s a. s -> Getting a s a -> a
^.ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
ip_reg)
case RegState (ArchReg arch) (Value arch ids)
regsRegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
forall s a. s -> Getting a s a -> a
^.ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
ip_reg of
BVValue NatRepr n
_ Integer
x ->
Maybe (ArchSegmentOff arch) -> [ArchSegmentOff arch]
forall a. Maybe a -> [a]
maybeToList (Maybe (ArchSegmentOff arch) -> [ArchSegmentOff arch])
-> Maybe (ArchSegmentOff arch) -> [ArchSegmentOff arch]
forall a b. (a -> b) -> a -> b
$ Memory n -> MemWord n -> Maybe (MemSegmentOff n)
forall (w :: Nat). Memory w -> MemWord w -> Maybe (MemSegmentOff w)
resolveAbsoluteAddr Memory n
Memory (RegAddrWidth (ArchReg arch))
mem (Integer -> MemWord n
forall a. Num a => Integer -> a
fromInteger Integer
x)
RelocatableValue AddrWidthRepr (RegAddrWidth (ArchReg arch))
_ MemAddr (RegAddrWidth (ArchReg arch))
a ->
Maybe (ArchSegmentOff arch) -> [ArchSegmentOff arch]
forall a. Maybe a -> [a]
maybeToList (Maybe (ArchSegmentOff arch) -> [ArchSegmentOff arch])
-> Maybe (ArchSegmentOff arch) -> [ArchSegmentOff arch]
forall a b. (a -> b) -> a -> b
$ Memory (RegAddrWidth (ArchReg arch))
-> MemAddr (RegAddrWidth (ArchReg arch))
-> Maybe (ArchSegmentOff arch)
forall (w :: Nat). Memory w -> MemAddr w -> Maybe (MemSegmentOff w)
asSegmentOff Memory (RegAddrWidth (ArchReg arch))
mem MemAddr (RegAddrWidth (ArchReg arch))
a
SymbolValue{} -> []
AssignedValue Assignment arch ids (BVType (RegAddrWidth (ArchReg arch)))
a ->
case Assignment arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> AssignRhs
arch (Value arch ids) (BVType (RegAddrWidth (ArchReg arch)))
forall arch ids (tp :: Type).
Assignment arch ids tp -> AssignRhs arch (Value arch ids) tp
assignRhs Assignment arch ids (BVType (RegAddrWidth (ArchReg arch)))
a of
ReadMem Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
addr (BVMemRepr NatRepr w
_ Endianness
end)
| Just MemAddr (RegAddrWidth (ArchReg arch))
laddr <- Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> Maybe (MemAddr (RegAddrWidth (ArchReg arch)))
forall arch ids.
MemWidth (ArchAddrWidth arch) =>
BVValue arch ids (ArchAddrWidth arch) -> Maybe (ArchMemAddr arch)
valueAsMemAddr Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
addr
, Right ArchSegmentOff arch
val <- Memory (RegAddrWidth (ArchReg arch))
-> Endianness
-> MemAddr (RegAddrWidth (ArchReg arch))
-> Either
(MemoryError (RegAddrWidth (ArchReg arch))) (ArchSegmentOff arch)
forall (w :: Nat).
Memory w
-> Endianness
-> MemAddr w
-> Either (MemoryError w) (MemSegmentOff w)
readSegmentOff Memory (RegAddrWidth (ArchReg arch))
mem Endianness
end MemAddr (RegAddrWidth (ArchReg arch))
laddr ->
ArchSegmentOff arch
val ArchSegmentOff arch
-> [ArchSegmentOff arch] -> [ArchSegmentOff arch]
forall a. a -> [a] -> [a]
: [ArchSegmentOff arch]
def
AssignRhs
arch (Value arch ids) (BVType (RegAddrWidth (ArchReg arch)))
_ -> [ArchSegmentOff arch]
def
Initial ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
_ -> [ArchSegmentOff arch]
def
callClassifier :: BlockClassifier arch ids
callClassifier :: forall arch ids. BlockClassifier arch ids
callClassifier = String
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall arch ids a.
String
-> BlockClassifierM arch ids a -> BlockClassifierM arch ids a
classifierName String
"Call" (BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
BlockClassifierContext arch ids
bcc <- BlockClassifierM arch ids (BlockClassifierContext arch ids)
forall r (m :: Type -> Type). MonadReader r m => m r
CMR.ask
let ctx :: ParseContext arch ids
ctx = BlockClassifierContext arch ids -> ParseContext arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParseContext arch ids
classifierParseContext BlockClassifierContext arch ids
bcc
let finalRegs :: RegState (ArchReg arch) (Value arch ids)
finalRegs = BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc
let ainfo :: ArchitectureInfo arch
ainfo = ParseContext arch ids -> ArchitectureInfo arch
forall arch ids. ParseContext arch ids -> ArchitectureInfo arch
pctxArchInfo ParseContext arch ids
ctx
let mem :: Memory (ArchAddrWidth arch)
mem = ParseContext arch ids -> Memory (ArchAddrWidth arch)
forall arch ids.
ParseContext arch ids -> Memory (ArchAddrWidth arch)
pctxMemory ParseContext arch ids
ctx
MemSegmentOff (ArchAddrWidth arch)
ret <- case ArchitectureInfo arch
-> forall ids.
Memory (ArchAddrWidth arch)
-> Seq (Stmt arch ids)
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (Seq (Stmt arch ids), MemSegmentOff (ArchAddrWidth arch))
forall arch.
ArchitectureInfo arch
-> forall ids.
Memory (ArchAddrWidth arch)
-> Seq (Stmt arch ids)
-> RegState (ArchReg arch) (Value arch ids)
-> Maybe (Seq (Stmt arch ids), ArchSegmentOff arch)
Info.identifyCall ArchitectureInfo arch
ainfo Memory (ArchAddrWidth arch)
mem (BlockClassifierContext arch ids -> Seq (Stmt arch ids)
forall arch ids.
BlockClassifierContext arch ids -> Seq (Stmt arch ids)
classifierStmts BlockClassifierContext arch ids
bcc) RegState (ArchReg arch) (Value arch ids)
finalRegs of
Just (Seq (Stmt arch ids)
_prev_stmts, MemSegmentOff (ArchAddrWidth arch)
ret) -> MemSegmentOff (ArchAddrWidth arch)
-> BlockClassifierM arch ids (MemSegmentOff (ArchAddrWidth arch))
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure MemSegmentOff (ArchAddrWidth arch)
ret
Maybe (Seq (Stmt arch ids), MemSegmentOff (ArchAddrWidth arch))
Nothing -> String
-> BlockClassifierM arch ids (MemSegmentOff (ArchAddrWidth arch))
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail String
"Call classifier failed."
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
forall arch.
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
Info.withArchConstraints ArchitectureInfo arch
ainfo ((ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> (ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ Parsed.ParsedContents { parsedNonterm :: [Stmt arch ids]
Parsed.parsedNonterm = Seq (Stmt arch ids) -> [Stmt arch ids]
forall a. Seq a -> [a]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
F.toList (BlockClassifierContext arch ids -> Seq (Stmt arch ids)
forall arch ids.
BlockClassifierContext arch ids -> Seq (Stmt arch ids)
classifierStmts BlockClassifierContext arch ids
bcc)
, parsedTerm :: ParsedTermStmt arch ids
Parsed.parsedTerm = RegState (ArchReg arch) (Value arch ids)
-> Maybe (MemSegmentOff (ArchAddrWidth arch))
-> ParsedTermStmt arch ids
forall arch ids.
RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch) -> ParsedTermStmt arch ids
Parsed.ParsedCall RegState (ArchReg arch) (Value arch ids)
finalRegs (MemSegmentOff (ArchAddrWidth arch)
-> Maybe (MemSegmentOff (ArchAddrWidth arch))
forall a. a -> Maybe a
Just MemSegmentOff (ArchAddrWidth arch)
ret)
, writtenCodeAddrs :: [MemSegmentOff (ArchAddrWidth arch)]
Parsed.writtenCodeAddrs = (MemSegmentOff (ArchAddrWidth arch) -> Bool)
-> [MemSegmentOff (ArchAddrWidth arch)]
-> [MemSegmentOff (ArchAddrWidth arch)]
forall a. (a -> Bool) -> [a] -> [a]
filter (MemSegmentOff (ArchAddrWidth arch)
-> MemSegmentOff (ArchAddrWidth arch) -> Bool
forall a. Eq a => a -> a -> Bool
/= MemSegmentOff (ArchAddrWidth arch)
ret) (BlockClassifierContext arch ids
-> [MemSegmentOff (ArchAddrWidth arch)]
forall arch ids.
BlockClassifierContext arch ids -> [ArchSegmentOff arch]
classifierWrittenAddrs BlockClassifierContext arch ids
bcc)
, intraJumpTargets :: [IntraJumpTarget arch]
Parsed.intraJumpTargets =
[( MemSegmentOff (ArchAddrWidth arch)
ret
, ArchitectureInfo arch
-> AbsProcessorState (ArchReg arch) ids
-> RegState (ArchReg arch) (Value arch ids)
-> MemSegmentOff (ArchAddrWidth arch)
-> AbsBlockState (ArchReg arch)
forall arch ids.
ArchitectureInfo arch
-> AbsProcessorState (ArchReg arch) ids
-> RegState (ArchReg arch) (Value arch ids)
-> ArchSegmentOff arch
-> AbsBlockState (ArchReg arch)
Info.postCallAbsState ArchitectureInfo arch
ainfo (BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
forall arch ids.
BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
classifierAbsState BlockClassifierContext arch ids
bcc) RegState (ArchReg arch) (Value arch ids)
finalRegs MemSegmentOff (ArchAddrWidth arch)
ret
, CallParams (ArchReg arch)
-> IntraJumpBounds arch ids
-> RegState (ArchReg arch) (Value arch ids)
-> InitJumpBounds arch
forall arch ids.
RegisterInfo (ArchReg arch) =>
CallParams (ArchReg arch)
-> IntraJumpBounds arch ids
-> RegState (ArchReg arch) (Value arch ids)
-> InitJumpBounds arch
Jmp.postCallBounds (ArchitectureInfo arch -> CallParams (ArchReg arch)
forall arch. ArchitectureInfo arch -> CallParams (ArchReg arch)
Info.archCallParams ArchitectureInfo arch
ainfo) (BlockClassifierContext arch ids -> IntraJumpBounds arch ids
forall arch ids.
BlockClassifierContext arch ids -> IntraJumpBounds arch ids
classifierJumpBounds BlockClassifierContext arch ids
bcc) RegState (ArchReg arch) (Value arch ids)
finalRegs
)]
, newFunctionAddrs :: [MemSegmentOff (ArchAddrWidth arch)]
Parsed.newFunctionAddrs = Memory (ArchAddrWidth arch)
-> AbsProcessorState (ArchReg arch) ids
-> RegState (ArchReg arch) (Value arch ids)
-> [MemSegmentOff (ArchAddrWidth arch)]
forall arch ids.
RegisterInfo (ArchReg arch) =>
Memory (ArchAddrWidth arch)
-> AbsProcessorState (ArchReg arch) ids
-> RegState (ArchReg arch) (Value arch ids)
-> [ArchSegmentOff arch]
identifyCallTargets Memory (ArchAddrWidth arch)
mem (BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
forall arch ids.
BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
classifierAbsState BlockClassifierContext arch ids
bcc) RegState (ArchReg arch) (Value arch ids)
finalRegs
}
returnClassifier :: BlockClassifier arch ids
returnClassifier :: forall arch ids. BlockClassifier arch ids
returnClassifier = String
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall arch ids a.
String
-> BlockClassifierM arch ids a -> BlockClassifierM arch ids a
classifierName String
"Return" (BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
BlockClassifierContext arch ids
bcc <- BlockClassifierM arch ids (BlockClassifierContext arch ids)
forall r (m :: Type -> Type). MonadReader r m => m r
CMR.ask
let ainfo :: ArchitectureInfo arch
ainfo = ParseContext arch ids -> ArchitectureInfo arch
forall arch ids. ParseContext arch ids -> ArchitectureInfo arch
pctxArchInfo (BlockClassifierContext arch ids -> ParseContext arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParseContext arch ids
classifierParseContext BlockClassifierContext arch ids
bcc)
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
forall arch.
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
Info.withArchConstraints ArchitectureInfo arch
ainfo ((ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> (ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
Just Seq (Stmt arch ids)
prevStmts <-
Maybe (Seq (Stmt arch ids))
-> BlockClassifierM arch ids (Maybe (Seq (Stmt arch ids)))
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Maybe (Seq (Stmt arch ids))
-> BlockClassifierM arch ids (Maybe (Seq (Stmt arch ids))))
-> Maybe (Seq (Stmt arch ids))
-> BlockClassifierM arch ids (Maybe (Seq (Stmt arch ids)))
forall a b. (a -> b) -> a -> b
$ ArchitectureInfo arch
-> forall ids.
Seq (Stmt arch ids)
-> RegState (ArchReg arch) (Value arch ids)
-> AbsProcessorState (ArchReg arch) ids
-> Maybe (Seq (Stmt arch ids))
forall arch.
ArchitectureInfo arch
-> forall ids.
Seq (Stmt arch ids)
-> RegState (ArchReg arch) (Value arch ids)
-> AbsProcessorState (ArchReg arch) ids
-> Maybe (Seq (Stmt arch ids))
Info.identifyReturn ArchitectureInfo arch
ainfo
(BlockClassifierContext arch ids -> Seq (Stmt arch ids)
forall arch ids.
BlockClassifierContext arch ids -> Seq (Stmt arch ids)
classifierStmts BlockClassifierContext arch ids
bcc)
(BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc)
(BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
forall arch ids.
BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
classifierAbsState BlockClassifierContext arch ids
bcc)
ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ Parsed.ParsedContents { parsedNonterm :: [Stmt arch ids]
Parsed.parsedNonterm = Seq (Stmt arch ids) -> [Stmt arch ids]
forall a. Seq a -> [a]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
F.toList Seq (Stmt arch ids)
prevStmts
, parsedTerm :: ParsedTermStmt arch ids
Parsed.parsedTerm = RegState (ArchReg arch) (Value arch ids) -> ParsedTermStmt arch ids
forall arch ids.
RegState (ArchReg arch) (Value arch ids) -> ParsedTermStmt arch ids
Parsed.ParsedReturn (BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc)
, writtenCodeAddrs :: [ArchSegmentOff arch]
Parsed.writtenCodeAddrs = BlockClassifierContext arch ids -> [ArchSegmentOff arch]
forall arch ids.
BlockClassifierContext arch ids -> [ArchSegmentOff arch]
classifierWrittenAddrs BlockClassifierContext arch ids
bcc
, intraJumpTargets :: [IntraJumpTarget arch]
Parsed.intraJumpTargets = []
, newFunctionAddrs :: [ArchSegmentOff arch]
Parsed.newFunctionAddrs = []
}
directJumpClassifier :: BlockClassifier arch ids
directJumpClassifier :: forall arch ids. BlockClassifier arch ids
directJumpClassifier = String
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall arch ids a.
String
-> BlockClassifierM arch ids a -> BlockClassifierM arch ids a
classifierName String
"Jump" (BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
BlockClassifierContext arch ids
bcc <- BlockClassifierM arch ids (BlockClassifierContext arch ids)
forall r (m :: Type -> Type). MonadReader r m => m r
CMR.ask
let ctx :: ParseContext arch ids
ctx = BlockClassifierContext arch ids -> ParseContext arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParseContext arch ids
classifierParseContext BlockClassifierContext arch ids
bcc
let ainfo :: ArchitectureInfo arch
ainfo = ParseContext arch ids -> ArchitectureInfo arch
forall arch ids. ParseContext arch ids -> ArchitectureInfo arch
pctxArchInfo ParseContext arch ids
ctx
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
forall arch.
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
Info.withArchConstraints ArchitectureInfo arch
ainfo ((ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> (ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
MemSegmentOff (RegAddrWidth (ArchReg arch))
tgtMSeg <- ParseContext arch ids
-> String
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall arch ids.
RegisterInfo (ArchReg arch) =>
ParseContext arch ids
-> String
-> Value arch ids (BVType (ArchAddrWidth arch))
-> BlockClassifierM arch ids (ArchSegmentOff arch)
classifyDirectJump ParseContext arch ids
ctx String
"Jump" (BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc RegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
forall s a. s -> Getting a s a -> a
^. ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
ip_reg)
let abst :: AbsBlockState (ArchReg arch)
abst = AbsProcessorState (ArchReg arch) ids
-> RegState (ArchReg arch) (Value arch ids)
-> AbsBlockState (ArchReg arch)
forall a ids.
RegisterInfo (ArchReg a) =>
AbsProcessorState (ArchReg a) ids
-> RegState (ArchReg a) (Value a ids) -> AbsBlockState (ArchReg a)
finalAbsBlockState (BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
forall arch ids.
BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
classifierAbsState BlockClassifierContext arch ids
bcc) (BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc)
let abst' :: AbsBlockState (ArchReg arch)
abst' = AbsBlockState (ArchReg arch)
abst AbsBlockState (ArchReg arch)
-> (AbsBlockState (ArchReg arch) -> AbsBlockState (ArchReg arch))
-> AbsBlockState (ArchReg arch)
forall a b. a -> (a -> b) -> b
& MemSegmentOff (RegAddrWidth (ArchReg arch))
-> AbsBlockState (ArchReg arch) -> AbsBlockState (ArchReg arch)
forall (r :: Type -> Type).
RegisterInfo r =>
MemSegmentOff (RegAddrWidth r)
-> AbsBlockState r -> AbsBlockState r
setAbsIP MemSegmentOff (RegAddrWidth (ArchReg arch))
tgtMSeg
let tgtBnds :: InitJumpBounds arch
tgtBnds = IntraJumpBounds arch ids
-> RegState (ArchReg arch) (Value arch ids) -> InitJumpBounds arch
forall arch ids.
RegisterInfo (ArchReg arch) =>
IntraJumpBounds arch ids
-> RegState (ArchReg arch) (Value arch ids) -> InitJumpBounds arch
Jmp.postJumpBounds (BlockClassifierContext arch ids -> IntraJumpBounds arch ids
forall arch ids.
BlockClassifierContext arch ids -> IntraJumpBounds arch ids
classifierJumpBounds BlockClassifierContext arch ids
bcc) (BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc)
ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ Parsed.ParsedContents { parsedNonterm :: [Stmt arch ids]
Parsed.parsedNonterm = Seq (Stmt arch ids) -> [Stmt arch ids]
forall a. Seq a -> [a]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
F.toList (BlockClassifierContext arch ids -> Seq (Stmt arch ids)
forall arch ids.
BlockClassifierContext arch ids -> Seq (Stmt arch ids)
classifierStmts BlockClassifierContext arch ids
bcc)
, parsedTerm :: ParsedTermStmt arch ids
Parsed.parsedTerm = RegState (ArchReg arch) (Value arch ids)
-> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> ParsedTermStmt arch ids
forall arch ids.
RegState (ArchReg arch) (Value arch ids)
-> ArchSegmentOff arch -> ParsedTermStmt arch ids
Parsed.ParsedJump (BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc) MemSegmentOff (RegAddrWidth (ArchReg arch))
tgtMSeg
, writtenCodeAddrs :: [MemSegmentOff (RegAddrWidth (ArchReg arch))]
Parsed.writtenCodeAddrs = BlockClassifierContext arch ids
-> [MemSegmentOff (RegAddrWidth (ArchReg arch))]
forall arch ids.
BlockClassifierContext arch ids -> [ArchSegmentOff arch]
classifierWrittenAddrs BlockClassifierContext arch ids
bcc
, intraJumpTargets :: [IntraJumpTarget arch]
Parsed.intraJumpTargets = [(MemSegmentOff (RegAddrWidth (ArchReg arch))
tgtMSeg, AbsBlockState (ArchReg arch)
abst', InitJumpBounds arch
tgtBnds)]
, newFunctionAddrs :: [MemSegmentOff (RegAddrWidth (ArchReg arch))]
Parsed.newFunctionAddrs = []
}
classifierEndBlock :: BlockClassifierContext arch ids
-> MemAddr (ArchAddrWidth arch)
classifierEndBlock :: forall arch ids.
BlockClassifierContext arch ids -> MemAddr (ArchAddrWidth arch)
classifierEndBlock BlockClassifierContext arch ids
ctx = ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
forall arch.
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
Info.withArchConstraints (ParseContext arch ids -> ArchitectureInfo arch
forall arch ids. ParseContext arch ids -> ArchitectureInfo arch
pctxArchInfo (BlockClassifierContext arch ids -> ParseContext arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParseContext arch ids
classifierParseContext BlockClassifierContext arch ids
ctx)) ((ArchConstraints arch => MemAddr (ArchAddrWidth arch))
-> MemAddr (ArchAddrWidth arch))
-> (ArchConstraints arch => MemAddr (ArchAddrWidth arch))
-> MemAddr (ArchAddrWidth arch)
forall a b. (a -> b) -> a -> b
$
let blockStart :: MemAddr (ArchAddrWidth arch)
blockStart = MemSegmentOff (ArchAddrWidth arch) -> MemAddr (ArchAddrWidth arch)
forall (w :: Nat). MemSegmentOff w -> MemAddr w
segoffAddr (ParseContext arch ids -> MemSegmentOff (ArchAddrWidth arch)
forall arch ids. ParseContext arch ids -> ArchSegmentOff arch
pctxAddr (BlockClassifierContext arch ids -> ParseContext arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParseContext arch ids
classifierParseContext BlockClassifierContext arch ids
ctx))
in Integer
-> MemAddr (ArchAddrWidth arch) -> MemAddr (ArchAddrWidth arch)
forall (w :: Nat). MemWidth w => Integer -> MemAddr w -> MemAddr w
incAddr (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (BlockClassifierContext arch ids -> Int
forall arch ids. BlockClassifierContext arch ids -> Int
classifierBlockSize BlockClassifierContext arch ids
ctx)) MemAddr (ArchAddrWidth arch)
blockStart
noreturnCallParsedContents :: BlockClassifierContext arch ids -> Parsed.ParsedContents arch ids
noreturnCallParsedContents :: forall arch ids.
BlockClassifierContext arch ids -> ParsedContents arch ids
noreturnCallParsedContents BlockClassifierContext arch ids
bcc =
let ctx :: ParseContext arch ids
ctx = BlockClassifierContext arch ids -> ParseContext arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParseContext arch ids
classifierParseContext BlockClassifierContext arch ids
bcc
mem :: Memory (ArchAddrWidth arch)
mem = ParseContext arch ids -> Memory (ArchAddrWidth arch)
forall arch ids.
ParseContext arch ids -> Memory (ArchAddrWidth arch)
pctxMemory ParseContext arch ids
ctx
absState :: AbsProcessorState (ArchReg arch) ids
absState = BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
forall arch ids.
BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
classifierAbsState BlockClassifierContext arch ids
bcc
regs :: RegState (ArchReg arch) (Value arch ids)
regs = BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc
blockEnd :: MemAddr (ArchAddrWidth arch)
blockEnd = BlockClassifierContext arch ids -> MemAddr (ArchAddrWidth arch)
forall arch ids.
BlockClassifierContext arch ids -> MemAddr (ArchAddrWidth arch)
classifierEndBlock BlockClassifierContext arch ids
bcc
in ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
forall arch.
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
Info.withArchConstraints (ParseContext arch ids -> ArchitectureInfo arch
forall arch ids. ParseContext arch ids -> ArchitectureInfo arch
pctxArchInfo ParseContext arch ids
ctx) ((ArchConstraints arch => ParsedContents arch ids)
-> ParsedContents arch ids)
-> (ArchConstraints arch => ParsedContents arch ids)
-> ParsedContents arch ids
forall a b. (a -> b) -> a -> b
$
Parsed.ParsedContents { parsedNonterm :: [Stmt arch ids]
Parsed.parsedNonterm = Seq (Stmt arch ids) -> [Stmt arch ids]
forall a. Seq a -> [a]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
F.toList (BlockClassifierContext arch ids -> Seq (Stmt arch ids)
forall arch ids.
BlockClassifierContext arch ids -> Seq (Stmt arch ids)
classifierStmts BlockClassifierContext arch ids
bcc)
, parsedTerm :: ParsedTermStmt arch ids
Parsed.parsedTerm = RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch) -> ParsedTermStmt arch ids
forall arch ids.
RegState (ArchReg arch) (Value arch ids)
-> Maybe (ArchSegmentOff arch) -> ParsedTermStmt arch ids
Parsed.ParsedCall RegState (ArchReg arch) (Value arch ids)
regs Maybe (ArchSegmentOff arch)
forall a. Maybe a
Nothing
, writtenCodeAddrs :: [ArchSegmentOff arch]
Parsed.writtenCodeAddrs =
(ArchSegmentOff arch -> Bool)
-> [ArchSegmentOff arch] -> [ArchSegmentOff arch]
forall a. (a -> Bool) -> [a] -> [a]
filter (\ArchSegmentOff arch
a -> ArchSegmentOff arch -> MemAddr (ArchAddrWidth arch)
forall (w :: Nat). MemSegmentOff w -> MemAddr w
segoffAddr ArchSegmentOff arch
a MemAddr (ArchAddrWidth arch)
-> MemAddr (ArchAddrWidth arch) -> Bool
forall a. Eq a => a -> a -> Bool
/= MemAddr (ArchAddrWidth arch)
blockEnd) ([ArchSegmentOff arch] -> [ArchSegmentOff arch])
-> [ArchSegmentOff arch] -> [ArchSegmentOff arch]
forall a b. (a -> b) -> a -> b
$
BlockClassifierContext arch ids -> [ArchSegmentOff arch]
forall arch ids.
BlockClassifierContext arch ids -> [ArchSegmentOff arch]
classifierWrittenAddrs BlockClassifierContext arch ids
bcc
, intraJumpTargets :: [IntraJumpTarget arch]
Parsed.intraJumpTargets = []
, newFunctionAddrs :: [ArchSegmentOff arch]
Parsed.newFunctionAddrs = Memory (ArchAddrWidth arch)
-> AbsProcessorState (ArchReg arch) ids
-> RegState (ArchReg arch) (Value arch ids)
-> [ArchSegmentOff arch]
forall arch ids.
RegisterInfo (ArchReg arch) =>
Memory (ArchAddrWidth arch)
-> AbsProcessorState (ArchReg arch) ids
-> RegState (ArchReg arch) (Value arch ids)
-> [ArchSegmentOff arch]
identifyCallTargets Memory (ArchAddrWidth arch)
mem AbsProcessorState (ArchReg arch) ids
absState RegState (ArchReg arch) (Value arch ids)
regs
}
noreturnCallClassifier :: BlockClassifier arch ids
noreturnCallClassifier :: forall arch ids. BlockClassifier arch ids
noreturnCallClassifier = String
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall arch ids a.
String
-> BlockClassifierM arch ids a -> BlockClassifierM arch ids a
classifierName String
"No return call" (BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
BlockClassifierContext arch ids
bcc <- BlockClassifierM arch ids (BlockClassifierContext arch ids)
forall r (m :: Type -> Type). MonadReader r m => m r
CMR.ask
let ctx :: ParseContext arch ids
ctx = BlockClassifierContext arch ids -> ParseContext arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParseContext arch ids
classifierParseContext BlockClassifierContext arch ids
bcc
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
forall arch.
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
Info.withArchConstraints (ParseContext arch ids -> ArchitectureInfo arch
forall arch ids. ParseContext arch ids -> ArchitectureInfo arch
pctxArchInfo ParseContext arch ids
ctx) ((ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> (ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
let regs :: RegState (ArchReg arch) (Value arch ids)
regs = BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc
let ipVal :: Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal = RegState (ArchReg arch) (Value arch ids)
regs RegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
forall s a. s -> Getting a s a -> a
^. ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
ip_reg
MemAddr (RegAddrWidth (ArchReg arch))
ma <-
case Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> Maybe (MemAddr (RegAddrWidth (ArchReg arch)))
forall arch ids.
MemWidth (ArchAddrWidth arch) =>
BVValue arch ids (ArchAddrWidth arch) -> Maybe (ArchMemAddr arch)
valueAsMemAddr Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal of
Maybe (MemAddr (RegAddrWidth (ArchReg arch)))
Nothing -> String
-> BlockClassifierM
arch ids (MemAddr (RegAddrWidth (ArchReg arch)))
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String
-> BlockClassifierM
arch ids (MemAddr (RegAddrWidth (ArchReg arch))))
-> String
-> BlockClassifierM
arch ids (MemAddr (RegAddrWidth (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$ String -> String -> String
forall r. PrintfType r => String -> r
printf String
"Noreturn target %s is not a valid address." (Value arch ids (BVType (RegAddrWidth (ArchReg arch))) -> String
forall a. Show a => a -> String
show Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal)
Just MemAddr (RegAddrWidth (ArchReg arch))
a -> MemAddr (RegAddrWidth (ArchReg arch))
-> BlockClassifierM
arch ids (MemAddr (RegAddrWidth (ArchReg arch)))
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure MemAddr (RegAddrWidth (ArchReg arch))
a
MemSegmentOff (RegAddrWidth (ArchReg arch))
a <- case Memory (RegAddrWidth (ArchReg arch))
-> MemAddr (RegAddrWidth (ArchReg arch))
-> Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall (w :: Nat). Memory w -> MemAddr w -> Maybe (MemSegmentOff w)
asSegmentOff (ParseContext arch ids -> Memory (RegAddrWidth (ArchReg arch))
forall arch ids.
ParseContext arch ids -> Memory (ArchAddrWidth arch)
pctxMemory ParseContext arch ids
ctx) MemAddr (RegAddrWidth (ArchReg arch))
ma of
Maybe (MemSegmentOff (RegAddrWidth (ArchReg arch)))
Nothing ->
String
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch))))
-> String
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall a b. (a -> b) -> a -> b
$ String -> String -> String
forall r. PrintfType r => String -> r
printf String
"Noreturn target %s is not a segment offset." (Value arch ids (BVType (RegAddrWidth (ArchReg arch))) -> String
forall a. Show a => a -> String
show Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
ipVal)
Just MemSegmentOff (RegAddrWidth (ArchReg arch))
sa -> MemSegmentOff (RegAddrWidth (ArchReg arch))
-> BlockClassifierM
arch ids (MemSegmentOff (RegAddrWidth (ArchReg arch)))
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure MemSegmentOff (RegAddrWidth (ArchReg arch))
sa
case MemSegmentOff (RegAddrWidth (ArchReg arch))
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) NoReturnFunStatus
-> Maybe NoReturnFunStatus
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup MemSegmentOff (RegAddrWidth (ArchReg arch))
a (ParseContext arch ids
-> Map
(MemSegmentOff (RegAddrWidth (ArchReg arch))) NoReturnFunStatus
forall arch ids.
ParseContext arch ids
-> Map (ArchSegmentOff arch) NoReturnFunStatus
pctxKnownFnEntries ParseContext arch ids
ctx) of
Maybe NoReturnFunStatus
Nothing -> String -> BlockClassifierM arch ids ()
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> BlockClassifierM arch ids ())
-> String -> BlockClassifierM arch ids ()
forall a b. (a -> b) -> a -> b
$ String -> String -> String
forall r. PrintfType r => String -> r
printf String
"Noreturn target %s is not a known function entry." (MemSegmentOff (RegAddrWidth (ArchReg arch)) -> String
forall a. Show a => a -> String
show MemSegmentOff (RegAddrWidth (ArchReg arch))
a)
Just NoReturnFunStatus
MayReturnFun -> String -> BlockClassifierM arch ids ()
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail (String -> BlockClassifierM arch ids ())
-> String -> BlockClassifierM arch ids ()
forall a b. (a -> b) -> a -> b
$ String -> String -> String
forall r. PrintfType r => String -> r
printf String
"Return target %s labeled mayreturn." (MemSegmentOff (RegAddrWidth (ArchReg arch)) -> String
forall a. Show a => a -> String
show MemSegmentOff (RegAddrWidth (ArchReg arch))
a)
Just NoReturnFunStatus
NoReturnFun -> () -> BlockClassifierM arch ids ()
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ()
ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$! BlockClassifierContext arch ids -> ParsedContents arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParsedContents arch ids
noreturnCallParsedContents BlockClassifierContext arch ids
bcc
tailCallClassifier :: BlockClassifier arch ids
tailCallClassifier :: forall arch ids. BlockClassifier arch ids
tailCallClassifier = String
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall arch ids a.
String
-> BlockClassifierM arch ids a -> BlockClassifierM arch ids a
classifierName String
"Tail call" (BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
BlockClassifierContext arch ids
bcc <- BlockClassifierM arch ids (BlockClassifierContext arch ids)
forall r (m :: Type -> Type). MonadReader r m => m r
CMR.ask
let ctx :: ParseContext arch ids
ctx = BlockClassifierContext arch ids -> ParseContext arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParseContext arch ids
classifierParseContext BlockClassifierContext arch ids
bcc
let ainfo :: ArchitectureInfo arch
ainfo = ParseContext arch ids -> ArchitectureInfo arch
forall arch ids. ParseContext arch ids -> ArchitectureInfo arch
pctxArchInfo ParseContext arch ids
ctx
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
forall arch.
ArchitectureInfo arch -> forall a. (ArchConstraints arch => a) -> a
Info.withArchConstraints ArchitectureInfo arch
ainfo ((ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> (ArchConstraints arch =>
BlockClassifierM arch ids (ParsedContents arch ids))
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$ do
let spVal :: Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
spVal = BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc RegState (ArchReg arch) (Value arch ids)
-> Getting
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
forall s a. s -> Getting a s a -> a
^. ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
-> Lens'
(RegState (ArchReg arch) (Value arch ids))
(Value arch ids (BVType (RegAddrWidth (ArchReg arch))))
forall {k} (r :: k -> Type) (f :: k -> Type) (tp :: k).
OrdF r =>
r tp -> Lens' (RegState r f) (f tp)
boundValue ArchReg arch (BVType (RegAddrWidth (ArchReg arch)))
forall (r :: Type -> Type).
RegisterInfo r =>
r (BVType (RegAddrWidth r))
sp_reg
Int64
o <-
case AbsProcessorState (ArchReg arch) ids
-> Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
-> ArchAbsValue arch (BVType (RegAddrWidth (ArchReg arch)))
forall a ids (tp :: Type).
(RegisterInfo (ArchReg a), HasCallStack) =>
AbsProcessorState (ArchReg a) ids
-> Value a ids tp -> ArchAbsValue a tp
transferValue (BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
forall arch ids.
BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
classifierAbsState BlockClassifierContext arch ids
bcc) Value arch ids (BVType (RegAddrWidth (ArchReg arch)))
spVal of
StackOffsetAbsVal MemAddr (RegAddrWidth (ArchReg arch))
_ Int64
o -> Int64 -> BlockClassifierM arch ids Int64
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Int64
o
ArchAbsValue arch (BVType (RegAddrWidth (ArchReg arch)))
_ -> String -> BlockClassifierM arch ids Int64
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail String
"Not a stack offset"
Bool
-> BlockClassifierM arch ids () -> BlockClassifierM arch ids ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
unless (Int64
o Int64 -> Int64 -> Bool
forall a. Eq a => a -> a -> Bool
== Int64
0) (BlockClassifierM arch ids () -> BlockClassifierM arch ids ())
-> BlockClassifierM arch ids () -> BlockClassifierM arch ids ()
forall a b. (a -> b) -> a -> b
$
String -> BlockClassifierM arch ids ()
forall a. String -> BlockClassifierM arch ids a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail String
"Expected stack height of 0"
Bool
-> BlockClassifierM arch ids () -> BlockClassifierM arch ids ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
unless (ArchitectureInfo arch
-> forall ids.
RegState (ArchReg arch) (Value arch ids)
-> AbsProcessorState (ArchReg arch) ids -> Bool
forall arch.
ArchitectureInfo arch
-> forall ids.
RegState (ArchReg arch) (Value arch ids)
-> AbsProcessorState (ArchReg arch) ids -> Bool
Info.checkForReturnAddr ArchitectureInfo arch
ainfo (BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
forall arch ids.
BlockClassifierContext arch ids
-> RegState (ArchReg arch) (Value arch ids)
classifierFinalRegState BlockClassifierContext arch ids
bcc) (BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
forall arch ids.
BlockClassifierContext arch ids
-> AbsProcessorState (ArchReg arch) ids
classifierAbsState BlockClassifierContext arch ids
bcc)) BlockClassifierM arch ids ()
forall a. BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Alternative f => f a
empty
ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a. a -> BlockClassifierM arch ids a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids))
-> ParsedContents arch ids
-> BlockClassifierM arch ids (ParsedContents arch ids)
forall a b. (a -> b) -> a -> b
$! BlockClassifierContext arch ids -> ParsedContents arch ids
forall arch ids.
BlockClassifierContext arch ids -> ParsedContents arch ids
noreturnCallParsedContents BlockClassifierContext arch ids
bcc