summaryrefslogtreecommitdiff
path: root/testsuite/tests/rts/linker/T20494.hs
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/tests/rts/linker/T20494.hs')
-rw-r--r--testsuite/tests/rts/linker/T20494.hs55
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"