mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 00:25:27 +00:00
Haskell bindings: use ExceptT instead of deprecated EitherT (#1034)
Backports commit 873fffc505b29c6179a8aece18b7e331e5f879e8 from unicorn.
This commit is contained in:
parent
9e8e5645fc
commit
07f315af47
|
@ -53,9 +53,9 @@ module Unicorn
|
||||||
, version
|
, version
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad (liftM)
|
import Control.Monad (join, liftM)
|
||||||
import Control.Monad.Trans.Class (lift)
|
import Control.Monad.Trans.Class (lift)
|
||||||
import Control.Monad.Trans.Either (hoistEither, left, right, runEitherT)
|
import Control.Monad.Trans.Except (throwE, runExceptT)
|
||||||
import Data.ByteString (ByteString, pack)
|
import Data.ByteString (ByteString, pack)
|
||||||
import Foreign
|
import Foreign
|
||||||
import Prelude hiding (until)
|
import Prelude hiding (until)
|
||||||
|
@ -73,7 +73,7 @@ runEmulator :: Emulator a -- ^ The emulation code to execute
|
||||||
-> IO (Either Error a) -- ^ A result on success, or an 'Error' on
|
-> IO (Either Error a) -- ^ A result on success, or an 'Error' on
|
||||||
-- failure
|
-- failure
|
||||||
runEmulator =
|
runEmulator =
|
||||||
runEitherT
|
runExceptT
|
||||||
|
|
||||||
-- | Create a new instance of the Unicorn engine.
|
-- | Create a new instance of the Unicorn engine.
|
||||||
open :: Architecture -- ^ CPU architecture
|
open :: Architecture -- ^ CPU architecture
|
||||||
|
@ -88,7 +88,7 @@ open arch mode = do
|
||||||
lift $ mkEngine ucPtr
|
lift $ mkEngine ucPtr
|
||||||
else
|
else
|
||||||
-- Otherwise return the error
|
-- Otherwise return the error
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Query internal status of the Unicorn engine.
|
-- | Query internal status of the Unicorn engine.
|
||||||
query :: Engine -- ^ 'Unicorn' engine handle
|
query :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -97,9 +97,9 @@ query :: Engine -- ^ 'Unicorn' engine handle
|
||||||
query uc queryType = do
|
query uc queryType = do
|
||||||
(err, result) <- lift $ ucQuery uc queryType
|
(err, result) <- lift $ ucQuery uc queryType
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right result
|
pure result
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Emulate machine code for a specific duration of time.
|
-- | Emulate machine code for a specific duration of time.
|
||||||
start :: Engine -- ^ 'Unicorn' engine handle
|
start :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -117,9 +117,9 @@ start :: Engine -- ^ 'Unicorn' engine handle
|
||||||
start uc begin until timeout count = do
|
start uc begin until timeout count = do
|
||||||
err <- lift $ ucEmuStart uc begin until (maybeZ timeout) (maybeZ count)
|
err <- lift $ ucEmuStart uc begin until (maybeZ timeout) (maybeZ count)
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
where maybeZ = maybe 0 id
|
where maybeZ = maybe 0 id
|
||||||
|
|
||||||
-- | Stop emulation (which was started by 'start').
|
-- | Stop emulation (which was started by 'start').
|
||||||
|
@ -131,9 +131,9 @@ stop :: Engine -- ^ 'Unicorn' engine handle
|
||||||
stop uc = do
|
stop uc = do
|
||||||
err <- lift $ ucEmuStop uc
|
err <- lift $ ucEmuStop uc
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Register operations
|
-- Register operations
|
||||||
|
@ -148,9 +148,9 @@ regWrite :: Reg r
|
||||||
regWrite uc reg value = do
|
regWrite uc reg value = do
|
||||||
err <- lift $ ucRegWrite uc reg value
|
err <- lift $ ucRegWrite uc reg value
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Read register value.
|
-- | Read register value.
|
||||||
regRead :: Reg r
|
regRead :: Reg r
|
||||||
|
@ -161,9 +161,9 @@ regRead :: Reg r
|
||||||
regRead uc reg = do
|
regRead uc reg = do
|
||||||
(err, val) <- lift $ ucRegRead uc reg
|
(err, val) <- lift $ ucRegRead uc reg
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right val
|
pure val
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Write multiple register values.
|
-- | Write multiple register values.
|
||||||
regWriteBatch :: Reg r
|
regWriteBatch :: Reg r
|
||||||
|
@ -174,9 +174,9 @@ regWriteBatch :: Reg r
|
||||||
regWriteBatch uc regs vals = do
|
regWriteBatch uc regs vals = do
|
||||||
err <- lift $ ucRegWriteBatch uc regs vals (length regs)
|
err <- lift $ ucRegWriteBatch uc regs vals (length regs)
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Read multiple register values.
|
-- | Read multiple register values.
|
||||||
regReadBatch :: Reg r
|
regReadBatch :: Reg r
|
||||||
|
@ -187,16 +187,15 @@ regReadBatch :: Reg r
|
||||||
regReadBatch uc regs = do
|
regReadBatch uc regs = do
|
||||||
-- Allocate an array of the given size
|
-- Allocate an array of the given size
|
||||||
let size = length regs
|
let size = length regs
|
||||||
result <- lift . allocaArray size $ \array -> do
|
join . lift . allocaArray size $ \array -> do
|
||||||
err <- ucRegReadBatch uc regs array size
|
err <- ucRegReadBatch uc regs array size
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
-- If ucRegReadBatch completed successfully, pack the contents of
|
-- If ucRegReadBatch completed successfully, pack the contents of
|
||||||
-- the array into a list and return it
|
-- the array into a list and return it
|
||||||
liftM Right (peekArray size array)
|
liftM pure (peekArray size array)
|
||||||
else
|
else
|
||||||
-- Otherwise return the error
|
-- Otherwise return the error
|
||||||
return $ Left err
|
return $ throwE err
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Memory operations
|
-- Memory operations
|
||||||
|
@ -210,9 +209,9 @@ memWrite :: Engine -- ^ 'Unicorn' engine handle
|
||||||
memWrite uc address bytes = do
|
memWrite uc address bytes = do
|
||||||
err <- lift $ ucMemWrite uc address bytes
|
err <- lift $ ucMemWrite uc address bytes
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Read memory contents.
|
-- | Read memory contents.
|
||||||
memRead :: Engine -- ^ 'Unicorn' engine handle
|
memRead :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -223,16 +222,15 @@ memRead :: Engine -- ^ 'Unicorn' engine handle
|
||||||
-- an 'Error' on failure
|
-- an 'Error' on failure
|
||||||
memRead uc address size = do
|
memRead uc address size = do
|
||||||
-- Allocate an array of the given size
|
-- Allocate an array of the given size
|
||||||
result <- lift . allocaArray size $ \array -> do
|
join . lift . allocaArray size $ \array -> do
|
||||||
err <- ucMemRead uc address array size
|
err <- ucMemRead uc address array size
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
-- If ucMemRead completed successfully, pack the contents of the
|
-- If ucMemRead completed successfully, pack the contents of the
|
||||||
-- array into a ByteString and return it
|
-- array into a ByteString and return it
|
||||||
liftM (Right . pack) (peekArray size array)
|
liftM (pure . pack) (peekArray size array)
|
||||||
else
|
else
|
||||||
-- Otherwise return the error
|
-- Otherwise return the error
|
||||||
return $ Left err
|
return $ throwE err
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-- | Map a range of memory.
|
-- | Map a range of memory.
|
||||||
memMap :: Engine -- ^ 'Unicorn' engine handle
|
memMap :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -248,9 +246,9 @@ memMap :: Engine -- ^ 'Unicorn' engine handle
|
||||||
memMap uc address size perms = do
|
memMap uc address size perms = do
|
||||||
err <- lift $ ucMemMap uc address size perms
|
err <- lift $ ucMemMap uc address size perms
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Unmap a range of memory.
|
-- | Unmap a range of memory.
|
||||||
memUnmap :: Engine -- ^ 'Unicorn' engine handle
|
memUnmap :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -264,9 +262,9 @@ memUnmap :: Engine -- ^ 'Unicorn' engine handle
|
||||||
memUnmap uc address size = do
|
memUnmap uc address size = do
|
||||||
err <- lift $ ucMemUnmap uc address size
|
err <- lift $ ucMemUnmap uc address size
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Change permissions on a range of memory.
|
-- | Change permissions on a range of memory.
|
||||||
memProtect :: Engine -- ^ 'Unicorn' engine handle
|
memProtect :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -283,9 +281,9 @@ memProtect :: Engine -- ^ 'Unicorn' engine handle
|
||||||
memProtect uc address size perms = do
|
memProtect uc address size perms = do
|
||||||
err <- lift $ ucMemProtect uc address size perms
|
err <- lift $ ucMemProtect uc address size perms
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Retrieve all memory regions mapped by 'memMap'.
|
-- | Retrieve all memory regions mapped by 'memMap'.
|
||||||
memRegions :: Engine -- ^ 'Unicorn' engine handle
|
memRegions :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -294,9 +292,9 @@ memRegions uc = do
|
||||||
(err, regionPtr, count) <- lift $ ucMemRegions uc
|
(err, regionPtr, count) <- lift $ ucMemRegions uc
|
||||||
if err == ErrOk then do
|
if err == ErrOk then do
|
||||||
regions <- lift $ peekArray count regionPtr
|
regions <- lift $ peekArray count regionPtr
|
||||||
right regions
|
pure regions
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Context operations
|
-- Context operations
|
||||||
|
@ -314,7 +312,7 @@ contextAllocate uc = do
|
||||||
-- Return a CPU context if ucContextAlloc completed successfully
|
-- Return a CPU context if ucContextAlloc completed successfully
|
||||||
lift $ mkContext contextPtr
|
lift $ mkContext contextPtr
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Save a copy of the internal CPU context.
|
-- | Save a copy of the internal CPU context.
|
||||||
contextSave :: Engine -- ^ 'Unicorn' engine handle
|
contextSave :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -323,9 +321,9 @@ contextSave :: Engine -- ^ 'Unicorn' engine handle
|
||||||
contextSave uc context = do
|
contextSave uc context = do
|
||||||
err <- lift $ ucContextSave uc context
|
err <- lift $ ucContextSave uc context
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-- | Restore the current CPU context from a saved copy.
|
-- | Restore the current CPU context from a saved copy.
|
||||||
contextRestore :: Engine -- ^ 'Unicorn' engine handle
|
contextRestore :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -334,9 +332,9 @@ contextRestore :: Engine -- ^ 'Unicorn' engine handle
|
||||||
contextRestore uc context = do
|
contextRestore uc context = do
|
||||||
err <- lift $ ucContextRestore uc context
|
err <- lift $ ucContextRestore uc context
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Misc.
|
-- Misc.
|
||||||
|
|
|
@ -39,7 +39,7 @@ module Unicorn.Hook
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.Trans.Class
|
import Control.Monad.Trans.Class
|
||||||
import Control.Monad.Trans.Either (hoistEither, left, right)
|
import Control.Monad.Trans.Except (ExceptT (..), throwE)
|
||||||
import Foreign
|
import Foreign
|
||||||
|
|
||||||
import Unicorn.Internal.Core
|
import Unicorn.Internal.Core
|
||||||
|
@ -60,12 +60,11 @@ codeHookAdd :: Storable a
|
||||||
-> Word64 -- ^ End address
|
-> Word64 -- ^ End address
|
||||||
-> Emulator Hook -- ^ The hook handle on success, or an 'Error'
|
-> Emulator Hook -- ^ The hook handle on success, or an 'Error'
|
||||||
-- on failure
|
-- on failure
|
||||||
codeHookAdd uc callback userData begin end = do
|
codeHookAdd uc callback userData begin end =
|
||||||
result <- lift . alloca $ \userDataPtr -> do
|
ExceptT . alloca $ \userDataPtr -> do
|
||||||
poke userDataPtr userData
|
poke userDataPtr userData
|
||||||
funPtr <- marshalCodeHook callback
|
funPtr <- marshalCodeHook callback
|
||||||
getResult $ ucHookAdd uc HookCode funPtr userDataPtr begin end
|
getResult $ ucHookAdd uc HookCode funPtr userDataPtr begin end
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-- | Register a callback for an interrupt hook event.
|
-- | Register a callback for an interrupt hook event.
|
||||||
interruptHookAdd :: Storable a
|
interruptHookAdd :: Storable a
|
||||||
|
@ -77,12 +76,11 @@ interruptHookAdd :: Storable a
|
||||||
-> Word64 -- ^ End address
|
-> Word64 -- ^ End address
|
||||||
-> Emulator Hook -- ^ The hook handle on success, or 'Error'
|
-> Emulator Hook -- ^ The hook handle on success, or 'Error'
|
||||||
-- on failure
|
-- on failure
|
||||||
interruptHookAdd uc callback userData begin end = do
|
interruptHookAdd uc callback userData begin end =
|
||||||
result <- lift . alloca $ \userDataPtr -> do
|
ExceptT . alloca $ \userDataPtr -> do
|
||||||
poke userDataPtr userData
|
poke userDataPtr userData
|
||||||
funPtr <- marshalInterruptHook callback
|
funPtr <- marshalInterruptHook callback
|
||||||
getResult $ ucHookAdd uc HookIntr funPtr userDataPtr begin end
|
getResult $ ucHookAdd uc HookIntr funPtr userDataPtr begin end
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-- | Register a callback for a block hook event.
|
-- | Register a callback for a block hook event.
|
||||||
blockHookAdd :: Storable a
|
blockHookAdd :: Storable a
|
||||||
|
@ -94,12 +92,11 @@ blockHookAdd :: Storable a
|
||||||
-> Word64 -- ^ End address
|
-> Word64 -- ^ End address
|
||||||
-> Emulator Hook -- ^ The hook handle on success, or an 'Error'
|
-> Emulator Hook -- ^ The hook handle on success, or an 'Error'
|
||||||
-- on failure
|
-- on failure
|
||||||
blockHookAdd uc callback userData begin end = do
|
blockHookAdd uc callback userData begin end =
|
||||||
result <- lift . alloca $ \userDataPtr -> do
|
ExceptT . alloca $ \userDataPtr -> do
|
||||||
poke userDataPtr userData
|
poke userDataPtr userData
|
||||||
funPtr <- marshalBlockHook callback
|
funPtr <- marshalBlockHook callback
|
||||||
getResult $ ucHookAdd uc HookBlock funPtr userDataPtr begin end
|
getResult $ ucHookAdd uc HookBlock funPtr userDataPtr begin end
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-- | Register a callback for an IN instruction hook event (X86).
|
-- | Register a callback for an IN instruction hook event (X86).
|
||||||
inHookAdd :: Storable a
|
inHookAdd :: Storable a
|
||||||
|
@ -111,13 +108,12 @@ inHookAdd :: Storable a
|
||||||
-> Word64 -- ^ End address
|
-> Word64 -- ^ End address
|
||||||
-> Emulator Hook -- ^ The hook handle on success, or an 'Error' on
|
-> Emulator Hook -- ^ The hook handle on success, or an 'Error' on
|
||||||
-- failure
|
-- failure
|
||||||
inHookAdd uc callback userData begin end = do
|
inHookAdd uc callback userData begin end =
|
||||||
result <- lift . alloca $ \userDataPtr -> do
|
ExceptT . alloca $ \userDataPtr -> do
|
||||||
poke userDataPtr userData
|
poke userDataPtr userData
|
||||||
funPtr <- marshalInHook callback
|
funPtr <- marshalInHook callback
|
||||||
getResult $ ucInsnHookAdd uc HookInsn funPtr userDataPtr begin end
|
getResult $ ucInsnHookAdd uc HookInsn funPtr userDataPtr begin end
|
||||||
X86.In
|
X86.In
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-- | Register a callback for an OUT instruction hook event (X86).
|
-- | Register a callback for an OUT instruction hook event (X86).
|
||||||
outHookAdd :: Storable a
|
outHookAdd :: Storable a
|
||||||
|
@ -129,13 +125,12 @@ outHookAdd :: Storable a
|
||||||
-> Word64 -- ^ End address
|
-> Word64 -- ^ End address
|
||||||
-> Emulator Hook -- ^ The hook handle on success, or an 'Error' on
|
-> Emulator Hook -- ^ The hook handle on success, or an 'Error' on
|
||||||
-- failure
|
-- failure
|
||||||
outHookAdd uc callback userData begin end = do
|
outHookAdd uc callback userData begin end =
|
||||||
result <- lift . alloca $ \userDataPtr -> do
|
ExceptT . alloca $ \userDataPtr -> do
|
||||||
poke userDataPtr userData
|
poke userDataPtr userData
|
||||||
funPtr <- marshalOutHook callback
|
funPtr <- marshalOutHook callback
|
||||||
getResult $ ucInsnHookAdd uc HookInsn funPtr userDataPtr begin end
|
getResult $ ucInsnHookAdd uc HookInsn funPtr userDataPtr begin end
|
||||||
X86.Out
|
X86.Out
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-- | Register a callback for a SYSCALL instruction hook event (X86).
|
-- | Register a callback for a SYSCALL instruction hook event (X86).
|
||||||
syscallHookAdd :: Storable a
|
syscallHookAdd :: Storable a
|
||||||
|
@ -147,13 +142,12 @@ syscallHookAdd :: Storable a
|
||||||
-> Word64 -- ^ End address
|
-> Word64 -- ^ End address
|
||||||
-> Emulator Hook -- ^ The hook handle on success, or an 'Error'
|
-> Emulator Hook -- ^ The hook handle on success, or an 'Error'
|
||||||
-- on failure
|
-- on failure
|
||||||
syscallHookAdd uc callback userData begin end = do
|
syscallHookAdd uc callback userData begin end =
|
||||||
result <- lift . alloca $ \userDataPtr -> do
|
ExceptT . alloca $ \userDataPtr -> do
|
||||||
poke userDataPtr userData
|
poke userDataPtr userData
|
||||||
funPtr <- marshalSyscallHook callback
|
funPtr <- marshalSyscallHook callback
|
||||||
getResult $ ucInsnHookAdd uc HookInsn funPtr userDataPtr begin end
|
getResult $ ucInsnHookAdd uc HookInsn funPtr userDataPtr begin end
|
||||||
X86.Syscall
|
X86.Syscall
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-- | Register a callback for a valid memory access event.
|
-- | Register a callback for a valid memory access event.
|
||||||
memoryHookAdd :: Storable a
|
memoryHookAdd :: Storable a
|
||||||
|
@ -167,12 +161,11 @@ memoryHookAdd :: Storable a
|
||||||
-> Word64 -- ^ End address
|
-> Word64 -- ^ End address
|
||||||
-> Emulator Hook -- ^ The hook handle on success, or an 'Error'
|
-> Emulator Hook -- ^ The hook handle on success, or an 'Error'
|
||||||
-- on failure
|
-- on failure
|
||||||
memoryHookAdd uc memHookType callback userData begin end = do
|
memoryHookAdd uc memHookType callback userData begin end =
|
||||||
result <- lift . alloca $ \userDataPtr -> do
|
ExceptT . alloca $ \userDataPtr -> do
|
||||||
poke userDataPtr userData
|
poke userDataPtr userData
|
||||||
funPtr <- marshalMemoryHook callback
|
funPtr <- marshalMemoryHook callback
|
||||||
getResult $ ucHookAdd uc memHookType funPtr userDataPtr begin end
|
getResult $ ucHookAdd uc memHookType funPtr userDataPtr begin end
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-- | Register a callback for an invalid memory access event.
|
-- | Register a callback for an invalid memory access event.
|
||||||
memoryEventHookAdd :: Storable a
|
memoryEventHookAdd :: Storable a
|
||||||
|
@ -188,12 +181,11 @@ memoryEventHookAdd :: Storable a
|
||||||
-> Word64 -- ^ End address
|
-> Word64 -- ^ End address
|
||||||
-> Emulator Hook -- ^ The hook handle on success, or
|
-> Emulator Hook -- ^ The hook handle on success, or
|
||||||
-- an 'Error' on failure
|
-- an 'Error' on failure
|
||||||
memoryEventHookAdd uc memEventHookType callback userData begin end = do
|
memoryEventHookAdd uc memEventHookType callback userData begin end =
|
||||||
result <- lift . alloca $ \userDataPtr -> do
|
ExceptT . alloca $ \userDataPtr -> do
|
||||||
poke userDataPtr userData
|
poke userDataPtr userData
|
||||||
funPtr <- marshalMemoryEventHook callback
|
funPtr <- marshalMemoryEventHook callback
|
||||||
getResult $ ucHookAdd uc memEventHookType funPtr userDataPtr begin end
|
getResult $ ucHookAdd uc memEventHookType funPtr userDataPtr begin end
|
||||||
hoistEither result
|
|
||||||
|
|
||||||
-- | Unregister (remove) a hook callback.
|
-- | Unregister (remove) a hook callback.
|
||||||
hookDel :: Engine -- ^ 'Unicorn' engine handle
|
hookDel :: Engine -- ^ 'Unicorn' engine handle
|
||||||
|
@ -202,9 +194,9 @@ hookDel :: Engine -- ^ 'Unicorn' engine handle
|
||||||
hookDel uc hook = do
|
hookDel uc hook = do
|
||||||
err <- lift $ ucHookDel uc hook
|
err <- lift $ ucHookDel uc hook
|
||||||
if err == ErrOk then
|
if err == ErrOk then
|
||||||
right ()
|
pure ()
|
||||||
else
|
else
|
||||||
left err
|
throwE err
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Helper functions
|
-- Helper functions
|
||||||
|
|
|
@ -14,7 +14,7 @@ way cabal handles ordering of chs files.
|
||||||
module Unicorn.Internal.Core where
|
module Unicorn.Internal.Core where
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.Trans.Either (EitherT)
|
import Control.Monad.Trans.Except (ExceptT)
|
||||||
import Foreign
|
import Foreign
|
||||||
|
|
||||||
{# context lib = "unicorn" #}
|
{# context lib = "unicorn" #}
|
||||||
|
@ -48,7 +48,7 @@ mkEngine ptr =
|
||||||
|
|
||||||
-- | The emulator runs in the IO monad and allows for the handling of errors
|
-- | The emulator runs in the IO monad and allows for the handling of errors
|
||||||
-- "under the hood".
|
-- "under the hood".
|
||||||
type Emulator a = EitherT Error IO a
|
type Emulator a = ExceptT Error IO a
|
||||||
|
|
||||||
-- | An architecture-dependent register.
|
-- | An architecture-dependent register.
|
||||||
class Enum a => Reg a
|
class Enum a => Reg a
|
||||||
|
|
|
@ -33,7 +33,6 @@ library
|
||||||
build-depends: base >=4 && <5
|
build-depends: base >=4 && <5
|
||||||
, bytestring >= 0.9.1
|
, bytestring >= 0.9.1
|
||||||
, transformers < 0.6
|
, transformers < 0.6
|
||||||
, either >= 4.4
|
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
c-sources: src/cbits/unicorn_wrapper.c
|
c-sources: src/cbits/unicorn_wrapper.c
|
||||||
include-dirs: src/include
|
include-dirs: src/include
|
||||||
|
|
Loading…
Reference in a new issue