From 0af418beb1aadcae1df036240151556895d00321 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Wed, 6 Jan 2010 18:53:21 +0000 Subject: [PATCH] Patch for shared libraries support on FreeBSD From Maxime Henrion --- compiler/HsVersions.h | 5 ++ compiler/cmm/CLabel.hs | 6 +- compiler/main/DriverPipeline.hs | 4 +- compiler/nativeGen/NCG.h | 6 ++ compiler/nativeGen/PIC.hs | 122 +++++++++++++++++++++------------------ compiler/nativeGen/Platform.hs | 12 +++- compiler/nativeGen/X86/Ppr.hs | 2 +- libffi/ghc.mk | 3 +- mk/config.mk.in | 2 +- 9 files changed, 96 insertions(+), 66 deletions(-) diff --git a/compiler/HsVersions.h b/compiler/HsVersions.h index 748b031..8359ad1 100644 --- a/compiler/HsVersions.h +++ b/compiler/HsVersions.h @@ -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 diff --git a/compiler/cmm/CLabel.hs b/compiler/cmm/CLabel.hs index d7f7724..3ceb982 100644 --- a/compiler/cmm/CLabel.hs +++ b/compiler/cmm/CLabel.hs @@ -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 diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs index f8073c9..5ac10ec 100644 --- a/compiler/main/DriverPipeline.hs +++ b/compiler/main/DriverPipeline.hs @@ -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 diff --git a/compiler/nativeGen/NCG.h b/compiler/nativeGen/NCG.h index 3a7bfcd..5921518 100644 --- a/compiler/nativeGen/NCG.h +++ b/compiler/nativeGen/NCG.h @@ -110,5 +110,11 @@ #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 diff --git a/compiler/nativeGen/PIC.hs b/compiler/nativeGen/PIC.hs index b497480..5bfe90b 100644 --- a/compiler/nativeGen/PIC.hs +++ b/compiler/nativeGen/PIC.hs @@ -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) diff --git a/compiler/nativeGen/Platform.hs b/compiler/nativeGen/Platform.hs index 8b01f5c..afbf0b2 100644 --- a/compiler/nativeGen/Platform.hs +++ b/compiler/nativeGen/Platform.hs @@ -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 diff --git a/compiler/nativeGen/X86/Ppr.hs b/compiler/nativeGen/X86/Ppr.hs index c0f4657..89bbb5d 100644 --- a/compiler/nativeGen/X86/Ppr.hs +++ b/compiler/nativeGen/X86/Ppr.hs @@ -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 ") <> diff --git a/libffi/ghc.mk b/libffi/ghc.mk index 92e11dd..1216a32 100644 --- a/libffi/ghc.mk +++ b/libffi/ghc.mk @@ -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 diff --git a/mk/config.mk.in b/mk/config.mk.in index 01bbc75..ea3c1ff 100644 --- a/mk/config.mk.in +++ b/mk/config.mk.in @@ -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@ -- 1.7.10.4