import Data.LLVM.BitCode (parseBitCode, formatError)
import Data.LLVM.CFG (buildCFG, CFG(..), blockId)
import Text.LLVM.AST (ppModule, defBody, modDefines)
import Control.Monad (when)
import Data.Graph.Inductive.Graph (nmap, emap)
import Data.Graph.Inductive.Dot (fglToDotString, showDot)
import Data.List (partition)
import System.Environment (getArgs,getProgName)
import System.Exit (exitFailure)
import System.IO (stderr,hPutStrLn)
import qualified Data.ByteString as S
main :: IO ()
main = do
args <- getArgs
let (doCFG, files) = partition (== "-cfg") args
when (null files) (printUsage >> exitFailure)
mapM_ (disasm (not $ null doCFG)) files
printUsage :: IO ()
printUsage = do
name <- getProgName
putStrLn ("Usage: " ++ name ++ " [-cfg] { file.bc }+")
disasm :: Bool -> FilePath -> IO ()
disasm doCFG file = do
putStrLn (replicate 80 '=' ++ "\n")
putStrLn ("; " ++ file)
e <- parseBitCode =<< S.readFile file
case e of
Left err -> do
hPutStrLn stderr (formatError err)
exitFailure
Right m -> do
print (ppModule m)
when doCFG $ do
let cfgs = map (buildCFG . defBody) $ modDefines m
fixup = nmap (show . blockId) . emap (const "")
mapM_ (putStrLn . showDot . fglToDotString . fixup . cfgGraph) cfgs