module LLVM.Internal.Linking
  ( loadLibraryPermanently
  , getSymbolAddressInProcess
  )where

import LLVM.Prelude

import qualified Data.ByteString as BS
import Foreign.C.String
import Foreign.Ptr
import LLVM.Internal.Coding
import qualified LLVM.Internal.FFI.DynamicLibrary as DL
import qualified LLVM.Internal.FFI.RTDyldMemoryManager as Dyld
import LLVM.Internal.OrcJIT

-- | Get the address of the given symbol in
--   the current process' address space.
getSymbolAddressInProcess
  :: MangledSymbol -> IO WordPtr
getSymbolAddressInProcess :: MangledSymbol -> IO WordPtr
getSymbolAddressInProcess (MangledSymbol sym :: ByteString
sym)
  = Word64 -> WordPtr
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> WordPtr) -> IO Word64 -> IO WordPtr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> (CString -> IO Word64) -> IO Word64
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
sym CString -> IO Word64
Dyld.getSymbolAddressInProcess

-- | Loads the given dynamic library permanently. If 'Nothing'
--   is given, this will make the symbols from the current
--   process available.
loadLibraryPermanently
  :: Maybe FilePath
  -> IO Bool
loadLibraryPermanently :: Maybe FilePath -> IO Bool
loadLibraryPermanently (Just fp :: FilePath
fp) = LLVMBool -> IO Bool
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (LLVMBool -> IO Bool) -> IO LLVMBool -> IO Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> (CString -> IO LLVMBool) -> IO LLVMBool
forall a. FilePath -> (CString -> IO a) -> IO a
withCString FilePath
fp CString -> IO LLVMBool
DL.loadLibraryPermanently
loadLibraryPermanently Nothing = LLVMBool -> IO Bool
forall (d :: * -> *) h c. DecodeM d h c => c -> d h
decodeM (LLVMBool -> IO Bool) -> IO LLVMBool -> IO Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< CString -> IO LLVMBool
DL.loadLibraryPermanently CString
forall a. Ptr a
nullPtr