Merge pull request #50 from GaloisInc/jhx/funargs

Jhx/funargs
This commit is contained in:
Joe Hendrix 2019-06-13 10:35:59 -07:00 committed by GitHub
commit 7fb1e80ae0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 107 additions and 96 deletions

View File

@ -32,3 +32,5 @@ install:
- stack build --ghc-options="-Wall -Werror" - stack build --ghc-options="-Wall -Werror"
# Run tests # Run tests
- stack test macaw-x86 macaw-x86-symbolic --ghc-options="-Wall -Werror" - stack test macaw-x86 macaw-x86-symbolic --ghc-options="-Wall -Werror"
# Build documentation
- stack haddock

View File

@ -1,5 +1,5 @@
name: macaw-base name: macaw-base
version: 0.3.7 version: 0.3.8
author: Galois, Inc. author: Galois, Inc.
maintainer: jhendrix@galois.com maintainer: jhendrix@galois.com
build-type: Simple build-type: Simple
@ -39,7 +39,7 @@ library
IntervalMap >= 0.5, IntervalMap >= 0.5,
lens >= 4.7, lens >= 4.7,
mtl, mtl,
parameterized-utils >= 2.0.0.0.100, parameterized-utils >= 2.0.0.0.101,
template-haskell, template-haskell,
text, text,
vector, vector,

View File

