module Keystone
( Assembler
, Engine
, Architecture(..)
, Mode(..)
, OptionType(..)
, OptionValue(..)
, runAssembler
, open
, option
, assemble
, Error(..)
, errno
, strerror
, version
) where
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Either (left, right, runEitherT)
import Data.ByteString (ByteString, packCStringLen)
import Data.List (intercalate)
import Foreign
import Keystone.Internal.Core
import Keystone.Internal.Keystone
runAssembler :: Assembler a -> IO (Either Error a) runAssembler =
runEitherT
open :: Architecture -> [Mode] -> Assembler Engine open arch mode = do
(err, ksPtr) <- lift $ ksOpen arch mode
if err == ErrOk then
lift $ mkEngine ksPtr
else
left err
option :: Engine -> OptionType -> OptionValue -> Assembler () option ks optType optValue = do
err <- lift $ ksOption ks optType optValue
if err == ErrOk then
right ()
else
left err
assemble :: Engine -> [String] -> Maybe Word64 -> Assembler (ByteString, Int) assemble ks stmts addr = do
let string = intercalate ";" stmts
(res, encPtr, encSize, statCount) <- lift $ ksAsm ks string (maybeZ addr)
if res == 0 then do
bs <- lift $ packCStringLen (castPtr encPtr, encSize)
lift $ ksFree encPtr
right (bs, statCount)
else do
err <- errno ks
left err
where maybeZ = maybe 0 id
version :: Int
version =
ksVersion nullPtr nullPtr
errno :: Engine -> Assembler Error errno =
lift . ksErrno
strerror :: Error -> String strerror =
ksStrerror