summaryrefslogtreecommitdiff
path: root/compiler/main/DriverPipeline.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/main/DriverPipeline.hs')
-rw-r--r--compiler/main/DriverPipeline.hs106
1 files changed, 61 insertions, 45 deletions
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index df6e7fd163..47706798f7 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -326,8 +326,7 @@ link' dflags batch_attempt_linking hpt
return Succeeded
else do
- compilationProgressMsg dflags $ showSDoc $
- (ptext (sLit "Linking") <+> text exe_file <+> text "...")
+ compilationProgressMsg dflags ("Linking " ++ exe_file ++ " ...")
-- Don't showPass in Batch mode; doLink will do that for us.
let link = case ghcLink dflags of
@@ -774,7 +773,7 @@ runPhase (Cpp sf) input_fn dflags0
(dflags1, unhandled_flags, warns)
<- io $ parseDynamicFilePragma dflags0 src_opts
setDynFlags dflags1
- io $ checkProcessArgsResult unhandled_flags
+ io $ checkProcessArgsResult dflags1 unhandled_flags
if not (xopt Opt_Cpp dflags1) then do
-- we have to be careful to emit warnings only once.
@@ -791,7 +790,7 @@ runPhase (Cpp sf) input_fn dflags0
src_opts <- io $ getOptionsFromFile dflags0 output_fn
(dflags2, unhandled_flags, warns)
<- io $ parseDynamicFilePragma dflags0 src_opts
- io $ checkProcessArgsResult unhandled_flags
+ io $ checkProcessArgsResult dflags2 unhandled_flags
unless (dopt Opt_Pp dflags2) $ io $ handleFlagWarnings dflags2 warns
-- the HsPp pass below will emit warnings
@@ -826,7 +825,7 @@ runPhase (HsPp sf) input_fn dflags
(dflags1, unhandled_flags, warns)
<- io $ parseDynamicFilePragma dflags src_opts
setDynFlags dflags1
- io $ checkProcessArgsResult unhandled_flags
+ io $ checkProcessArgsResult dflags1 unhandled_flags
io $ handleFlagWarnings dflags1 warns
return (Hsc sf, output_fn)
@@ -1176,14 +1175,17 @@ runPhase As input_fn dflags
= do
llvmVer <- io $ figureLlvmVersion dflags
return $ case llvmVer of
- Just n | n >= 30 -> SysTools.runClang
- _ -> SysTools.runAs
+ -- using cGccLinkerOpts here but not clear if
+ -- opt_c isn't a better choice
+ Just n | n >= 30 ->
+ (SysTools.runClang, cGccLinkerOpts)
+
+ _ -> (SysTools.runAs, getOpts dflags opt_a)
| otherwise
- = return SysTools.runAs
+ = return (SysTools.runAs, getOpts dflags opt_a)
- as_prog <- whichAsProg
- let as_opts = getOpts dflags opt_a
+ (as_prog, as_opts) <- whichAsProg
let cmdline_include_paths = includePaths dflags
next_phase <- maybeMergeStub
@@ -1191,7 +1193,7 @@ runPhase As input_fn dflags
-- we create directories for the object file, because it
-- might be a hierarchical module.
- io $ createDirectoryHierarchy (takeDirectory output_fn)
+ io $ createDirectoryIfMissing True (takeDirectory output_fn)
io $ as_prog dflags
(map SysTools.Option as_opts
@@ -1230,7 +1232,7 @@ runPhase SplitAs _input_fn dflags
osuf = objectSuf dflags
split_odir = base_o ++ "_" ++ osuf ++ "_split"
- io $ createDirectoryHierarchy split_odir
+ io $ createDirectoryIfMissing True split_odir
-- remove M_split/ *.o, because we're going to archive M_split/ *.o
-- later and we don't want to pick up any old objects.
@@ -1369,7 +1371,8 @@ runPhase LlvmLlc input_fn dflags
SysTools.Option "-o", SysTools.FileOption "" output_fn]
++ map SysTools.Option lc_opts
++ [SysTools.Option tbaa]
- ++ map SysTools.Option fpOpts)
+ ++ map SysTools.Option fpOpts
+ ++ map SysTools.Option abiOpts)
return (next_phase, output_fn)
where
@@ -1381,12 +1384,19 @@ runPhase LlvmLlc input_fn dflags
-- while compiling GHC source code. It's probably due to fact that it
-- does not enable VFP by default. Let's do this manually here
fpOpts = case platformArch (targetPlatform dflags) of
- ArchARM ARMv7 ext -> if (elem VFPv3 ext)
+ ArchARM ARMv7 ext _ -> if (elem VFPv3 ext)
then ["-mattr=+v7,+vfp3"]
else if (elem VFPv3D16 ext)
then ["-mattr=+v7,+vfp3,+d16"]
else []
_ -> []
+ -- On Ubuntu/Debian with ARM hard float ABI, LLVM's llc still
+ -- compiles into soft-float ABI. We need to explicitly set abi
+ -- to hard
+ abiOpts = case platformArch (targetPlatform dflags) of
+ ArchARM ARMv7 _ HARD -> ["-float-abi=hard"]
+ ArchARM ARMv7 _ _ -> []
+ _ -> []
-----------------------------------------------------------------------------
-- LlvmMangle phase
@@ -1453,9 +1463,9 @@ runPhase_MoveBinary dflags input_fn
return True
| otherwise = return True
-mkExtraCObj :: DynFlags -> String -> IO FilePath
-mkExtraCObj dflags xs
- = do cFile <- newTempName dflags "c"
+mkExtraObj :: DynFlags -> Suffix -> String -> IO FilePath
+mkExtraObj dflags extn xs
+ = do cFile <- newTempName dflags extn
oFile <- newTempName dflags "o"
writeFile cFile xs
let rtsDetails = getPackageDetails (pkgState dflags) rtsPackageId
@@ -1474,23 +1484,19 @@ mkExtraCObj dflags xs
-- so now we generate and compile a main() stub as part of every
-- binary and pass the -rtsopts setting directly to the RTS (#5373)
--
-mkExtraObjToLinkIntoBinary :: DynFlags -> [PackageId] -> IO FilePath
-mkExtraObjToLinkIntoBinary dflags dep_packages = do
- link_info <- getLinkInfo dflags dep_packages
-
+mkExtraObjToLinkIntoBinary :: DynFlags -> IO FilePath
+mkExtraObjToLinkIntoBinary dflags = do
let have_rts_opts_flags =
isJust (rtsOpts dflags) || case rtsOptsEnabled dflags of
RtsOptsSafeOnly -> False
_ -> True
when (dopt Opt_NoHsMain dflags && have_rts_opts_flags) $ do
- hPutStrLn stderr $ "Warning: -rtsopts and -with-rtsopts have no effect with -no-hs-main.\n" ++
- " Call hs_init_ghc() from your main() function to set these options."
+ log_action dflags dflags SevInfo noSrcSpan defaultUserStyle
+ (text "Warning: -rtsopts and -with-rtsopts have no effect with -no-hs-main." $$
+ text " Call hs_init_ghc() from your main() function to set these options.")
- mkExtraCObj dflags (showSDoc (vcat [main,
- link_opts link_info]
- <> char '\n')) -- final newline, to
- -- keep gcc happy
+ mkExtraObj dflags "c" (showSDoc dflags main)
where
main
@@ -1508,31 +1514,40 @@ mkExtraObjToLinkIntoBinary dflags dep_packages = do
Just opts -> ptext (sLit " __conf.rts_opts= ") <>
text (show opts) <> semi,
ptext (sLit " return hs_main(argc, argv, &ZCMain_main_closure,__conf);"),
- char '}'
+ char '}',
+ char '\n' -- final newline, to keep gcc happy
]
- link_opts info
- | not (platformSupportsSavingLinkOpts (platformOS (targetPlatform dflags)))
- = empty
- | otherwise = hcat [
- text "__asm__(\"\\t.section ", text ghcLinkInfoSectionName,
- text ",\\\"\\\",",
- text elfSectionNote,
- text "\\n",
+-- Write out the link info section into a new assembly file. Previously
+-- this was included as inline assembly in the main.c file but this
+-- is pretty fragile. gas gets upset trying to calculate relative offsets
+-- that span the .note section (notably .text) when debug info is present
+mkNoteObjsToLinkIntoBinary :: DynFlags -> [PackageId] -> IO [FilePath]
+mkNoteObjsToLinkIntoBinary dflags dep_packages = do
+ link_info <- getLinkInfo dflags dep_packages
+
+ if (platformSupportsSavingLinkOpts (platformOS (targetPlatform dflags)))
+ then fmap (:[]) $ mkExtraObj dflags "s" (showSDoc dflags (link_opts link_info))
+ else return []
+
+ where
+ link_opts info = hcat [
+ text "\t.section ", text ghcLinkInfoSectionName,
+ text ",\"\",",
+ text elfSectionNote,
+ text "\n",
- text "\\t.ascii \\\"", info', text "\\\"\\n\");" ]
+ text "\t.ascii \"", info', text "\"\n" ]
where
- -- we need to escape twice: once because we're inside a C string,
- -- and again because we're inside an asm string.
- info' = text $ (escape.escape) info
+ info' = text $ escape info
escape :: String -> String
escape = concatMap (charToC.fromIntegral.ord)
elfSectionNote :: String
elfSectionNote = case platformArch (targetPlatform dflags) of
- ArchARM _ _ -> "%note"
- _ -> "@note"
+ ArchARM _ _ _ -> "%note"
+ _ -> "@note"
-- The "link info" is a string representing the parameters of the
-- link. We save this information in the binary, and the next time we
@@ -1661,7 +1676,8 @@ linkBinary dflags o_files dep_packages = do
let lib_paths = libraryPaths dflags
let lib_path_opts = map ("-L"++) lib_paths
- extraLinkObj <- mkExtraObjToLinkIntoBinary dflags dep_packages
+ extraLinkObj <- mkExtraObjToLinkIntoBinary dflags
+ noteLinkObjs <- mkNoteObjsToLinkIntoBinary dflags dep_packages
pkg_link_opts <- getPackageLinkOpts dflags dep_packages
@@ -1778,7 +1794,7 @@ linkBinary dflags o_files dep_packages = do
++ framework_path_opts
++ framework_opts
++ pkg_lib_path_opts
- ++ [extraLinkObj]
+ ++ extraLinkObj:noteLinkObjs
++ pkg_link_opts
++ pkg_framework_path_opts
++ pkg_framework_opts
@@ -2132,6 +2148,6 @@ hscPostBackendPhase dflags _ hsc_lang =
touchObjectFile :: DynFlags -> FilePath -> IO ()
touchObjectFile dflags path = do
- createDirectoryHierarchy $ takeDirectory path
+ createDirectoryIfMissing True $ takeDirectory path
SysTools.touch dflags "Touching object file" path