@ -52,6 +52,18 @@ import Data.Macaw.CFG.DemandSet
import Data.Macaw.Discovery.State import Data.Macaw.Discovery.State
import Data.Macaw.Types import Data.Macaw.Types
-- | Map from blocks to their predcessors within a function.
type PredBlockMap arch = Map (ArchSegmentOff arch) [ArchSegmentOff arch]
-- | Generate map from block within a function to their predecessors
predBlockMap :: DiscoveryFunInfo arch ids -> PredBlockMap arch
predBlockMap finfo =
Map.fromListWith (++)
[ (dest, [pblockAddr b])
| b <- Map.elems (finfo^.parsedBlocks)
, dest <- parsedTermSucc (pblockTermStmt b)
]
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- The algorithm computes the set of direct deps (i.e., from writes) -- The algorithm computes the set of direct deps (i.e., from writes)
@ -93,6 +105,11 @@ data DemandSet (r :: Type -> Kind.Type) =
, functionResultDemands :: !(Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r)) , functionResultDemands :: !(Map (MemSegmentOff (RegAddrWidth r)) (RegisterSet r))
} }
-- | Return True if the demand set indicates no registers are needed.
isEmptyDemandSet :: DemandSet r -> Bool
isEmptyDemandSet ds =
Set.null (registerDemands ds) && Map.null (functionResultDemands ds)
-- | Create a demand set for specific registers. -- | Create a demand set for specific registers.
registerDemandSet :: RegisterSet r -> DemandSet r registerDemandSet :: RegisterSet r -> DemandSet r
registerDemandSet s = DemandSet { registerDemands = s registerDemandSet s = DemandSet { registerDemands = s
@ -145,7 +162,8 @@ data DemandType r
-- | This denotes a value needed if the function at the given -- | This denotes a value needed if the function at the given
-- address needs the specific register as an argument. -- address needs the specific register as an argument.
| forall tp. DemandFunctionArg (RegSegmentOff r) (r tp) | forall tp. DemandFunctionArg (RegSegmentOff r) (r tp)
-- | This denotes demands if we need the return value of this -- | This key is used to denote the demands associating with
-- needing to compute the the return value of the
-- function stored in the given register. -- function stored in the given register.
| forall tp. DemandFunctionResult (r tp) | forall tp. DemandFunctionResult (r tp)
@ -211,12 +229,26 @@ instance OrdF r => Semigroup (BlockDemands r) where
instance OrdF r => Monoid (BlockDemands r) where instance OrdF r => Monoid (BlockDemands r) where
mempty = BD Map.empty mempty = BD Map.empty
-- | A cache from assignment identifiers to registers.
type AssignmentCache r ids = Map (Some (AssignId ids)) (RegisterSet r) type AssignmentCache r ids = Map (Some (AssignId ids)) (RegisterSet r)
-- | Maps each register to the what information is needed to compute -- | Maps each register to the what information is needed to compute
-- the value stored in that register. -- the value stored in that register.
newtype FinalRegisterDemands r = FRD (Map (Some r) (DemandSet r)) newtype FinalRegisterDemands r = FRD (Map (Some r) (DemandSet r))
-- | Add demands for a register to collection.
insertRegDemand :: OrdF r
=> r tp
-> DemandSet r
-> FinalRegisterDemands r
-> FinalRegisterDemands r
insertRegDemand r s (FRD m)
| isEmptyDemandSet s = FRD m
| otherwise = FRD (Map.insertWith mappend (Some r) s m)
postRegisterDemands :: OrdF r => FinalRegisterDemands r -> r tp -> DemandSet r
postRegisterDemands (FRD m) r = m^.ix (Some r)
instance OrdF r => Semigroup (FinalRegisterDemands r) where instance OrdF r => Semigroup (FinalRegisterDemands r) where
FRD x <> FRD y = FRD (Map.unionWith mappend x y) FRD x <> FRD y = FRD (Map.unionWith mappend x y)
@ -289,16 +321,11 @@ data FunArgContext arch = FAC
data FunctionArgsState arch ids = FAS data FunctionArgsState arch ids = FAS
{ -- | Map from block address to the result demands map for the block. { -- | Map from block address to the result demands map for the block.
_blockTransfer :: !(Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch))) _blockTransfer :: !(Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch)))
-- | If a demand d is demanded of block address then the block
-- | If a demand d is demanded of block address then the block demands S, s.t. -- demands S, s.t. `blockDemandMap ^. at addr ^. at d = Just S1
-- `blockDemandMap ^. at addr ^. at d = Just S1
, _blockDemandMap :: !(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))) , _blockDemandMap :: !(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)))
-- | A cache of the assignments and their deps. The key is not
-- | Maps each global block label to the set of blocks that have intra-procedural -- included in the set of deps (but probably should be).
-- jumps to that block. Since the function does not change, we omit the global label
, _blockPreds :: !(Map (ArchSegmentOff arch) [ArchSegmentOff arch])
-- | A cache of the assignments and their deps. The key is not included
-- in the set of deps (but probably should be).
, _assignmentCache :: !(AssignmentCache (ArchReg arch) ids) , _assignmentCache :: !(AssignmentCache (ArchReg arch) ids)
-- | Warnings from summarization in reverse order. -- | Warnings from summarization in reverse order.
, reversedWarnings :: [String] , reversedWarnings :: [String]
@ -312,9 +339,6 @@ blockDemandMap :: Simple Lens (FunctionArgsState arch ids)
(Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))) (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)))
blockDemandMap = lens _blockDemandMap (\s v -> s { _blockDemandMap = v }) blockDemandMap = lens _blockDemandMap (\s v -> s { _blockDemandMap = v })
blockPreds :: Simple Lens (FunctionArgsState arch ids) (Map (ArchSegmentOff arch) [ArchSegmentOff arch])
blockPreds = lens _blockPreds (\s v -> s { _blockPreds = v })
assignmentCache :: Simple Lens (FunctionArgsState arch ids) (AssignmentCache (ArchReg arch) ids) assignmentCache :: Simple Lens (FunctionArgsState arch ids) (AssignmentCache (ArchReg arch) ids)
assignmentCache = lens _assignmentCache (\s v -> s { _assignmentCache = v }) assignmentCache = lens _assignmentCache (\s v -> s { _assignmentCache = v })
@ -322,7 +346,6 @@ initFunctionArgsState :: [String] -> FunctionArgsState arch ids
initFunctionArgsState prevWarn = initFunctionArgsState prevWarn =
FAS { _blockTransfer = Map.empty FAS { _blockTransfer = Map.empty
, _blockDemandMap = Map.empty , _blockDemandMap = Map.empty
, _blockPreds = Map.empty
, _assignmentCache = Map.empty , _assignmentCache = Map.empty
, reversedWarnings = prevWarn , reversedWarnings = prevWarn
} }
@ -344,14 +367,6 @@ addWarning msg =
-- ---------------------------------------------------------------------------------------- -- ----------------------------------------------------------------------------------------
-- Phase one functions -- Phase one functions
-- | This registers a block in the first phase (block discovery).
addIntraproceduralJumpTarget :: {-ArchConstraints arch
=> -} ArchSegmentOff arch
-> ArchSegmentOff arch
-> FunctionArgsM arch ids ()
addIntraproceduralJumpTarget src dest = -- record the edge
blockPreds %= Map.insertWith (++) dest [src]
withAssignmentCache :: State (AssignmentCache (ArchReg arch) ids) a -> FunctionArgsM arch ids a withAssignmentCache :: State (AssignmentCache (ArchReg arch) ids) a -> FunctionArgsM arch ids a
withAssignmentCache m = do withAssignmentCache m = do
c <- use assignmentCache c <- use assignmentCache
@ -410,14 +425,14 @@ recordBlockTransfer :: forall arch ids t
-- ^ List of registers that subsequent blocks may depend on. -- ^ List of registers that subsequent blocks may depend on.
-> FunctionArgsM arch ids () -> FunctionArgsM arch ids ()
recordBlockTransfer addr regs regSet = do recordBlockTransfer addr regs regSet = do
curDemands <- fromMaybe (FRD Map.empty) . Map.lookup addr <$> use blockTransfer curDemands <- use $ blockTransfer . ix addr
let doReg :: FinalRegisterDemands (ArchReg arch) let doReg :: FinalRegisterDemands (ArchReg arch)
-> Some (ArchReg arch) -> Some (ArchReg arch)
-> State (AssignmentCache (ArchReg arch) ids) -> State (AssignmentCache (ArchReg arch) ids)
(FinalRegisterDemands (ArchReg arch)) (FinalRegisterDemands (ArchReg arch))
doReg (FRD m) (Some r) = do doReg m (Some r) = do
rs' <- valueUses (regs ^. boundValue r) rs' <- valueUses (regs^.boundValue r)
return $! FRD (Map.insertWith mappend (Some r) (registerDemandSet rs') m) pure $! insertRegDemand r (registerDemandSet rs') m
vs <- withAssignmentCache $ foldlM doReg curDemands regSet vs <- withAssignmentCache $ foldlM doReg curDemands regSet
blockTransfer %= Map.insert addr vs blockTransfer %= Map.insert addr vs
@ -517,7 +532,7 @@ linkKnownCallReturnValues addr faddr regs mReturnAddr = do
-- Update blockTransfer to indicate that for all potential -- Update blockTransfer to indicate that for all potential
-- return registers that demanding the register -- return registers that demanding the register
let linkRetReg (FRD m) sr = FRD (Map.insertWith mappend sr (demandFunctionReturn faddr sr) m) let linkRetReg m (Some r) = insertRegDemand r (demandFunctionReturn faddr (Some r)) m
let srDemandSet :: FinalRegisterDemands (ArchReg arch) let srDemandSet :: FinalRegisterDemands (ArchReg arch)
srDemandSet = foldl linkRetReg mempty retRegs srDemandSet = foldl linkRetReg mempty retRegs
@ -627,17 +642,10 @@ summarizeBlock b = do
(pblockStmts b) (pblockStmts b)
-- Add values demanded by terminal statements -- Add values demanded by terminal statements
case pblockTermStmt b of case pblockTermStmt b of
ParsedCall finalRegs mRetAddr -> do ParsedCall regs mRetAddr -> do
-- Record the intraprocural jump target for the return address.
case mRetAddr of
Nothing -> do
pure ()
Just retAddr -> do
addIntraproceduralJumpTarget addr retAddr
-- Record the demands based on the call, and add edges between -- Record the demands based on the call, and add edges between
-- this note and next nodes. -- this note and next nodes.
summarizeCall addr finalRegs mRetAddr summarizeCall addr regs mRetAddr
PLTStub regs _ sym -> do PLTStub regs _ sym -> do
-- Get argument registers if known for symbol. -- Get argument registers if known for symbol.
@ -660,45 +668,40 @@ summarizeBlock b = do
addBlockDemands addr $ demandAlways $ addBlockDemands addr $ demandAlways $
registerDemandSet $ demands registerDemandSet $ demands
ParsedJump procState tgtAddr -> do ParsedJump regs _tgtAddr -> do
-- record all propagations -- record all propagations
recordBlockTransfer addr procState archRegs recordBlockTransfer addr regs archRegs
addIntraproceduralJumpTarget addr tgtAddr
ParsedBranch nextRegs cond trueAddr falseAddr -> do ParsedBranch regs cond _trueAddr _falseAddr -> do
demandValue addr cond demandValue addr cond
-- record all propagations -- record all propagations
let notIP (Some r) = isNothing (testEquality r ip_reg) let notIP (Some r) = isNothing (testEquality r ip_reg)
recordBlockTransfer addr nextRegs (filter notIP archRegs) recordBlockTransfer addr regs (filter notIP archRegs)
addIntraproceduralJumpTarget addr trueAddr
addIntraproceduralJumpTarget addr falseAddr
ParsedLookupTable finalRegs lookup_idx vec -> do ParsedLookupTable regs lookup_idx _vec -> do
demandValue addr lookup_idx demandValue addr lookup_idx
-- record all propagations -- record all propagations
recordBlockTransfer addr finalRegs archRegs recordBlockTransfer addr regs archRegs
traverse_ (addIntraproceduralJumpTarget addr) vec
ParsedReturn finalRegs -> do ParsedReturn regs -> do
let retRegs = functionRetRegs ainfo let retRegs = functionRetRegs ainfo
let regDemandSet m (Some r) = do let regDemandSet m (Some r) = do
regs <- valueUses (finalRegs^.boundValue r) rUses <- valueUses (regs^.boundValue r)
pure $! addDemandFunctionResult r (registerDemandSet regs) m pure $! addDemandFunctionResult r (registerDemandSet rUses) m
demands <- withAssignmentCache $ foldlM regDemandSet mempty retRegs demands <- withAssignmentCache $ foldlM regDemandSet mempty retRegs
addBlockDemands addr demands addBlockDemands addr demands
ParsedArchTermStmt tstmt finalRegs next_addr -> do ParsedArchTermStmt tstmt regs _nextAddr -> do
-- Compute effects of terminal statement. -- Compute effects of terminal statement.
let e = computeArchTermStmtEffects ainfo tstmt finalRegs let e = computeArchTermStmtEffects ainfo tstmt regs
-- Demand all registers the terminal statement demands. -- Demand all registers the terminal statement demands.
do let regUses s (Some r) = addValueUses s (finalRegs^.boundValue r) do let regUses s (Some r) = addValueUses s (regs^.boundValue r)
demands <- withAssignmentCache $ demands <- withAssignmentCache $
foldlM regUses Set.empty (termRegDemands e) foldlM regUses Set.empty (termRegDemands e)
addBlockDemands addr $ demandAlways (registerDemandSet demands) addBlockDemands addr $ demandAlways (registerDemandSet demands)
recordBlockTransfer addr finalRegs (termRegTransfers e) recordBlockTransfer addr regs (termRegTransfers e)
traverse_ (addIntraproceduralJumpTarget addr) next_addr
ParsedTranslateError _ -> do ParsedTranslateError _ -> do
-- We ignore demands for translate errors. -- We ignore demands for translate errors.
@ -753,58 +756,62 @@ calculateOnePred :: ( MemWidth (ArchAddrWidth arch)
, OrdF (ArchReg arch) , OrdF (ArchReg arch)
, ShowF (ArchReg arch) , ShowF (ArchReg arch)
) )
=> ArchSegmentOff arch => Map (ArchSegmentOff arch) (FinalRegisterDemands (ArchReg arch))
-- ^ Maps the entry point of each block in the function to the
-- register demands map for that block.
-> ArchSegmentOff arch
-- ^ Address of the current block -- ^ Address of the current block
-> BlockDemands (ArchReg arch) -> BlockDemands (ArchReg arch)
-- ^ New demands for this block.
-> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)) -> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-- ^ Current demand map for function -- ^ Maps each block to the demands that have not yet
-- -- been backpropagated to predecessors.
-- Maps block addresses to their demand map.
-> ArchSegmentOff arch -> ArchSegmentOff arch
-- ^ Address of the previous block. -- ^ Address of the previous block.
-> FunctionArgsM arch ids (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))) -> FunctionArgsM arch ids (Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)))
calculateOnePred addr (BD newDemands) pendingMap predAddr = do calculateOnePred xferMap addr (BD newDemands) pendingMap predAddr = do
xfer <- use (blockTransfer . ix predAddr) let xfer = xferMap^.ix predAddr
-- update uses, returning value before this iteration -- update uses, returning value before this iteration
BD seenDemands <- use (blockDemandMap . ix predAddr) BD seenDemands <- use (blockDemandMap . ix predAddr)
demands' <- traverse (transferDemands predAddr addr xfer) newDemands demands' <- traverse (transferDemands predAddr addr xfer) newDemands
blockDemandMap %= Map.insert predAddr (unionBlockDemands (BD seenDemands) (BD demands'))
let diff :: OrdF r => DemandSet r -> DemandSet r -> Maybe (DemandSet r) let diff :: OrdF r => DemandSet r -> DemandSet r -> Maybe (DemandSet r)
diff ds1 ds2 | ds' == mempty = Nothing diff ds1 ds2 | ds' == mempty = Nothing
| otherwise = Just ds' | otherwise = Just ds'
where ds' = ds1 `demandSetDifference` ds2 where ds' = ds1 `demandSetDifference` ds2
let d = Map.differenceWith diff demands' seenDemands let d = Map.differenceWith diff demands' seenDemands
-- If no new entries are seen, then just return pendingMap -- If no new entries are seen, then just return pendingMap
if Map.null d then if Map.null d then
pure $! pendingMap pure $! pendingMap
else else do
blockDemandMap %= Map.insert predAddr (unionBlockDemands (BD seenDemands) (BD demands'))
pure $! Map.insertWith unionBlockDemands predAddr (BD d) pendingMap pure $! Map.insertWith unionBlockDemands predAddr (BD d) pendingMap
-- | This updates the block map -- | This back-propagates demands sets from blocks to their
-- predecessors until we each a fixpoint.
calculateLocalFixpoint :: forall arch ids calculateLocalFixpoint :: forall arch ids
. ( MemWidth (ArchAddrWidth arch) . ( MemWidth (ArchAddrWidth arch)
, OrdF (ArchReg arch) , OrdF (ArchReg arch)
, ShowF (ArchReg arch) , ShowF (ArchReg arch)
) )
=> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch)) => PredBlockMap arch
-- ^ Maps block addresses to new entries in demand map -- ^ Predecessor block map for function.
-- -> Map (ArchSegmentOff arch) (BlockDemands (ArchReg arch))
-- The function -- ^ Maps each block starting address to demands that
-- have not yet been back propagated.
-> FunctionArgsM arch ids () -> FunctionArgsM arch ids ()
calculateLocalFixpoint new = calculateLocalFixpoint predMap new =
case Map.maxViewWithKey new of case Map.maxViewWithKey new of
Nothing -> pure () Nothing -> pure ()
Just ((currAddr, newDemands), rest) -> do Just ((currAddr, newDemands), rest) -> do
-- propagate new demands bacl to predecessors of this block. -- propagate new demands bacl to predecessors of this block.
preds <- use $ blockPreds . ix currAddr xferMap <- use blockTransfer
next <- foldlM (calculateOnePred currAddr newDemands) rest preds next <- foldlM (calculateOnePred xferMap currAddr newDemands) rest (predMap^.ix currAddr)
calculateLocalFixpoint next calculateLocalFixpoint predMap next
-- | Intermediate information used to infer global demands. -- | Intermediate information used to infer global demands.
data FunctionSummaries r = FunctionSummaries { data FunctionSummaries r = FunctionSummaries {
@ -844,10 +851,9 @@ decomposeMap _ addr acc (DemandFunctionArg f r) v =
decomposeMap _ addr acc (DemandFunctionResult r) v = decomposeMap _ addr acc (DemandFunctionResult r) v =
acc & funResMap %~ Map.insertWith mappend addr (FRD (Map.singleton (Some r) v)) acc & funResMap %~ Map.insertWith mappend addr (FRD (Map.singleton (Some r) v))
-- Strip out callee saved registers as well. -- Strip out callee saved registers as well.
decomposeMap ds addr acc DemandAlways v = do decomposeMap ds addr acc DemandAlways v =
let v' = v { registerDemands = registerDemands v `Set.difference` ds } let v' = v { registerDemands = registerDemands v `Set.difference` ds }
acc & alwaysDemandMap %~ Map.insertWith mappend addr v' in acc & alwaysDemandMap %~ Map.insertWith mappend addr v'
-- | This records the registers a function demands in the global state after -- | This records the registers a function demands in the global state after
-- being inferred from definition. -- being inferred from definition.
@ -889,7 +895,7 @@ doOneFunction ctx acc (Some finfo) = do
-- Propagate block demands until we are done. -- Propagate block demands until we are done.
new <- use blockDemandMap new <- use blockDemandMap
calculateLocalFixpoint new calculateLocalFixpoint (predBlockMap finfo) new
-- Get registers demanded by initial block map. -- Get registers demanded by initial block map.
entryDemands <- use $ blockDemandMap . ix addr entryDemands <- use $ blockDemandMap . ix addr
@ -917,7 +923,7 @@ calculateGlobalFixpoint s = (go (s^.alwaysDemandMap) (s^.alwaysDemandMap), rever
go acc new go acc new
| Just ((fun, newDemands), rest) <- Map.maxViewWithKey new = | Just ((fun, newDemands), rest) <- Map.maxViewWithKey new =
let (nexts, acc') = backPropagate acc fun newDemands let (nexts, acc') = backPropagate acc fun newDemands
in go acc' (Map.unionWith mappend rest nexts) in go acc' (Map.unionWith mappend rest nexts)
| otherwise = acc | otherwise = acc
backPropagate :: AddrDemandMap r backPropagate :: AddrDemandMap r
@ -929,11 +935,7 @@ calculateGlobalFixpoint s = (go (s^.alwaysDemandMap) (s^.alwaysDemandMap), rever
-- notify all functions which call fun regs. -- notify all functions which call fun regs.
let goRet :: RegSegmentOff r -> Set (Some r) -> DemandSet r let goRet :: RegSegmentOff r -> Set (Some r) -> DemandSet r
goRet addr retRegs = goRet addr retRegs =
foldl (\prev r -> foldMap (\(Some r) -> postRegisterDemands (resultDemandsMap^.ix addr) r) retRegs
let FRD m = resultDemandsMap^.ix addr
in mappend prev (m^.ix r))
mempty
retRegs
retDemands :: AddrDemandMap r retDemands :: AddrDemandMap r
retDemands = Map.mapWithKey goRet rets retDemands = Map.mapWithKey goRet rets
@ -963,13 +965,14 @@ functionDemands :: forall arch
-- registers. -- registers.
-> Map BS.ByteString (ComputedRegs (ArchReg arch)) -> Map BS.ByteString (ComputedRegs (ArchReg arch))
-- ^ Known symbol registers. -- ^ Known symbol registers.
-> DiscoveryState arch -> Memory (ArchAddrWidth arch)
-- ^ State of memory for resolving segment offsets.
-> [Some (DiscoveryFunInfo arch)]
-- ^ List of function to compute demands for.
-> (AddrDemandMap (ArchReg arch), [String]) -> (AddrDemandMap (ArchReg arch), [String])
functionDemands archFns addrMap symMap ds = functionDemands archFns addrMap symMap mem entries =
calculateGlobalFixpoint (foldl' (doOneFunction ctx) m0 entries) calculateGlobalFixpoint (foldl' (doOneFunction ctx) m0 entries)
where where
notKnown (Some f) = not (Map.member (discoveredFunAddr f) addrMap)
entries = filter notKnown $ exploredFunctions ds
m0 :: FunctionSummaries (ArchReg arch) m0 :: FunctionSummaries (ArchReg arch)
m0 = FunctionSummaries m0 = FunctionSummaries
@ -980,7 +983,7 @@ functionDemands archFns addrMap symMap ds =
} }
ctx = FAC { archDemandInfo = archFns ctx = FAC { archDemandInfo = archFns
, ctxMemory = memory ds , ctxMemory = mem
, computedAddrSet = Set.fromList $ viewSome discoveredFunAddr <$> entries , computedAddrSet = Set.fromList $ viewSome discoveredFunAddr <$> entries
, resolvedAddrs = addrMap , resolvedAddrs = addrMap
, knownSymbolDecls = symMap , knownSymbolDecls = symMap

View File

@ -248,8 +248,8 @@ parsedTermSucc ts = do
ParsedBranch _ _ t f -> [t,f] ParsedBranch _ _ t f -> [t,f]
ParsedLookupTable _ _ v -> V.toList v ParsedLookupTable _ _ v -> V.toList v
ParsedReturn{} -> [] ParsedReturn{} -> []
ParsedTranslateError{} -> []
ParsedArchTermStmt _ _ ret -> maybeToList ret ParsedArchTermStmt _ _ ret -> maybeToList ret
ParsedTranslateError{} -> []
ClassifyFailure{} -> [] ClassifyFailure{} -> []
------------------------------------------------------------------------ ------------------------------------------------------------------------

2
deps/crucible vendored

@ -1 +1 @@
Subproject commit 51c03f500e514c5c9dbc7346672b07d35cc19542 Subproject commit 2ca1b72e64816736f0f4561a82920456f40df2d8

2
deps/flexdis86 vendored

@ -1 +1 @@
Subproject commit a6786e261dddf2ff3d206c7f8f76c17e50928e96 Subproject commit 751ca702a28b7c365cefcc46c281a02c3160db49

@ -1 +1 @@
Subproject commit 1562a0425a0634897c0698aa0f4c4f4c56519e1c Subproject commit ed267619990cda910e4b89a777f277805d2476c0

View File

@ -1,5 +1,5 @@
name: macaw-x86 name: macaw-x86
version: 0.0.1 version: 0.3.0
author: Galois, Inc. author: Galois, Inc.
maintainer: jhendrix@galois.com maintainer: jhendrix@galois.com
build-type: Simple build-type: Simple

View File

@ -90,6 +90,7 @@ module Data.Macaw.X86.X86Reg
, x87FPURegList , x87FPURegList
, x86StateRegs , x86StateRegs
, x86CalleeSavedRegs , x86CalleeSavedRegs
, x86GPPArgumentRegs
, x86ArgumentRegs , x86ArgumentRegs
, x86FloatArgumentRegs , x86FloatArgumentRegs
, x86ResultRegs , x86ResultRegs
@ -446,8 +447,13 @@ x86CalleeSavedRegs = Set.fromList $
, Some X87_TopReg , Some X87_TopReg
] ]
-- | General purpose registers that may be needed for arguments according
-- to X86_64 ABI.
x86GPPArgumentRegs :: [F.Reg64]
x86GPPArgumentRegs = [F.RDI, F.RSI, F.RDX, F.RCX, F.R8, F.R9 ]
x86ArgumentRegs :: [X86Reg (BVType 64)] x86ArgumentRegs :: [X86Reg (BVType 64)]
x86ArgumentRegs = X86_GP <$> [ F.RDI, F.RSI, F.RDX, F.RCX, F.R8, F.R9 ] x86ArgumentRegs = X86_GP <$> x86GPPArgumentRegs
x86FloatArgumentRegs :: [X86Reg (BVType 512)] x86FloatArgumentRegs :: [X86Reg (BVType 512)]
x86FloatArgumentRegs = X86_ZMMReg <$> [0..7] x86FloatArgumentRegs = X86_ZMMReg <$> [0..7]