libriscv-0.1.0.0: app/Main.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
module Main where
import Control.Monad (when)
import Control.Monad.Freer
import Data.BitVector
import Data.IORef (newIORef)
import Data.Word (Word32)
import LibRISCV (RegIdx (SP), align)
import LibRISCV.CmdLine
import LibRISCV.Effects.Decoding.Default.Interpreter (
defaultDecoding,
)
import LibRISCV.Effects.Expressions.Default.Interpreter (defaultEval, evalE)
import qualified LibRISCV.Effects.Expressions.Expr as E
import LibRISCV.Effects.Logging.Default.Interpreter (
defaultLogging,
noLogging,
)
import LibRISCV.Effects.Operations.Default.Interpreter (
defaultInstructions,
dumpState,
getMem,
mkArchState,
)
import LibRISCV.Effects.Operations.Default.Machine.Memory (storeByteString)
import LibRISCV.Loader
import LibRISCV.Semantics (buildAST, writeRegister)
import Options.Applicative
main' :: BasicArgs -> IO ()
main' (BasicArgs memAddr memSize trace putReg fp) = do
state <- mkArchState memAddr memSize
elf <- readElf fp
loadElf elf $ storeByteString fromIntegral (getMem state)
entry <- startAddr elf
instRef <- newIORef (0 :: Word32)
let
initalSP = align (memAddr + memSize - 1)
evalEnv = ((== 1), evalE)
interpreter =
interpretM (defaultInstructions state)
. interpretM (defaultEval evalEnv)
. interpretM (defaultDecoding @BV instRef)
. interpretM (if trace then defaultLogging else noLogging)
runM $ interpreter $ do
writeRegister (bitVec 32 $ fromEnum SP) (E.FromInt 32 $ fromIntegral initalSP)
buildAST @32 (bitVec 32 entry)
when putReg $
dumpState state
main :: IO ()
main = main' =<< execParser opts
where
opts =
info
(basicArgs <**> helper)
( fullDesc
<> progDesc "Concrete execution of RV32I machine code"
)