module Binja.ReferenceSource
  ( Binja.ReferenceSource.codeRefs,
  )
where

import Binja.FFI
import Binja.Types

data CodeReferenceList = CodeReferenceList
  { CodeReferenceList -> ForeignPtr BNFunctionPtr
crArrayPtr :: !(ForeignPtr BNFunctionPtr),
    CodeReferenceList -> Int
crCount :: !Int,
    CodeReferenceList -> [BNReferenceSource]
crList :: ![BNReferenceSource],
    CodeReferenceList -> BNBinaryViewPtr
crViewPtr :: !BNBinaryViewPtr
  }
  deriving (CodeReferenceList -> CodeReferenceList -> Bool
(CodeReferenceList -> CodeReferenceList -> Bool)
-> (CodeReferenceList -> CodeReferenceList -> Bool)
-> Eq CodeReferenceList
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CodeReferenceList -> CodeReferenceList -> Bool
== :: CodeReferenceList -> CodeReferenceList -> Bool
$c/= :: CodeReferenceList -> CodeReferenceList -> Bool
/= :: CodeReferenceList -> CodeReferenceList -> Bool
Eq, Int -> CodeReferenceList -> ShowS
[CodeReferenceList] -> ShowS
CodeReferenceList -> String
(Int -> CodeReferenceList -> ShowS)
-> (CodeReferenceList -> String)
-> ([CodeReferenceList] -> ShowS)
-> Show CodeReferenceList
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CodeReferenceList -> ShowS
showsPrec :: Int -> CodeReferenceList -> ShowS
$cshow :: CodeReferenceList -> String
show :: CodeReferenceList -> String
$cshowList :: [CodeReferenceList] -> ShowS
showList :: [CodeReferenceList] -> ShowS
Show)

codeRefs :: BNBinaryViewPtr -> Word64 -> IO [BNReferenceSource]
codeRefs :: BNBinaryViewPtr -> Word64 -> IO [BNReferenceSource]
codeRefs BNBinaryViewPtr
view Word64
addr =
  (Ptr CSize -> IO [BNReferenceSource]) -> IO [BNReferenceSource]
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CSize -> IO [BNReferenceSource]) -> IO [BNReferenceSource])
-> (Ptr CSize -> IO [BNReferenceSource]) -> IO [BNReferenceSource]
forall a b. (a -> b) -> a -> b
$ \Ptr CSize
countPtr -> do
    arrPtr <- BNBinaryViewPtr
-> Word64 -> Ptr CSize -> CBool -> CSize -> IO BNReferenceSourcePtr
c_BNGetCodeReferences BNBinaryViewPtr
view Word64
addr Ptr CSize
countPtr (Word8 -> CBool
CBool Word8
0) CSize
0
    count' <- fromIntegral <$> peek countPtr
    if arrPtr == nullPtr || count' == 0
      then pure []
      else do
        headPtr <- peekArray count' (castPtr arrPtr :: Ptr BNReferenceSource)
        c_BNFreeCodeReferences arrPtr (fromIntegral count')
        pure headPtr