- xs' :: [OffIns]
- xs' = evalState (calculateInstructionOffset xs >>= markBackwardTargets) []
-
--- get already calculated jmp-targets and mark the predecessor of the
--- target-instruction as "FallThrough". we just care about backwards
--- jumps here (forward jumps are handled in buildCFG')
-markBackwardTargets :: [OffIns] -> AnalyseState
-markBackwardTargets [] = return []
-markBackwardTargets (x:[]) = return [x]
-markBackwardTargets (x@(x_off,x_bbend,x_ins):y@(y_off,_,_):xs) = do
- rest <- markBackwardTargets (y:xs)
- targets <- get
- let isTarget = y_off `elem` targets
- x_new = case x_bbend of
- Just _ -> x -- already marked, don't change
- Nothing -> if isTarget then checkX y_off else x
- checkX w16 = case x_bbend of
- Nothing -> (x_off, Just $ FallThrough w16, x_ins) -- mark previous insn
- _ -> error "basicblock: something is wrong"
- return $ x_new:rest
-
-
-
-buildCFG' :: MapBB -> [OffIns] -> [OffIns] -> MapBB
-buildCFG' hmap [] _ = hmap
-buildCFG' hmap ((off, entry, _):xs) insns = buildCFG' (insertlist entryi hmap) xs insns
- where
- insertlist :: [BlockID] -> MapBB -> MapBB
- insertlist [] hmap' = hmap'
- insertlist (y:ys) hmap' = insertlist ys newhmap
- where
- newhmap = if M.member y hmap' then hmap' else M.insert y value hmap'
- value = parseBasicBlock y insns
- entryi :: [BlockID]
- entryi = if off == 0 then 0:ys else ys -- also consider the entrypoint