{-# LANGUAGE RecordWildCards #-} module Main(main) where {- This is an example program emulating most of the functionality of udis86's udcli. It additionally provides a command-line option "-dump", which will print the Haskell 'Instruction' data structures to standard output. Compile with: $ ghc --make -O hdcli.hs -} import Hdis86 import System.Environment ( getArgs ) import Control.Monad import Text.Printf import qualified Data.ByteString as BS data Opts = Opts { skip :: Int , count :: Maybe Int , doOff :: Bool , doHex :: Bool , doDump :: Bool , file :: Maybe String } deriving (Show) getOpts :: [String] -> (Opts, Config) getOpts = go (dfl, amd32 { cfgSyntax = SyntaxIntel }) where dfl = Opts 0 Nothing True True False Nothing go pair@(opt,cfg) = f where f [] = pair f [fname@(c:_)] | c /= '-' = (opt { file = Just fname }, cfg) f ("-16" :xs) = go (opt, cfg { cfgCPUMode = Mode16 }) xs f ("-32" :xs) = go (opt, cfg { cfgCPUMode = Mode32 }) xs f ("-64" :xs) = go (opt, cfg { cfgCPUMode = Mode64 }) xs f ("-intel" :xs) = go (opt, cfg { cfgSyntax = SyntaxIntel }) xs f ("-att" :xs) = go (opt, cfg { cfgSyntax = SyntaxATT }) xs f ("-v":"intel":xs) = go (opt, cfg { cfgVendor = Intel }) xs f ("-v":"amd" :xs) = go (opt, cfg { cfgVendor = AMD }) xs f ("-o":n :xs) = go (opt, cfg { cfgOrigin = parse n }) xs f ("-s":n :xs) = go (opt { skip = parse n }, cfg ) xs f ("-c":n :xs) = go (opt { count = Just $ parse n }, cfg ) xs f ("-noff" :xs) = go (opt { doOff = False }, cfg ) xs f ("-nohex" :xs) = go (opt { doHex = False }, cfg ) xs f ("-dump" :xs) = go (opt { doDump = True }, cfg ) xs f ("-h" :_ ) = error "takes the same arguments as udcli" f xs = error ("could not parse options: " ++ show xs) parse :: (Read a) => String -> a parse xs = case reads xs of [(v,"")] -> v _ -> error ("could not parse: " ++ show xs) main :: IO () main = do (opts@Opts{..}, cfg) <- getOpts `fmap` getArgs inpt <- case file of Nothing -> BS.getContents Just f -> BS.readFile f let chunk = maybe id BS.take count . BS.drop skip $ inpt let inst = disassembleMetadata cfg chunk mapM_ (out opts) inst out :: Opts -> Metadata -> IO () out Opts{..} Metadata{..} = do when doOff $ printf "%016x " mdOffset let (hex, leftover) = splitAt 16 mdHex when doHex $ printf "%-16s" hex _ <- printf " %-24s" mdAssembly when (doHex && leftover /= "") $ do putChar '\n' when doOff $ putStr " -" printf "%-16s" leftover when doDump $ do putChar '\n' putStr $ replicate 34 ' ' print mdInst putChar '\n'