Patch for shared libraries support on FreeBSD
authorIan Lynagh <igloo@earth.li>
Wed, 6 Jan 2010 18:53:21 +0000 (18:53 +0000)
committerIan Lynagh <igloo@earth.li>
Wed, 6 Jan 2010 18:53:21 +0000 (18:53 +0000)
From Maxime Henrion <mhenrion@gmail.com>

compiler/HsVersions.h
compiler/cmm/CLabel.hs
compiler/main/DriverPipeline.hs
compiler/nativeGen/NCG.h
compiler/nativeGen/PIC.hs
compiler/nativeGen/Platform.hs
compiler/nativeGen/X86/Ppr.hs
libffi/ghc.mk
mk/config.mk.in

index 748b031..8359ad1 100644 (file)
@@ -16,6 +16,11 @@ you will screw up the layout where they are used in case expressions!
 /* Pull in all the platform defines for this build (foo_TARGET_ARCH etc.) */
 #include "ghc_boot_platform.h"
 
+/* This macro indicates that the target OS supports ELF-like shared libraries */
+#if linux_TARGET_OS || freebsd_TARGET_OS
+#define elf_OBJ_FORMAT 1
+#endif
+
 /* Pull in the autoconf defines (HAVE_FOO), but don't include
  * ghcconfig.h, because that will include ghcplatform.h which has the
  * wrong platform settings for the compiler (it has the platform
index d7f7724..3ceb982 100644 (file)
@@ -1101,7 +1101,7 @@ pprDynamicLinkerAsmLabel SymbolPtr lbl
 pprDynamicLinkerAsmLabel _ _
   = panic "pprDynamicLinkerAsmLabel"
 
-#elif powerpc_TARGET_ARCH && linux_TARGET_OS
+#elif powerpc_TARGET_ARCH && elf_OBJ_FORMAT
 pprDynamicLinkerAsmLabel CodeStub lbl
   = pprCLabel lbl <> text "@plt"
 pprDynamicLinkerAsmLabel SymbolPtr lbl
@@ -1109,7 +1109,7 @@ pprDynamicLinkerAsmLabel SymbolPtr lbl
 pprDynamicLinkerAsmLabel _ _
   = panic "pprDynamicLinkerAsmLabel"
 
-#elif x86_64_TARGET_ARCH && linux_TARGET_OS
+#elif x86_64_TARGET_ARCH && elf_OBJ_FORMAT
 pprDynamicLinkerAsmLabel CodeStub lbl
   = pprCLabel lbl <> text "@plt"
 pprDynamicLinkerAsmLabel GotSymbolPtr lbl
@@ -1119,7 +1119,7 @@ pprDynamicLinkerAsmLabel GotSymbolOffset lbl
 pprDynamicLinkerAsmLabel SymbolPtr lbl
   = text ".LC_" <> pprCLabel lbl
 
-#elif linux_TARGET_OS
+#elif elf_OBJ_FORMAT
 pprDynamicLinkerAsmLabel CodeStub lbl
   = pprCLabel lbl <> text "@plt"
 pprDynamicLinkerAsmLabel SymbolPtr lbl
index f8073c9..5ac10ec 100644 (file)
@@ -1374,7 +1374,7 @@ linkBinary dflags o_files dep_packages = do
 
     pkg_lib_paths <- getPackageLibraryPath dflags dep_packages
     let pkg_lib_path_opts = concat (map get_pkg_lib_path_opts pkg_lib_paths)
-#ifdef linux_TARGET_OS
+#ifdef elf_OBJ_FORMAT
         get_pkg_lib_path_opts l | (dynLibLoader dflags)==SystemDependent && not opt_Static = ["-L" ++ l, "-Wl,-rpath", "-Wl," ++ l]
                                 | otherwise = ["-L" ++ l]
 #else
@@ -1573,7 +1573,7 @@ linkDynLib dflags o_files dep_packages = do
 #endif
     let pkg_lib_paths = collectLibraryPaths pkgs_no_rts
     let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths
-#ifdef linux_TARGET_OS
+#ifdef elf_OBJ_FORMAT
         get_pkg_lib_path_opts l | (dynLibLoader dflags)==SystemDependent && not opt_Static = ["-L" ++ l, "-Wl,-rpath", "-Wl," ++ l]
                                 | otherwise = ["-L" ++ l]
 #else
index 3a7bfcd..5921518 100644 (file)
 #else
 # define IF_OS_darwin(x,y) y
 #endif
+-- - - - - - - - - - - - - - - - - - - - - - 
+#if freebsd_TARGET_OS
+# define IF_OS_freebsd(x,y) x
+#else
+# define IF_OS_freebsd(x,y) y
+#endif
 ---------------------------------------------
 #endif
index b497480..5bfe90b 100644 (file)
@@ -293,37 +293,38 @@ howToAccessLabel dflags arch OSDarwin _ lbl
 -- from position independent code. It is also required from the main program
 -- when dynamic libraries containing Haskell code are used.
 
-howToAccessLabel _ ArchPPC_64 OSLinux kind _
-
-       -- ELF PPC64 (powerpc64-linux), AIX, MacOS 9, BeOS/PPC
-       | DataReference <- kind
-       = AccessViaSymbolPtr
-       
-       -- actually, .label instead of label
-       | otherwise
-       = AccessDirectly 
-
-howToAccessLabel _ _ OSLinux _ _
+howToAccessLabel _ ArchPPC_64 os kind _
+       | osElfTarget os
+       = if kind == DataReference
+           -- ELF PPC64 (powerpc64-linux), AIX, MacOS 9, BeOS/PPC
+            then AccessViaSymbolPtr
+           -- actually, .label instead of label
+            else AccessDirectly
+
+howToAccessLabel _ _ os _ _
        -- no PIC -> the dynamic linker does everything for us;
        --           if we don't dynamically link to Haskell code,
        --           it actually manages to do so without messing thins up.
-       | not opt_PIC && opt_Static 
+       | osElfTarget os
+       , not opt_PIC && opt_Static 
        = AccessDirectly
 
-howToAccessLabel dflags arch OSLinux DataReference lbl
-       -- A dynamic label needs to be accessed via a symbol pointer.
-       | labelDynamic (thisPackage dflags) lbl 
-       = AccessViaSymbolPtr
-
-       -- For PowerPC32 -fPIC, we have to access even static data
-       -- via a symbol pointer (see below for an explanation why
-       -- PowerPC32 Linux is especially broken).
-       | arch == ArchPPC
-       , opt_PIC
-       = AccessViaSymbolPtr
+howToAccessLabel dflags arch os DataReference lbl
+       | osElfTarget os
+       = case () of
+           -- A dynamic label needs to be accessed via a symbol pointer.
+          _ | labelDynamic (thisPackage dflags) lbl 
+           -> AccessViaSymbolPtr
+
+           -- For PowerPC32 -fPIC, we have to access even static data
+           -- via a symbol pointer (see below for an explanation why
+           -- PowerPC32 Linux is especially broken).
+           | arch == ArchPPC
+           , opt_PIC
+           -> AccessViaSymbolPtr
        
-       | otherwise 
-       = AccessDirectly
+           | otherwise 
+           -> AccessDirectly
 
 
        -- In most cases, we have to avoid symbol stubs on ELF, for the following reasons:
@@ -338,20 +339,21 @@ howToAccessLabel dflags arch OSLinux DataReference lbl
        -- (AccessDirectly, because we get an implicit symbol stub)
        -- and calling functions from PIC code on non-i386 platforms (via a symbol stub) 
 
-howToAccessLabel dflags arch OSLinux CallReference lbl
-       | labelDynamic (thisPackage dflags) lbl && not opt_PIC
+howToAccessLabel dflags arch os CallReference lbl
+       | osElfTarget os
+       , labelDynamic (thisPackage dflags) lbl && not opt_PIC
        = AccessDirectly
 
-       | arch /= ArchX86
+       | osElfTarget os
+       , arch /= ArchX86
        , labelDynamic (thisPackage dflags) lbl && opt_PIC
        = AccessViaStub
 
-howToAccessLabel dflags _ OSLinux _ lbl
-       | labelDynamic (thisPackage dflags) lbl 
-       = AccessViaSymbolPtr
-
-       | otherwise 
-       = AccessDirectly
+howToAccessLabel dflags _ os _ lbl
+       | osElfTarget os
+       = if labelDynamic (thisPackage dflags) lbl 
+           then AccessViaSymbolPtr
+           else AccessDirectly
 
 -- all other platforms
 howToAccessLabel _ _ _ _ _
@@ -387,7 +389,8 @@ picRelative arch OSDarwin lbl
 -- We have made sure that *everything* is accessed indirectly, so this
 -- is only used for offsets from the GOT to symbol pointers inside the
 -- GOT.
-picRelative ArchPPC OSLinux lbl
+picRelative ArchPPC os lbl
+       | osElfTarget os
        = CmmLabelDiffOff lbl gotLabel 0
 
 
@@ -399,7 +402,7 @@ picRelative ArchPPC OSLinux lbl
 -- and a GotSymbolOffset label for other things.
 -- For reasons of tradition, the symbol offset label is written as a plain label.
 picRelative arch os lbl
-       | os == OSLinux || (os == OSDarwin && arch == ArchX86_64)
+       | osElfTarget os || (os == OSDarwin && arch == ArchX86_64)
        = let   result
                        | Just (SymbolPtr, lbl') <- dynamicLinkerLabelInfo lbl
                        = CmmLabel $ mkDynamicLinkerLabel GotSymbolPtr lbl'
@@ -436,12 +439,12 @@ needImportedSymbols arch os
        = True
        
        -- PowerPC Linux: -fPIC or -dynamic
-       | os    == OSLinux
+       | osElfTarget os
        , arch  == ArchPPC
        = opt_PIC || not opt_Static
 
        -- i386 (and others?): -dynamic but not -fPIC
-       | os    == OSLinux
+       | osElfTarget os
        , arch  /= ArchPPC_64
        = not opt_Static && not opt_PIC
 
@@ -482,12 +485,14 @@ pprGotDeclaration _ OSDarwin
 -- The .LCTOC1 label is defined to point 32768 bytes into the table,
 -- to make the most of the PPC's 16-bit displacements.
 -- Only needed for PIC.
-pprGotDeclaration arch OSLinux
-       | arch  /= ArchPPC_64
+pprGotDeclaration arch os
+       | osElfTarget os
+       , arch  /= ArchPPC_64
        , not opt_PIC 
        = Pretty.empty
 
-       | arch  /= ArchPPC_64
+       | osElfTarget os
+       , arch  /= ArchPPC_64
        = vcat [
                ptext (sLit ".section \".got2\",\"aw\""),
                ptext (sLit ".LCTOC1 = .+32768") ]
@@ -645,23 +650,26 @@ pprImportedSymbol _ OSDarwin _
 -- the NCG will keep track of all DynamicLinkerLabels it uses
 -- and output each of them using pprImportedSymbol.
 
-pprImportedSymbol ArchPPC_64 OSLinux _
+pprImportedSymbol ArchPPC_64 os _
+       | osElfTarget os
        = empty
 
-pprImportedSymbol _ OSLinux importedLbl
-       | Just (SymbolPtr, lbl) <- dynamicLinkerLabelInfo importedLbl
-       = let   symbolSize = case wordWidth of
-                    W32 -> sLit "\t.long"
-                    W64 -> sLit "\t.quad"
-                    _ -> panic "Unknown wordRep in pprImportedSymbol"
+pprImportedSymbol _ os importedLbl
+       | osElfTarget os
+       = case dynamicLinkerLabelInfo importedLbl of
+           Just (SymbolPtr, lbl)
+             -> let symbolSize = case wordWidth of
+                        W32 -> sLit "\t.long"
+                        W64 -> sLit "\t.quad"
+                        _ -> panic "Unknown wordRep in pprImportedSymbol"
 
-         in vcat [
-               ptext (sLit ".section \".got2\", \"aw\""),
-               ptext (sLit ".LC_") <> pprCLabel_asm lbl <> char ':',
-               ptext symbolSize <+> pprCLabel_asm lbl ]
+                in vcat [
+                     ptext (sLit ".section \".got2\", \"aw\""),
+                     ptext (sLit ".LC_") <> pprCLabel_asm lbl <> char ':',
+                     ptext symbolSize <+> pprCLabel_asm lbl ]
 
-       -- PLT code stubs are generated automatically by the dynamic linker.
-       | otherwise = empty
+           -- PLT code stubs are generated automatically by the dynamic linker.
+           _ -> empty
 
 pprImportedSymbol _ _ _
        = panic "PIC.pprImportedSymbol: no match"
@@ -704,8 +712,9 @@ initializePicBase_ppc
        -> [NatCmmTop PPC.Instr] 
        -> NatM [NatCmmTop PPC.Instr]
 
-initializePicBase_ppc ArchPPC OSLinux picReg
+initializePicBase_ppc ArchPPC os picReg
     (CmmProc info lab params (ListGraph blocks) : statics)
+    | osElfTarget os
     = do
         gotOffLabel <- getNewLabelNat
         tmp <- getNewRegNat $ intSize wordWidth
@@ -756,8 +765,9 @@ initializePicBase_x86
        -> [NatCmmTop X86.Instr] 
        -> NatM [NatCmmTop X86.Instr]
 
-initializePicBase_x86 ArchX86 OSLinux picReg 
+initializePicBase_x86 ArchX86 os picReg 
        (CmmProc info lab params (ListGraph blocks) : statics)
+    | osElfTarget os
     = return (CmmProc info lab params (ListGraph (b':tail blocks)) : statics)
     where BasicBlock bID insns = head blocks
           b' = BasicBlock bID (X86.FETCHGOT picReg : insns)
index 8b01f5c..afbf0b2 100644 (file)
@@ -9,7 +9,8 @@ module Platform (
        Arch(..),
        OS(..),
 
-       defaultTargetPlatform
+       defaultTargetPlatform,
+       osElfTarget
 )
 
 where
@@ -47,9 +48,16 @@ data OS
        | OSDarwin
        | OSSolaris
        | OSMinGW32
+       | OSFreeBSD
        deriving (Show, Eq)
 
 
+-- | This predicates tells us whether the OS supports ELF-like shared libraries.
+osElfTarget :: OS -> Bool
+osElfTarget OSLinux   = True
+osElfTarget OSFreeBSD = True
+osElfTarget _         = False
+
 -- | This is the target platform as far as the #ifdefs are concerned.
 --     These are set in includes/ghcplatform.h by the autoconf scripts
 defaultTargetPlatform :: Platform
@@ -86,6 +94,8 @@ defaultTargetOS       = OSDarwin
 defaultTargetOS        = OSSolaris
 #elif mingw32_TARGET_OS
 defaultTargetOS        = OSMinGW32
+#elif freebsd_TARGET_OS
+defaultTargetOS        = OSFreeBSD
 #else
 defaultTargetOS        = OSUnknown
 #endif
index c0f4657..89bbb5d 100644 (file)
@@ -115,7 +115,7 @@ pprGloblDecl lbl
                pprCLabel_asm lbl
 
 pprTypeAndSizeDecl :: CLabel -> Doc
-#if linux_TARGET_OS
+#if elf_OBJ_FORMAT
 pprTypeAndSizeDecl lbl
   | not (externallyVisibleCLabel lbl) = empty
   | otherwise = ptext (sLit ".type ") <>
index 92e11dd..1216a32 100644 (file)
@@ -88,8 +88,7 @@ ifeq "$(darwin_TARGET_OS)" "1"
 libffi_DYNAMIC_LIBS = libffi/libffi$(soext) libffi/libffi.5$(soext) libffi/libffi.5.0.9$(soext)
 else
 libffi_DYNAMIC_LIBS = libffi/dist-install/build/libffi.so \
-                      libffi/dist-install/build/libffi.so.5 \
-                      libffi/dist-install/build/libffi.so.5.0.9
+                      libffi/dist-install/build/libffi.so.5
 endif
 endif
 
index 01bbc75..ea3c1ff 100644 (file)
@@ -102,7 +102,7 @@ GhcDebugged=NO
 GhcLibProfiled=$(if $(filter p,$(GhcLibWays)),YES,NO)
 
 # Do we support shared libs?
-PlatformSupportsSharedLibs = $(if $(filter $(TARGETPLATFORM),i386-unknown-linux x86_64-unknown-linux),YES,NO)
+PlatformSupportsSharedLibs = $(if $(filter $(TARGETPLATFORM),i386-unknown-linux x86_64-unknown-linux i386-unknown-freebsd amd64-unknown-freebsd),YES,NO)
 
 # ToDo later:
 # BuildStaticLibs=@BuildStaticLibs@