Implement split-sections support for windows.
authorTamar Christina <tamar@zhox.com>
Sun, 26 Mar 2017 18:05:46 +0000 (19:05 +0100)
committerTamar Christina <tamar@zhox.com>
Fri, 7 Jul 2017 23:02:36 +0000 (00:02 +0100)
Summary:
Initial implementation of split-section on Windows.

This also corrects section namings and uses the platform
convention of `$` instead of `.` to separate sections.

Implementation is based on @awson's patches to binutils.

Binutils requires some extra help when compiling the libraries
for GHCi usage. We drop the `-T` and use implicit scripts to amend
the linker scripts instead of replacing it.

Because of these very large GHCi object files, we need big-obj support,
which will be added by another patch.

Test Plan: ./validate

Reviewers: awson, austin, bgamari

Subscribers: dfeuer, rwbarton, thomie, snowleopard, #ghc_windows_task_force

GHC Trac Issues: #12913

Differential Revision: https://phabricator.haskell.org/D3383

compiler/llvmGen/LlvmCodeGen/Data.hs
compiler/nativeGen/PprBase.hs
docs/users_guide/8.4.1-notes.rst
driver/utils/merge_sections_pe.ld [new file with mode: 0644]
mk/config.mk.in
rules/build-package-way.mk

index adb86d3..39abbd1 100644 (file)
@@ -60,13 +60,19 @@ genLlvmData (sec, Statics lbl xs) = do
 llvmSectionType :: Platform -> SectionType -> FastString
 llvmSectionType p t = case t of
     Text                    -> fsLit ".text"
-    ReadOnlyData            -> fsLit ".rodata"
-    RelocatableReadOnlyData -> fsLit ".data.rel.ro"
-    ReadOnlyData16          -> fsLit ".rodata.cst16"
+    ReadOnlyData            -> case platformOS p of
+                                 OSMinGW32 -> fsLit ".rdata"
+                                 _         -> fsLit ".rodata"
+    RelocatableReadOnlyData -> case platformOS p of
+                                 OSMinGW32 -> fsLit ".rdata$rel.ro"
+                                 _         -> fsLit ".data.rel.ro"
+    ReadOnlyData16          -> case platformOS p of
+                                 OSMinGW32 -> fsLit ".rdata$cst16"
+                                 _         -> fsLit ".rodata.cst16"
     Data                    -> fsLit ".data"
     UninitialisedData       -> fsLit ".bss"
     CString                 -> case platformOS p of
-                                 OSMinGW32 -> fsLit ".rdata"
+                                 OSMinGW32 -> fsLit ".rdata$str"
                                  _         -> fsLit ".rodata.str"
     (OtherSection _)        -> panic "llvmSectionType: unknown section type"
 
@@ -80,7 +86,11 @@ llvmSection (Section t suffix) = do
   then return Nothing
   else do
     lmsuffix <- strCLabel_llvm suffix
-    return (Just (concatFS [llvmSectionType platform t, fsLit ".", lmsuffix]))
+    let result sep = Just (concatFS [llvmSectionType platform t
+                                    , fsLit sep, lmsuffix])
+    case platformOS platform of
+      OSMinGW32 -> return (result "$")
+      _         -> return (result ".")
 
 -- ----------------------------------------------------------------------------
 -- * Generate static data
index e05b2b5..76ac13e 100644 (file)
@@ -93,14 +93,15 @@ doubleToBytes d
 pprSectionHeader :: Platform -> Section -> SDoc
 pprSectionHeader platform (Section t suffix) =
  case platformOS platform of
-   OSAIX    -> pprXcoffSectionHeader t
-   OSDarwin -> pprDarwinSectionHeader t
-   _        -> pprGNUSectionHeader t suffix
+   OSAIX     -> pprXcoffSectionHeader t
+   OSDarwin  -> pprDarwinSectionHeader t
+   OSMinGW32 -> pprGNUSectionHeader (char '$') t suffix
+   _         -> pprGNUSectionHeader (char '.') t suffix
 
-pprGNUSectionHeader :: SectionType -> CLabel -> SDoc
-pprGNUSectionHeader t suffix = sdocWithDynFlags $ \dflags ->
+pprGNUSectionHeader :: SDoc -> SectionType -> CLabel -> SDoc
+pprGNUSectionHeader sep t suffix = sdocWithDynFlags $ \dflags ->
   let splitSections = gopt Opt_SplitSections dflags
-      subsection | splitSections = char '.' <> ppr suffix
+      subsection | splitSections = sep <> ppr suffix
                  | otherwise     = empty
   in  text ".section " <> ptext (header dflags) <> subsection <>
       flags dflags
@@ -108,20 +109,28 @@ pprGNUSectionHeader t suffix = sdocWithDynFlags $ \dflags ->
     header dflags = case t of
       Text -> sLit ".text"
       Data -> sLit ".data"
-      ReadOnlyData -> sLit ".rodata"
-      RelocatableReadOnlyData -> sLit ".data.rel.ro"
+      ReadOnlyData  | OSMinGW32 <- platformOS (targetPlatform dflags)
+                                -> sLit ".rdata"
+                    | otherwise -> sLit ".rodata"
+      RelocatableReadOnlyData | OSMinGW32 <- platformOS (targetPlatform dflags)
+                                -- Concept does not exist on Windows,
+                                -- So map these to R/O data.
+                                          -> sLit ".rdata$rel.ro"
+                              | otherwise -> sLit ".data.rel.ro"
       UninitialisedData -> sLit ".bss"
