diff options
Diffstat (limited to 'testsuite/tests/rts/linker/T20494.hs')
| -rw-r--r-- | testsuite/tests/rts/linker/T20494.hs | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/testsuite/tests/rts/linker/T20494.hs b/testsuite/tests/rts/linker/T20494.hs new file mode 100644 index 0000000000..590a9aa258 --- /dev/null +++ b/testsuite/tests/rts/linker/T20494.hs @@ -0,0 +1,55 @@ +{-# LANGUAGE ForeignFunctionInterface, CPP #-} +import Foreign.C.String +import Control.Monad +import System.Environment +import System.FilePath +import Foreign.Ptr +import System.Mem + +-- Type of paths is different on Windows +#if defined(mingw32_HOST_OS) +type PathString = CWString +withPathString = withCWString +#else +type PathString = CString +withPathString = withCString +#endif + +foreign import ccall "initLinker" + initLinker :: IO () +foreign import ccall "loadObj" + loadObj :: PathString -> IO Int +foreign import ccall "resolveObjs" + resolveObjs :: IO Int +foreign import ccall "lookupSymbol" + lookupSymbol :: CString -> IO (FunPtr a) +foreign import ccall "unloadObj" + unloadObj :: PathString -> IO Int + +type HelloFn = IO () +foreign import ccall "dynamic" + mkHello :: FunPtr HelloFn -> HelloFn + +main :: IO () +main = do + [objPath] <- getArgs + initLinker + + r <- withPathString objPath loadObj + when (r /= 1) $ error "loadObj failed" + + r <- resolveObjs + when (r /= 1) $ error "resolveObj failed" + + ptr <- withCString "hello" lookupSymbol + when (nullFunPtr == ptr) $ error "lookupSymbol failed" + + let hello = mkHello ptr + hello + + withPathString objPath unloadObj + when (r /= 1) $ error "unloadObj failed" + + -- Perform a major GC to ensure that the object can be unloaded. + performMajorGC + putStrLn "done" |
