Cheng Shao pushed to branch wip/fix-clang64-split-sections at Glasgow Haskell Compiler / GHC
Commits:
-
6213bb57
by maralorn at 2026-01-02T16:30:32+01:00
-
b820ff50
by Janis Voigtlaender at 2026-01-05T02:43:18-05:00
-
f9bda57b
by Cheng Shao at 2026-01-05T09:25:50+01:00
-
9f426e30
by Cheng Shao at 2026-01-05T10:33:30+01:00
-
043299ef
by Cheng Shao at 2026-01-05T10:42:34+01:00
8 changed files:
- compiler/GHC/Cmm.hs
- compiler/GHC/Cmm/InitFini.hs
- compiler/GHC/CmmToAsm/Ppr.hs
- compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Control/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Context.hs
Changes:
| ... | ... | @@ -278,8 +278,8 @@ data SectionProtection |
| 278 | 278 | deriving (Eq)
|
| 279 | 279 | |
| 280 | 280 | -- | Should a data in this section be considered constant at runtime
|
| 281 | -sectionProtection :: Section -> SectionProtection
|
|
| 282 | -sectionProtection (Section t _) = case t of
|
|
| 281 | +sectionProtection :: SectionType -> SectionProtection
|
|
| 282 | +sectionProtection t = case t of
|
|
| 283 | 283 | Text -> ReadOnlySection
|
| 284 | 284 | ReadOnlyData -> ReadOnlySection
|
| 285 | 285 | RelocatableReadOnlyData -> WriteProtectedSection
|
| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | module GHC.Cmm.InitFini
|
| 3 | 3 | ( InitOrFini(..)
|
| 4 | 4 | , isInitOrFiniArray
|
| 5 | + , isInitOrFiniSection
|
|
| 5 | 6 | ) where
|
| 6 | 7 | |
| 7 | 8 | import GHC.Prelude
|
| ... | ... | @@ -63,8 +64,8 @@ finalizer CmmDecl will be emitted per module. |
| 63 | 64 | data InitOrFini = IsInitArray | IsFiniArray
|
| 64 | 65 | |
| 65 | 66 | isInitOrFiniArray :: RawCmmDecl -> Maybe (InitOrFini, [CLabel])
|
| 66 | -isInitOrFiniArray (CmmData sect (CmmStaticsRaw _ lits))
|
|
| 67 | - | Just initOrFini <- isInitOrFiniSection sect
|
|
| 67 | +isInitOrFiniArray (CmmData (Section t _) (CmmStaticsRaw _ lits))
|
|
| 68 | + | Just initOrFini <- isInitOrFiniSection t
|
|
| 68 | 69 | = Just (initOrFini, map get_label lits)
|
| 69 | 70 | where
|
| 70 | 71 | get_label :: CmmStatic -> CLabel
|
| ... | ... | @@ -72,7 +73,7 @@ isInitOrFiniArray (CmmData sect (CmmStaticsRaw _ lits)) |
| 72 | 73 | get_label static = pprPanic "isInitOrFiniArray: invalid entry" (ppr static)
|
| 73 | 74 | isInitOrFiniArray _ = Nothing
|
| 74 | 75 | |
| 75 | -isInitOrFiniSection :: Section -> Maybe InitOrFini
|
|
| 76 | -isInitOrFiniSection (Section InitArray _) = Just IsInitArray
|
|
| 77 | -isInitOrFiniSection (Section FiniArray _) = Just IsFiniArray
|
|
| 76 | +isInitOrFiniSection :: SectionType -> Maybe InitOrFini
|
|
| 77 | +isInitOrFiniSection InitArray = Just IsInitArray
|
|
| 78 | +isInitOrFiniSection FiniArray = Just IsFiniArray
|
|
| 78 | 79 | isInitOrFiniSection _ = Nothing |
| 1 | 1 | {-# LANGUAGE MagicHash #-}
|
| 2 | +{-# LANGUAGE MultiWayIf #-}
|
|
| 2 | 3 | |
| 3 | 4 | -----------------------------------------------------------------------------
|
| 4 | 5 | --
|
| ... | ... | @@ -23,6 +24,7 @@ import GHC.Prelude |
| 23 | 24 | |
| 24 | 25 | import GHC.Utils.Asm
|
| 25 | 26 | import GHC.Cmm.CLabel
|
| 27 | +import GHC.Cmm.InitFini
|
|
| 26 | 28 | import GHC.Cmm
|
| 27 | 29 | import GHC.CmmToAsm.Config
|
| 28 | 30 | import GHC.Utils.Outputable as SDoc
|
| ... | ... | @@ -240,21 +242,45 @@ pprGNUSectionHeader config t suffix = |
| 240 | 242 | | OSMinGW32 <- platformOS platform
|
| 241 | 243 | -> text ".rdata"
|
| 242 | 244 | | otherwise -> text ".ipe"
|
| 243 | - flags = case t of
|
|
| 244 | - Text
|
|
| 245 | - | OSMinGW32 <- platformOS platform, splitSections
|
|
| 246 | - -> text ",\"xr\""
|
|
| 247 | - | splitSections
|
|
| 248 | - -> text ",\"ax\"," <> sectionType platform "progbits"
|
|
| 249 | - CString
|
|
| 250 | - | OSMinGW32 <- platformOS platform
|
|
| 251 | - -> empty
|
|
| 252 | - | otherwise -> text ",\"aMS\"," <> sectionType platform "progbits" <> text ",1"
|
|
| 253 | - IPE
|
|
| 254 | - | OSMinGW32 <- platformOS platform
|
|
| 255 | - -> empty
|
|
| 256 | - | otherwise -> text ",\"a\"," <> sectionType platform "progbits"
|
|
| 257 | - _ -> empty
|
|
| 245 | + flags
|
|
| 246 | + -- See
|
|
| 247 | + -- https://github.com/llvm/llvm-project/blob/llvmorg-21.1.8/lld/COFF/Chunks.cpp#L54
|
|
| 248 | + -- and https://llvm.org/docs/Extensions.html#section-directive.
|
|
| 249 | + -- LLD COFF backend gc-sections only work on COMDAT sections so
|
|
| 250 | + -- we need to mark it as a COMDAT section. You can use clang64
|
|
| 251 | + -- toolchain to compile small examples with
|
|
| 252 | + -- `-ffunction-sections -fdata-sections -S` to see these section
|
|
| 253 | + -- headers in the wild.
|
|
| 254 | + | OSMinGW32 <- platformOS platform,
|
|
| 255 | + splitSections =
|
|
| 256 | + if
|
|
| 257 | + | Just _ <- isInitOrFiniSection t -> text ",\"dw\""
|
|
| 258 | + | otherwise ->
|
|
| 259 | + let coff_section_flags
|
|
| 260 | + | Text <- t = "xr"
|
|
| 261 | + | UninitialisedData <- t = "bw"
|
|
| 262 | + | ReadWriteSection <- sectionProtection t = "dw"
|
|
| 263 | + | otherwise = "dr"
|
|
| 264 | + in hcat
|
|
| 265 | + [ text ",\"",
|
|
| 266 | + text coff_section_flags,
|
|
| 267 | + text "\",one_only,",
|
|
| 268 | + pprAsmLabel platform suffix
|
|
| 269 | + ]
|
|
| 270 | + | otherwise =
|
|
| 271 | + case t of
|
|
| 272 | + Text
|
|
| 273 | + | splitSections
|
|
| 274 | + -> text ",\"ax\"," <> sectionType platform "progbits"
|
|
| 275 | + CString
|
|
| 276 | + | OSMinGW32 <- platformOS platform
|
|
| 277 | + -> empty
|
|
| 278 | + | otherwise -> text ",\"aMS\"," <> sectionType platform "progbits" <> text ",1"
|
|
| 279 | + IPE
|
|
| 280 | + | OSMinGW32 <- platformOS platform
|
|
| 281 | + -> empty
|
|
| 282 | + | otherwise -> text ",\"a\"," <> sectionType platform "progbits"
|
|
| 283 | + _ -> empty
|
|
| 258 | 284 | {-# SPECIALIZE pprGNUSectionHeader :: NCGConfig -> SectionType -> CLabel -> SDoc #-}
|
| 259 | 285 | {-# SPECIALIZE pprGNUSectionHeader :: NCGConfig -> SectionType -> CLabel -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable
|
| 260 | 286 |
| ... | ... | @@ -107,7 +107,7 @@ symKindFromCLabel lbl |
| 107 | 107 | -- | Calculate a data section's kind, see haddock docs of
|
| 108 | 108 | -- 'DataSectionKind' for more explanation.
|
| 109 | 109 | dataSectionKindFromCmmSection :: Section -> DataSectionKind
|
| 110 | -dataSectionKindFromCmmSection s = case sectionProtection s of
|
|
| 110 | +dataSectionKindFromCmmSection (Section t _) = case sectionProtection t of
|
|
| 111 | 111 | ReadWriteSection -> SectionData
|
| 112 | 112 | _ -> SectionROData
|
| 113 | 113 |
| ... | ... | @@ -121,7 +121,7 @@ pprTop platform = \case |
| 121 | 121 | pprDataExterns platform lits $$
|
| 122 | 122 | pprWordArray platform (isSecConstant section) lbl lits
|
| 123 | 123 | where
|
| 124 | - isSecConstant section = case sectionProtection section of
|
|
| 124 | + isSecConstant (Section t _) = case sectionProtection t of
|
|
| 125 | 125 | ReadOnlySection -> True
|
| 126 | 126 | WriteProtectedSection -> True
|
| 127 | 127 | _ -> False
|
| ... | ... | @@ -75,7 +75,7 @@ genLlvmData (sect, statics) |
| 75 | 75 | IsFiniArray -> fsLit "llvm.global_dtors"
|
| 76 | 76 | in genGlobalLabelArray var clbls
|
| 77 | 77 | |
| 78 | -genLlvmData (sec, CmmStaticsRaw lbl xs) = do
|
|
| 78 | +genLlvmData (sec@(Section t _), CmmStaticsRaw lbl xs) = do
|
|
| 79 | 79 | label <- strCLabel_llvm lbl
|
| 80 | 80 | static <- mapM genData xs
|
| 81 | 81 | lmsec <- llvmSection sec
|
| ... | ... | @@ -92,7 +92,7 @@ genLlvmData (sec, CmmStaticsRaw lbl xs) = do |
| 92 | 92 | then Just 2 else Just 1
|
| 93 | 93 | Section Data _ -> Just $ platformWordSizeInBytes platform
|
| 94 | 94 | _ -> Nothing
|
| 95 | - const = if sectionProtection sec == ReadOnlySection
|
|
| 95 | + const = if sectionProtection t == ReadOnlySection
|
|
| 96 | 96 | then Constant else Global
|
| 97 | 97 | varDef = LMGlobalVar label tyAlias link lmsec align const
|
| 98 | 98 | globDef = LMGlobal varDef struct
|
| ... | ... | @@ -314,7 +314,7 @@ Core: https://gitlab.haskell.org/ghc/ghc/issues/11795#note_118976 |
| 314 | 314 | -- | @'replicateM' n act@ performs the action @act@ @n@ times,
|
| 315 | 315 | -- and then returns the list of results.
|
| 316 | 316 | --
|
| 317 | --- @replicateM n (pure x) == 'replicate' n x@
|
|
| 317 | +-- @replicateM n (pure x) == pure ('replicate' n x)@
|
|
| 318 | 318 | --
|
| 319 | 319 | -- ==== __Examples__
|
| 320 | 320 | --
|
| ... | ... | @@ -64,7 +64,7 @@ instance Monoid ExceptionContext where |
| 64 | 64 | emptyExceptionContext :: ExceptionContext
|
| 65 | 65 | emptyExceptionContext = ExceptionContext []
|
| 66 | 66 | |
| 67 | --- | Construct a singleton 'ExceptionContext' from an 'ExceptionAnnotation'.
|
|
| 67 | +-- | Add an 'ExceptionAnnotation' to a given 'ExceptionContext'.
|
|
| 68 | 68 | --
|
| 69 | 69 | -- @since base-4.20.0.0
|
| 70 | 70 | addExceptionAnnotation :: ExceptionAnnotation a => a -> ExceptionContext -> ExceptionContext
|