-      ReadOnlyData16 -> sLit ".rodata.cst16"
+      ReadOnlyData16 | OSMinGW32 <- platformOS (targetPlatform dflags)
+                                 -> sLit ".rdata$cst16"
+                     | otherwise -> sLit ".rodata.cst16"
       CString
         | OSMinGW32 <- platformOS (targetPlatform dflags)
-          -> sLit ".rdata"
+                    -> sLit ".rdata"
         | otherwise -> sLit ".rodata.str"
       OtherSection _ ->
         panic "PprBase.pprGNUSectionHeader: unknown section type"
     flags dflags = case t of
       CString
         | OSMinGW32 <- platformOS (targetPlatform dflags)
-          -> text ",\"dr\""
+                    -> empty
         | otherwise -> text ",\"aMS\",@progbits,1"
       _ -> empty
 
index 7e918f2..c3b41c3 100644 (file)
@@ -76,6 +76,9 @@ Now we generate ::
 
       _ == _ = error ...
 
+- `-fsplit-sections` is now supported on x86_64 Windows and is on by default.
+  See :ghc-ticket:`12913`.
+
 - Configure on Windows now supports ``--enable-distro-toolchain`` which can be
   used to build a GHC using compilers on your ``PATH`` instead of using the
   bundled bindist. See :ghc-ticket:`13792`
diff --git a/driver/utils/merge_sections_pe.ld b/driver/utils/merge_sections_pe.ld
new file mode 100644 (file)
index 0000000..c9eed87
--- /dev/null
@@ -0,0 +1,26 @@
+/* Linker script to undo -split-sections and merge all sections together when
+ * linking relocatable object files for GHCi.
+ * ld -r normally retains the individual sections, which is what you would want
+ * if the intention is to eventually link into a binary with --gc-sections, but
+ * it doesn't have a flag for directly doing what we want. */
+SECTIONS
+{
+    .text : {
+        *(.text$*)
+    }
+    .rdata : {
+        *(.rdata$*)
+    }
+    .data : {
+        *(.data$*)
+    }
+    .pdata : {
+        *(.pdata$*)
+    }
+    .xdata : {
+        *(.xdata$*)
+    }
+    .bss : {
+        *(.bss$*)
+    }
+}
index 2c62e90..88f3b51 100644 (file)
@@ -358,7 +358,7 @@ SplitObjs = $(if $(and $(filter YES,$(SupportsSplitObjs)),\
 #
 # This is not supported on Darwin (where you can use subsections-via-symbols
 # instead) and Windows is not yet working. (See #11445 and related tickets.)
-OsSupportsSplitSections=$(if $(filter $(TargetOS_CPP),mingw32 darwin),NO,YES)
+OsSupportsSplitSections=$(if $(filter $(TargetOS_CPP),darwin),NO,YES)
 SupportsSplitSections=$(if $(and $(filter YES,$(OsSupportsSplitSections)),\
                                    $(filter YES,$(LdIsGNULd))),YES,NO)
 SplitSections ?= $(SupportsSplitSections)
index 7775856..3b4d1c9 100644 (file)
@@ -138,9 +138,15 @@ endif
 
 ifeq "$$($1_$2_SplitSections)" "YES"
 ifeq "$(LdIsGNULd)" "YES"
+ifeq "$$(HostOS_CPP)" "mingw32"
+$1_$2_LD_SCRIPT_CMD =
+$1_$2_LD_SCRIPT = driver/utils/merge_sections_pe.ld
+else
+$1_$2_LD_SCRIPT_CMD = -T
 $1_$2_LD_SCRIPT = driver/utils/merge_sections.ld
 endif
 endif
+endif
 
 # Build the GHCi library
 ifeq "$3" "v"
@@ -152,7 +158,7 @@ BINDIST_LIBS += $$($1_$2_GHCI_LIB)
 endif
 endif
 $$($1_$2_GHCI_LIB) : $$($1_$2_$3_HS_OBJS) $$($1_$2_$3_CMM_OBJS) $$($1_$2_$3_C_OBJS) $$($1_$2_$3_S_OBJS) $$($1_$2_EXTRA_OBJS) $$($1_$2_LD_SCRIPT)
-       $$(call cmd,LD) $$(CONF_LD_LINKER_OPTS_STAGE$4) -r $$(if $$($1_$2_LD_SCRIPT),-T $$($1_$2_LD_SCRIPT)) -o $$@ $$(EXTRA_LD_LINKER_OPTS) $$($1_$2_$3_HS_OBJS) $$($1_$2_$3_CMM_OBJS) $$($1_$2_$3_C_OBJS) $$($1_$2_$3_S_OBJS) $$($1_$2_EXTRA_OBJS)
+       $$(call cmd,LD) $$(CONF_LD_LINKER_OPTS_STAGE$4) -r $$(if $$($1_$2_LD_SCRIPT),$$($1_$2_LD_SCRIPT_CMD) $$($1_$2_LD_SCRIPT)) -o $$@ $$(EXTRA_LD_LINKER_OPTS) $$($1_$2_$3_HS_OBJS) $$($1_$2_$3_CMM_OBJS) $$($1_$2_$3_C_OBJS) $$($1_$2_$3_S_OBJS) $$($1_$2_EXTRA_OBJS)
 
 ifeq "$$($1_$2_BUILD_GHCI_LIB)" "YES"
 # Don't bother making ghci libs for bootstrapping packages