module Internal.X86.StorableSpec where import Foreign import Foreign.C.Types import Test.Hspec import Test.QuickCheck import Hapstone.Internal.X86 import Internal.X86.Default -- | main spec spec :: Spec spec = describe "Hapstone.Internal.X86" $ do x86OpMemStructSpec csX86OpSpec csX86Spec getX86OpMemStruct :: IO X86OpMemStruct getX86OpMemStruct = do ptr <- mallocArray (sizeOf x86OpMemStruct) :: IO (Ptr Word8) poke (castPtr ptr) (0x01234567 :: Word32) poke (plusPtr ptr 4) (0x10325476 :: Word32) poke (plusPtr ptr 8) (0x13052746 :: Word32) poke (plusPtr ptr 12) (0x31507264 :: Int32) poke (plusPtr ptr 16) (0x3df1507264 :: Int64) peek (castPtr ptr) <* free ptr x86OpMemStruct :: X86OpMemStruct x86OpMemStruct = X86OpMemStruct 0x01234567 0x10325476 0x13052746 0x31507264 0x3df1507264 -- | X86OpMemStruct spec x86OpMemStructSpec :: Spec x86OpMemStructSpec = describe "Storable X86OpMemStruct" $ do it "has a memory layout we can handle" $ sizeOf (undefined :: X86OpMemStruct) == 4 * 4 + 8 it "has matching peek- and poke-implementations" $ property $ \s@X86OpMemStruct{} -> alloca (\p -> poke p s >> peek p) `shouldReturn` s it "parses correctly" $ getX86OpMemStruct `shouldReturn` x86OpMemStruct getCsX86Op :: IO CsX86Op getCsX86Op = do ptr <- mallocArray (sizeOf csX86Op) :: IO (Ptr Word8) poke (castPtr ptr) (fromIntegral $ fromEnum X86OpImm :: Int32) poke (plusPtr ptr 8) (0x0123456789abcdef :: Int64) poke (plusPtr ptr 32) (2 :: Word8) poke (plusPtr ptr 36) (fromIntegral $ fromEnum X86AvxBcast4 :: Int32) poke (plusPtr ptr 40) (1 :: Word8) peek (castPtr ptr) <* free ptr csX86Op :: CsX86Op csX86Op = CsX86Op (Imm 0x0123456789abcdef) 2 X86AvxBcast4 True -- | CsX86ipsOp spec csX86OpSpec :: Spec csX86OpSpec = describe "Storable CsX86Op" $ do it "has a memory layout we can handle" $ sizeOf (undefined :: CsX86Op) == 4 + 4 + 24 + 1 + 3 + 4 + 1 + 7 it "has matching peek- and poke-implementations" $ property $ \s -> alloca (\p -> poke p s >> (peek p :: IO CsX86Op)) `shouldReturn` s it "parses correctly" $ getCsX86Op `shouldReturn` csX86Op getCsX86 :: IO CsX86 getCsX86 = do ptr <- mallocArray (sizeOf csX86) :: IO (Ptr Word8) pokeArray ptr ([ 0x0, 0x1, 0x2, 0x3 -- prefix , 0x4, 0x5, 0x6, 0x7 -- opcode , 0x0 -- rex , 0x20 -- address_size , 0x21 -- modrm , 0x0 -- sib ] :: [Word8]) poke (plusPtr ptr 12) (0x01234567 :: Int32) poke (plusPtr ptr 16) (fromIntegral $ fromEnum X86RegAl :: Int32) poke (plusPtr ptr 20) (0x2 :: Int8) poke (plusPtr ptr 24) (fromIntegral $ fromEnum X86RegEdx :: Int32) poke (plusPtr ptr 28) (fromIntegral $ fromEnum X86SseCcEq :: Int32) poke (plusPtr ptr 32) (fromIntegral $ fromEnum X86AvxCcEq :: Int32) poke (plusPtr ptr 36) (0x1 :: Word8) poke (plusPtr ptr 40) (fromIntegral $ fromEnum X86AvxRmRu :: Int32) poke (plusPtr ptr 44) (0x1 :: Word8) poke (plusPtr ptr 48) csX86Op peek (castPtr ptr) <* free ptr csX86 :: CsX86 csX86 = CsX86 (Nothing, Just 0x1, Just 0x2, Just 0x3) [0x4, 0x5, 0x6, 0x7] 0x0 0x20 0x21 Nothing (Just 0x01234567) X86RegAl 0x2 X86RegEdx X86SseCcEq X86AvxCcEq True X86AvxRmRu [csX86Op] -- | CsX86 spec csX86Spec :: Spec csX86Spec = describe "Storable CsX86" $ do it "has a memory-layout we can handle" $ sizeOf (undefined :: CsX86) == 4 * 5 + 1 + 3 + 4 * 3 + 1 + 3 + 4 + 1 + 3 + 48 * 8 it "has matching peek- and poke-implementations" $ property $ \s@CsX86{} -> alloca (\p -> poke p s >> peek p) `shouldReturn` s it "parses correctly" $ getCsX86 `shouldReturn` csX86