summaryrefslogtreecommitdiff
path: root/compiler/GHC/Driver
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Driver')
-rw-r--r--compiler/GHC/Driver/Pipeline.hs61
-rw-r--r--compiler/GHC/Driver/Session.hs10
2 files changed, 36 insertions, 35 deletions
diff --git a/compiler/GHC/Driver/Pipeline.hs b/compiler/GHC/Driver/Pipeline.hs
index 36010a76af..e422624fa6 100644
--- a/compiler/GHC/Driver/Pipeline.hs
+++ b/compiler/GHC/Driver/Pipeline.hs
@@ -2133,6 +2133,23 @@ We must enable bigobj output in a few places:
Unfortunately the big object format is not supported on 32-bit targets so
none of this can be used in that case.
+
+
+Note [Merging object files for GHCi]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GHCi can usually loads standard linkable object files using GHC's linker
+implementation. However, most users build their projects with -split-sections,
+meaning that such object files can have an extremely high number of sections.
+As the linker must map each of these sections individually, loading such object
+files is very inefficient.
+
+To avoid this inefficiency, we use the linker's `-r` flag and a linker script
+to produce a merged relocatable object file. This file will contain a singe
+text section section and can consequently be mapped far more efficiently. As
+gcc tends to do unpredictable things to our linker command line, we opt to
+invoke ld directly in this case, in contrast to our usual strategy of linking
+via gcc.
+
-}
joinObjectFiles :: DynFlags -> [FilePath] -> FilePath -> IO ()
@@ -2140,34 +2157,13 @@ joinObjectFiles dflags o_files output_fn = do
let toolSettings' = toolSettings dflags
ldIsGnuLd = toolSettings_ldIsGnuLd toolSettings'
osInfo = platformOS (targetPlatform dflags)
- ld_r args cc = GHC.SysTools.runLink dflags ([
- GHC.SysTools.Option "-nostdlib",
- GHC.SysTools.Option "-Wl,-r"
- ]
- -- See Note [No PIE while linking] in GHC.Driver.Session
- ++ (if toolSettings_ccSupportsNoPie toolSettings'
- then [GHC.SysTools.Option "-no-pie"]
- else [])
-
- ++ (if any (cc ==) [Clang, AppleClang, AppleClang51]
- then []
- else [GHC.SysTools.Option "-nodefaultlibs"])
- ++ (if osInfo == OSFreeBSD
- then [GHC.SysTools.Option "-L/usr/lib"]
- else [])
- -- gcc on sparc sets -Wl,--relax implicitly, but
- -- -r and --relax are incompatible for ld, so
- -- disable --relax explicitly.
- ++ (if platformArch (targetPlatform dflags)
- `elem` [ArchSPARC, ArchSPARC64]
- && ldIsGnuLd
- then [GHC.SysTools.Option "-Wl,-no-relax"]
- else [])
+ ld_r args = GHC.SysTools.runMergeObjects dflags (
-- See Note [Produce big objects on Windows]
- ++ [ GHC.SysTools.Option "-Wl,--oformat,pe-bigobj-x86-64"
- | OSMinGW32 == osInfo
- , not $ target32Bit (targetPlatform dflags)
- ]
+ concat
+ [ [GHC.SysTools.Option "--oformat", GHC.SysTools.Option "pe-bigobj-x86-64"]
+ | OSMinGW32 == osInfo
+ , not $ target32Bit (targetPlatform dflags)
+ ]
++ map GHC.SysTools.Option ld_build_id
++ [ GHC.SysTools.Option "-o",
GHC.SysTools.FileOption "" output_fn ]
@@ -2176,25 +2172,24 @@ joinObjectFiles dflags o_files output_fn = do
-- suppress the generation of the .note.gnu.build-id section,
-- which we don't need and sometimes causes ld to emit a
-- warning:
- ld_build_id | toolSettings_ldSupportsBuildId toolSettings' = ["-Wl,--build-id=none"]
+ ld_build_id | toolSettings_ldSupportsBuildId toolSettings' = ["--build-id=none"]
| otherwise = []
- ccInfo <- getCompilerInfo dflags
if ldIsGnuLd
then do
script <- newTempName dflags TFL_CurrentModule "ldscript"
cwd <- getCurrentDirectory
let o_files_abs = map (\x -> "\"" ++ (cwd </> x) ++ "\"") o_files
writeFile script $ "INPUT(" ++ unwords o_files_abs ++ ")"
- ld_r [GHC.SysTools.FileOption "" script] ccInfo
+ ld_r [GHC.SysTools.FileOption "" script]
else if toolSettings_ldSupportsFilelist toolSettings'
then do
filelist <- newTempName dflags TFL_CurrentModule "filelist"
writeFile filelist $ unlines o_files
- ld_r [GHC.SysTools.Option "-Wl,-filelist",
- GHC.SysTools.FileOption "-Wl," filelist] ccInfo
+ ld_r [GHC.SysTools.Option "-filelist",
+ GHC.SysTools.FileOption "" filelist]
else do
- ld_r (map (GHC.SysTools.FileOption "") o_files) ccInfo
+ ld_r (map (GHC.SysTools.FileOption "") o_files)
-- -----------------------------------------------------------------------------
-- Misc.
diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs
index 01555dff8f..795cbf2256 100644
--- a/compiler/GHC/Driver/Session.hs
+++ b/compiler/GHC/Driver/Session.hs
@@ -102,6 +102,7 @@ module GHC.Driver.Session (
sPgm_c,
sPgm_a,
sPgm_l,
+ sPgm_lm,
sPgm_dll,
sPgm_T,
sPgm_windres,
@@ -120,6 +121,7 @@ module GHC.Driver.Session (
sOpt_cxx,
sOpt_a,
sOpt_l,
+ sOpt_lm,
sOpt_windres,
sOpt_lo,
sOpt_lc,
@@ -142,10 +144,10 @@ module GHC.Driver.Session (
ghcUsagePath, ghciUsagePath, topDir, tmpDir,
versionedAppDir, versionedFilePath,
extraGccViaCFlags, globalPackageDatabasePath,
- pgm_L, pgm_P, pgm_F, pgm_c, pgm_a, pgm_l, pgm_dll, pgm_T,
+ pgm_L, pgm_P, pgm_F, pgm_c, pgm_a, pgm_l, pgm_lm, pgm_dll, pgm_T,
pgm_windres, pgm_libtool, pgm_ar, pgm_ranlib, pgm_lo, pgm_lc,
pgm_lcc, pgm_i,
- opt_L, opt_P, opt_F, opt_c, opt_cxx, opt_a, opt_l, opt_i,
+ opt_L, opt_P, opt_F, opt_c, opt_cxx, opt_a, opt_l, opt_lm, opt_i,
opt_P_signature,
opt_windres, opt_lo, opt_lc, opt_lcc,
@@ -940,6 +942,8 @@ pgm_a :: DynFlags -> (String,[Option])
pgm_a dflags = toolSettings_pgm_a $ toolSettings dflags
pgm_l :: DynFlags -> (String,[Option])
pgm_l dflags = toolSettings_pgm_l $ toolSettings dflags
+pgm_lm :: DynFlags -> (String,[Option])
+pgm_lm dflags = toolSettings_pgm_lm $ toolSettings dflags
pgm_dll :: DynFlags -> (String,[Option])
pgm_dll dflags = toolSettings_pgm_dll $ toolSettings dflags
pgm_T :: DynFlags -> String
@@ -986,6 +990,8 @@ opt_a dflags= toolSettings_opt_a $ toolSettings dflags
opt_l :: DynFlags -> [String]
opt_l dflags = concatMap (wayOptl (targetPlatform dflags)) (ways dflags)
++ toolSettings_opt_l (toolSettings dflags)
+opt_lm :: DynFlags -> [String]
+opt_lm dflags= toolSettings_opt_lm $ toolSettings dflags
opt_windres :: DynFlags -> [String]
opt_windres dflags= toolSettings_opt_windres $ toolSettings dflags
opt_lcc :: DynFlags -> [String]