Duncan Coutts pushed to branch wip/dcoutts/windows-dlls-experimental at Glasgow Haskell Compiler / GHC

Commits:

16 changed files:

Changes:

  • compiler/GHC/Cmm/Parser.y
    ... ... @@ -668,25 +668,29 @@ importName
    668 668
             -- an unnamed Haskell package. This corresponds on Windows/PE to
    
    669 669
             -- __declspec(dllimport) in C.
    
    670 670
             | 'extern' NAME
    
    671
    -        { ($2, mkForeignLabel $2 ForeignLabelInExternalPackage IsFunction) }
    
    671
    +        { ($2, mkForeignLabel $2 ForeignLabelInExternalPackage
    
    672
    +                                 ForeignLabelIsFunction) }
    
    672 673
     
    
    673 674
             -- A data label imported from another unamed shared library.
    
    674 675
             -- This corresponds on Windows/PE to __declspec(dllimport) in C (but
    
    675 676
             -- cmm doesn't know about data vs function symbols so we have to say).
    
    676 677
             | 'extern' 'DATA' NAME
    
    677
    -        { ($3, mkForeignLabel $3 ForeignLabelInExternalPackage IsData) }
    
    678
    +        { ($3, mkForeignLabel $3 ForeignLabelInExternalPackage
    
    679
    +                                 ForeignLabelIsData) }
    
    678 680
     
    
    679 681
             -- A code label imported from the shared library for a Haskell package
    
    680 682
             -- with the given UnitId. Such labels behave as local when used within
    
    681 683
             -- the specified unit, or as extern otherwise.
    
    682 684
             | STRING NAME
    
    683
    -        { ($2, mkForeignLabel $2 (ForeignLabelInPackage (UnitId (mkFastString $1))) IsFunction) }
    
    685
    +        { ($2, mkForeignLabel $2 (ForeignLabelInPackage (UnitId (mkFastString $1)))
    
    686
    +                                 ForeignLabelIsFunction) }
    
    684 687
     
    
    685 688
             -- A data label imported from the shared library for a Haskell package
    
    686 689
             -- with the given UnitId. Such labels behave as local when used within
    
    687 690
             -- the specified unit, or as extern otherwise.
    
    688 691
             | STRING 'DATA' NAME
    
    689
    -        { ($3, mkForeignLabel $3 (ForeignLabelInPackage (UnitId (mkFastString $1))) IsData) }
    
    692
    +        { ($3, mkForeignLabel $3 (ForeignLabelInPackage (UnitId (mkFastString $1)))
    
    693
    +                                 ForeignLabelIsData) }
    
    690 694
     
    
    691 695
     
    
    692 696
     names   :: { [FastString] }
    

  • compiler/GHC/Driver/Session.hs
    ... ... @@ -3624,7 +3624,7 @@ compilerInfo dflags
    3624 3624
            ("target has RTS linker",       showBool $ platformHasRTSLinker platform),
    
    3625 3625
            ("Target default backend",      show     $ platformDefaultBackend platform),
    
    3626 3626
            -- Whether or not we support @-dynamic-too@
    
    3627
    -       ("Support dynamic-too",         showBool $ not isWindows),
    
    3627
    +       ("Support dynamic-too",         "YES"),
    
    3628 3628
            -- Whether or not we support the @-j@ flag with @--make@.
    
    3629 3629
            ("Support parallel --make",     "YES"),
    
    3630 3630
            -- Whether or not we support "Foo from foo-0.1-XXX:Foo" syntax in
    
    ... ... @@ -3659,7 +3659,6 @@ compilerInfo dflags
    3659 3659
         showBool True  = "YES"
    
    3660 3660
         showBool False = "NO"
    
    3661 3661
         platform  = targetPlatform dflags
    
    3662
    -    isWindows = platformOS platform == OSMinGW32
    
    3663 3662
         expandDirectories = expandToolDir (toolDir dflags) . expandTopDir (topDir dflags)
    
    3664 3663
         query :: (Target -> a) -> a
    
    3665 3664
         query f = f (rawTarget dflags)
    
    ... ... @@ -3757,11 +3756,6 @@ makeDynFlagsConsistent :: DynFlags -> (DynFlags, [Warn], [Located SDoc])
    3757 3756
     -- ensure that a later change doesn't invalidate an earlier check.
    
    3758 3757
     -- Be careful not to introduce potential loops!
    
    3759 3758
     makeDynFlagsConsistent dflags
    
    3760
    - -- Disable -dynamic-too on Windows (#8228, #7134, #5987)
    
    3761
    - | os == OSMinGW32 && gopt Opt_BuildDynamicToo dflags
    
    3762
    -    = let dflags' = gopt_unset dflags Opt_BuildDynamicToo
    
    3763
    -          warn    = "-dynamic-too is not supported on Windows"
    
    3764
    -      in loop dflags' warn
    
    3765 3759
      -- Disable -dynamic-too if we are are compiling with -dynamic already, otherwise
    
    3766 3760
      -- you get two dynamic object files (.o and .dyn_o). (#20436)
    
    3767 3761
      | ways dflags `hasWay` WayDyn && gopt Opt_BuildDynamicToo dflags
    

  • compiler/GHC/Stg/Utils.hs
    ... ... @@ -128,6 +128,9 @@ stripStgTicksTopE p = go
    128 128
              go other               = other
    
    129 129
     
    
    130 130
     -- | Do we allow the given top-level (static) ConApp?
    
    131
    +--
    
    132
    +-- Currently this is unconditionally True, but historically it has been more
    
    133
    +-- complicated, so the mechanism to choose otherwise is still here for now.
    
    131 134
     allowTopLevelConApp
    
    132 135
       :: Platform
    
    133 136
       -> Bool          -- is Opt_ExternalDynamicRefs enabled?
    
    ... ... @@ -138,22 +141,18 @@ allowTopLevelConApp
    138 141
     allowTopLevelConApp platform ext_dyn_refs this_mod con args
    
    139 142
       -- we're not using dynamic linking
    
    140 143
       | not ext_dyn_refs = True
    
    141
    -  -- if the target OS is Windows, we only allow top-level ConApps if they don't
    
    142
    -  -- reference external names (Windows DLLs have a problem with static cross-DLL
    
    143
    -  -- refs)
    
    144
    -  | platformOS platform == OSMinGW32 = not is_external_con_app
    
    144
    +
    
    145
    +  -- On Windows, for now, always use top level constructor applications, and
    
    146
    +  -- rely on Mingw "pseudo relocations" to make this work. We might want to
    
    147
    +  -- have a flag to control this behaviour, because using pseudo-relocations
    
    148
    +  -- can be incompatible with some security restrictions, but note that
    
    149
    +  -- ghc-internal and everything would need to be rebuilt. Note also that
    
    150
    +  -- dynamic top level con apps increases symbol exports a lot.
    
    151
    +  | platformOS platform == OSMinGW32 = True
    
    152
    +
    
    145 153
       -- otherwise, allowed
    
    146 154
       -- Sylvain: shouldn't this be False when (ext_dyn_refs && is_external_con_app)?
    
    147 155
       | otherwise = True
    
    148
    -  where
    
    149
    -    is_external_con_app = isDynLinkName platform this_mod (dataConName con) || any is_dll_arg args
    
    150
    -
    
    151
    -    -- NB: typePrimRep1 is legit because any free variables won't have
    
    152
    -    -- unlifted type (there are no unlifted things at top level)
    
    153
    -    is_dll_arg :: StgArg -> Bool
    
    154
    -    is_dll_arg (StgVarArg v) =  isAddrRep (typePrimRep1 (idType v))
    
    155
    -                             && isDynLinkName platform this_mod (idName v)
    
    156
    -    is_dll_arg _             = False
    
    157 156
     
    
    158 157
     -- True of machine addresses; these are the things that don't work across DLLs.
    
    159 158
     -- The key point here is that VoidRep comes out False, so that a top level
    

  • hadrian/src/Builder.hs
    ... ... @@ -346,11 +346,7 @@ instance H.Builder Builder where
    346 346
     
    
    347 347
                     Haddock BuildPackage -> runHaddock path buildArgs buildInputs
    
    348 348
     
    
    349
    -                Ghc FindHsDependencies _ -> do
    
    350
    -                  -- Use a response file for ghc -M invocations, to
    
    351
    -                  -- avoid issues with command line size limit on
    
    352
    -                  -- Windows (#26637)
    
    353
    -                  runGhcWithResponse path buildArgs buildInputs
    
    349
    +                Ghc _ _ -> runGhcWithResponse path buildArgs buildInputs buildOptions
    
    354 350
     
    
    355 351
                     HsCpp    -> captureStdout
    
    356 352
     
    
    ... ... @@ -394,16 +390,18 @@ runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do
    394 390
         writeFile' tmp $ escapeArgs fileInputs
    
    395 391
         cmd [haddockPath] flagArgs ('@' : tmp)
    
    396 392
     
    
    397
    -runGhcWithResponse :: FilePath -> [String] -> [FilePath] -> Action ()
    
    398
    -runGhcWithResponse ghcPath flagArgs fileInputs = withTempFile $ \tmp -> do
    
    399
    -
    
    400
    -    writeFile' tmp $ escapeArgs fileInputs
    
    401
    -
    
    402
    -    -- We can't put the flags in a response file, because some flags
    
    403
    -    -- require empty arguments (such as the -dep-suffix flag), but
    
    404
    -    -- that isn't supported yet due to #26560.
    
    405
    -    cmd [ghcPath] flagArgs ('@' : tmp)
    
    406
    -
    
    393
    +-- | Use a response file for ghc invocations to avoid issues with command line
    
    394
    +-- size limit on Windows (#26637).
    
    395
    +runGhcWithResponse :: FilePath -- ^ Path to ghc
    
    396
    +  -> [String] -- ^ Arguments passed on the command line
    
    397
    +  -> [FilePath] -- ^ Input file paths (passed via response file)
    
    398
    +  -> [CmdOption]
    
    399
    +  -> Action ()
    
    400
    +runGhcWithResponse ghcPath buildArgs buildInputs buildOptions = withTempFile $ \tmp -> do
    
    401
    +  let tmpContents = escapeArgs buildInputs
    
    402
    +  putVerbose $ "Build Inputs (" <> tmp <> "): " <> show buildInputs
    
    403
    +  writeFile' tmp tmpContents
    
    404
    +  cmd [ghcPath] buildArgs ('@' : tmp) buildOptions
    
    407 405
     
    
    408 406
     -- TODO: Some builders are required only on certain platforms. For example,
    
    409 407
     -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform
    

  • hadrian/src/Hadrian/Builder.hs
    ... ... @@ -29,7 +29,9 @@ import Hadrian.Utilities
    29 29
     
    
    30 30
     -- | This data structure captures all information relevant to invoking a builder.
    
    31 31
     data BuildInfo = BuildInfo {
    
    32
    -    -- | Command line arguments.
    
    32
    +    -- | Command line arguments. Some builders (e.g. Ar, Ghc, Haddock) omit
    
    33
    +    -- buildInputs from buildArgs so that buildInputs can be passed separately
    
    34
    +    -- using a response file.
    
    33 35
         buildArgs :: [String],
    
    34 36
         -- | Input files.
    
    35 37
         buildInputs :: [FilePath],
    

  • hadrian/src/Oracles/Flag.hs
    ... ... @@ -82,11 +82,10 @@ arSupportsAtFile stage = Toolchain.arSupportsAtFile . tgtAr <$> targetStage stag
    82 82
     platformSupportsSharedLibs :: Action Bool
    
    83 83
     -- FIXME: This is querying about the target but is named "platformXXX", targetSupportsSharedLibs would be better
    
    84 84
     platformSupportsSharedLibs = do
    
    85
    -    windows       <- isWinTarget
    
    86 85
         ppc_linux     <- (&&) <$> anyTargetArch [ ArchPPC ] <*> anyTargetOs [ OSLinux ]
    
    87 86
         solaris       <- (&&) <$> anyTargetArch [ ArchX86 ] <*> anyTargetOs [ OSSolaris2 ]
    
    88 87
         javascript    <- anyTargetArch     [ ArchJavaScript ]
    
    89
    -    return $ not (windows || javascript || ppc_linux || solaris)
    
    88
    +    return $ not (javascript || ppc_linux || solaris)
    
    90 89
     
    
    91 90
     -- | Does the target support threaded RTS?
    
    92 91
     targetSupportsThreadedRts :: Action Bool
    

  • hadrian/src/Rules/Register.hs
    ... ... @@ -12,7 +12,6 @@ import Hadrian.BuildPath
    12 12
     import Hadrian.Expression
    
    13 13
     import Hadrian.Haskell.Cabal
    
    14 14
     import Packages
    
    15
    -import Rules.Rts
    
    16 15
     import Settings
    
    17 16
     import Target
    
    18 17
     import Utilities
    
    ... ... @@ -88,14 +87,9 @@ parseToBuildSubdirectory root = do
    88 87
     -- * Registering
    
    89 88
     
    
    90 89
     registerPackages :: [Context] -> Action ()
    
    91
    -registerPackages ctxs = do
    
    90
    +registerPackages ctxs =
    
    92 91
         need =<< mapM pkgRegisteredLibraryFile ctxs
    
    93 92
     
    
    94
    -    -- Dynamic RTS library files need symlinks (Rules.Rts.rtsRules).
    
    95
    -    forM_ ctxs $ \ ctx -> when (package ctx == rts) $ do
    
    96
    -        ways <- interpretInContext ctx (getLibraryWays <> getRtsWays)
    
    97
    -        needRtsSymLinks (stage ctx) ways
    
    98
    -
    
    99 93
     -- | Register a package and initialise the corresponding package database if
    
    100 94
     -- need be. Note that we only register packages in 'Stage0' and 'Stage1'.
    
    101 95
     registerPackageRules :: [(Resource, Int)] -> Stage -> Inplace -> Rules ()
    

  • hadrian/src/Rules/Rts.hs
    1
    -{-# LANGUAGE MultiWayIf #-}
    
    1
    +module Rules.Rts (rtsRules) where
    
    2 2
     
    
    3
    -module Rules.Rts (rtsRules, needRtsSymLinks) where
    
    4
    -
    
    5
    -import qualified Data.Set as Set
    
    6
    -
    
    7
    -import Packages (rts)
    
    8 3
     import Hadrian.Utilities
    
    9 4
     import Settings.Builders.Common
    
    10 5
     
    
    ... ... @@ -12,18 +7,7 @@ import Settings.Builders.Common
    12 7
     -- library files (see Rules.Library.libraryRules).
    
    13 8
     rtsRules :: Rules ()
    
    14 9
     rtsRules = priority 3 $ do
    
    15
    -    -- Dynamic RTS library files need symlinks without the dummy version number.
    
    16
    -    -- This is for backwards compatibility (the old make build system omitted the
    
    17
    -    -- dummy version number).
    
    18 10
         root <- buildRootRules
    
    19
    -    [ root -/- "**/libHSrts_*-ghc*.so",
    
    20
    -      root -/- "**/libHSrts_*-ghc*.dylib",
    
    21
    -      root -/- "**/libHSrts-ghc*.so",
    
    22
    -      root -/- "**/libHSrts-ghc*.dylib"]
    
    23
    -      |%> \ rtsLibFilePath' -> createFileLink
    
    24
    -            (addRtsDummyVersion $ takeFileName rtsLibFilePath')
    
    25
    -            rtsLibFilePath'
    
    26
    -
    
    27 11
         -- Solve the recursive dependency between the rts and ghc-internal
    
    28 12
         -- on Windows by creating an import lib for the ghc-internal dll,
    
    29 13
         -- to be linked into the rts dll.
    
    ... ... @@ -37,35 +21,3 @@ buildGhcInternalImportLib target = do
    37 21
             output = target -- the .dll.a import lib
    
    38 22
         need [input]
    
    39 23
         runBuilder Dlltool ["-d", input, "-l", output] [input] [output]
    40
    -
    
    41
    --- Need symlinks generated by rtsRules.
    
    42
    -needRtsSymLinks :: Stage -> Set.Set Way -> Action ()
    
    43
    -needRtsSymLinks stage rtsWays
    
    44
    -    = forM_ (Set.filter (wayUnit Dynamic) rtsWays) $ \ way -> do
    
    45
    -        let ctx = Context stage rts way Final
    
    46
    -        distDir     <- distDynDir ctx
    
    47
    -        rtsLibFile  <- takeFileName <$> pkgLibraryFile ctx
    
    48
    -        need [removeRtsDummyVersion (distDir </> rtsLibFile)]
    
    49
    -
    
    50
    -prefix, versionlessPrefix :: String
    
    51
    -versionlessPrefix = "libHSrts"
    
    52
    -prefix = versionlessPrefix ++ "-1.0.3"
    
    53
    -
    
    54
    --- removeRtsDummyVersion "a/libHSrts-1.0-ghc1.2.3.4.so"
    
    55
    ---                    == "a/libHSrts-ghc1.2.3.4.so"
    
    56
    -removeRtsDummyVersion :: FilePath -> FilePath
    
    57
    -removeRtsDummyVersion = replaceLibFilePrefix prefix versionlessPrefix
    
    58
    -
    
    59
    --- addRtsDummyVersion "a/libHSrts-ghc1.2.3.4.so"
    
    60
    ---                 == "a/libHSrts-1.0-ghc1.2.3.4.so"
    
    61
    -addRtsDummyVersion :: FilePath -> FilePath
    
    62
    -addRtsDummyVersion = replaceLibFilePrefix versionlessPrefix prefix
    
    63
    -
    
    64
    -replaceLibFilePrefix :: String -> String -> FilePath -> FilePath
    
    65
    -replaceLibFilePrefix oldPrefix newPrefix oldFilePath = let
    
    66
    -    oldFileName = takeFileName oldFilePath
    
    67
    -    newFileName = maybe
    
    68
    -        (error $ "Expected RTS library file to start with " ++ oldPrefix)
    
    69
    -        (newPrefix ++)
    
    70
    -        (stripPrefix oldPrefix oldFileName)
    
    71
    -    in replaceFileName oldFilePath newFileName

  • hadrian/src/Settings/Builders/Ghc.hs
    ... ... @@ -62,7 +62,6 @@ compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do
    62 62
                       [ arg "-fwrite-ide-info"
    
    63 63
                       , arg "-hiedir", arg hie_path
    
    64 64
                       ]
    
    65
    -            , getInputs
    
    66 65
                 , arg "-o", arg =<< getOutput ]
    
    67 66
     
    
    68 67
     compileC :: Args
    
    ... ... @@ -78,7 +77,6 @@ compileC = builder (Ghc CompileCWithGhc) ? do
    78 77
                 , mconcat (map (map ("-optc" ++) <$>) ccArgs)
    
    79 78
                 , defaultGhcWarningsArgs
    
    80 79
                 , arg "-c"
    
    81
    -            , getInputs
    
    82 80
                 , arg "-o"
    
    83 81
                 , arg =<< getOutput ]
    
    84 82
     
    
    ... ... @@ -95,7 +93,6 @@ compileCxx = builder (Ghc CompileCppWithGhc) ? do
    95 93
                 , mconcat (map (map ("-optcxx" ++) <$>) ccArgs)
    
    96 94
                 , defaultGhcWarningsArgs
    
    97 95
                 , arg "-c"
    
    98
    -            , getInputs
    
    99 96
                 , arg "-o"
    
    100 97
                 , arg =<< getOutput ]
    
    101 98
     
    

  • hadrian/src/Settings/Default.hs
    ... ... @@ -44,6 +44,7 @@ import Settings.Builders.SplitSections
    44 44
     import Settings.Builders.RunTest
    
    45 45
     import Settings.Builders.Xelatex
    
    46 46
     import Settings.Packages
    
    47
    +import Settings.Program
    
    47 48
     import Settings.Warnings
    
    48 49
     import qualified Hadrian.Builder.Git
    
    49 50
     import Settings.Builders.Win32Tarballs
    
    ... ... @@ -215,12 +216,32 @@ testsuitePackages = return ([ timeout | windowsHost ] ++ [ checkPpr, checkExact,
    215 216
     -- * We build 'profiling' way when stage > Stage0.
    
    216 217
     -- * We build 'dynamic' way when stage > Stage0 and the platform supports it.
    
    217 218
     defaultLibraryWays :: Ways
    
    218
    -defaultLibraryWays = Set.fromList <$>
    
    219
    -    mconcat
    
    220
    -    [ pure [vanilla]
    
    221
    -    , notStage0 ? pure [profiling]
    
    222
    -    , notStage0 ? platformSupportsSharedLibs ? pure [dynamic, profilingDynamic]
    
    223
    -    ]
    
    219
    +defaultLibraryWays = do
    
    220
    +    pkg <- getPackage
    
    221
    +    if isLibrary pkg
    
    222
    +
    
    223
    +      -- modules for libraries get built several ways
    
    224
    +      then Set.fromList <$>
    
    225
    +             mconcat
    
    226
    +             [ pure [vanilla]
    
    227
    +             , notStage0 ? pure [profiling]
    
    228
    +             , notStage0 ? platformSupportsSharedLibs
    
    229
    +                         ? onlyDynGhcLibIfSupported
    
    230
    +                         ? pure [dynamic, profilingDynamic]
    
    231
    +             ]
    
    232
    +
    
    233
    +      -- modules for executables get built only one way
    
    234
    +      else do stage <- getStage
    
    235
    +              Set.singleton <$> expr (programWay stage pkg)
    
    236
    +
    
    237
    +-- | Only build the ghc library the dynamic way, if the platform supports it.
    
    238
    +--
    
    239
    +onlyDynGhcLibIfSupported :: Predicate
    
    240
    +onlyDynGhcLibIfSupported = do
    
    241
    +    pkg <- getPackage
    
    242
    +    if pkg == compiler
    
    243
    +      then expr defaultDynamicGhcPrograms
    
    244
    +      else pure True
    
    224 245
     
    
    225 246
     -- | Default build ways for the RTS.
    
    226 247
     defaultRtsWays :: Ways
    
    ... ... @@ -310,7 +331,10 @@ defaultFlavour = Flavour
    310 331
     defaultDynamicGhcPrograms :: Action Bool
    
    311 332
     defaultDynamicGhcPrograms = do
    
    312 333
       supportsShared <- platformSupportsSharedLibs
    
    313
    -  return (not windowsHost && supportsShared)
    
    334
    +  winTarget <- isWinTarget
    
    335
    +  -- For now, don't build dynamic ghc on windows because we hit dll
    
    336
    +  -- symbol limits for the ghc library.
    
    337
    +  return (supportsShared && not winTarget)
    
    314 338
     
    
    315 339
     -- | All 'Builder'-dependent command line arguments.
    
    316 340
     defaultBuilderArgs :: Args
    

  • hadrian/src/Settings/Packages.hs
    ... ... @@ -321,6 +321,7 @@ rtsPackageArgs = package rts ? do
    321 321
               , Profiling `wayUnit` way          ? arg "-DPROFILING"
    
    322 322
               , Threaded  `wayUnit` way          ? arg "-DTHREADED_RTS"
    
    323 323
               , notM targetSupportsSMP           ? arg "-optc-DNOSMP"
    
    324
    +          , isWinHost                        ? arg "-optl-Wl,--disable-runtime-pseudo-reloc"
    
    324 325
     
    
    325 326
                 -- See Note [AutoApply.cmm for vectors] in genapply/Main.hs
    
    326 327
                 --
    

  • hadrian/src/Settings/Program.hs
    1 1
     module Settings.Program
    
    2 2
       ( programContext
    
    3
    +  , programWay
    
    3 4
       , ghcWithInterpreter
    
    4 5
       ) where
    
    5 6
     
    
    ... ... @@ -17,18 +18,21 @@ import Settings.Builders.Common (anyTargetOs, anyTargetArch, isArmTarget)
    17 18
     -- get a context/contexts for a given stage and package.
    
    18 19
     programContext :: Stage -> Package -> Action Context
    
    19 20
     programContext stage pkg = do
    
    20
    -    profiled <- askGhcProfiled stage
    
    21
    -    dynGhcProgs <- askDynGhcPrograms --dynamicGhcPrograms =<< flavour
    
    22
    -    return $ Context stage pkg (wayFor profiled dynGhcProgs) Final
    
    21
    +    way <- programWay stage pkg
    
    22
    +    return $ Context stage pkg way Final
    
    23 23
     
    
    24
    -    where wayFor prof dyn
    
    25
    -            | prof && dyn                          = profilingDynamic
    
    26
    -            | pkg == ghc && prof && notStage0 stage = profiling
    
    27
    -            | dyn && notStage0 stage                = dynamic
    
    28
    -            | otherwise                            = vanilla
    
    24
    +programWay :: Stage -> Package -> Action Way
    
    25
    +programWay stage pkg =
    
    26
    +    wayFor <$> askGhcProfiled stage <*> askDynGhcPrograms
    
    27
    +  where
    
    28
    +    wayFor prof dyn
    
    29
    +      | prof && dyn                           = profilingDynamic
    
    30
    +      | pkg == ghc && prof && notStage0 stage = profiling
    
    31
    +      | dyn && notStage0 stage                = dynamic
    
    32
    +      | otherwise                             = vanilla
    
    29 33
     
    
    30
    -          notStage0 (Stage0 {}) = False
    
    31
    -          notStage0 _ = True
    
    34
    +    notStage0 (Stage0 {}) = False
    
    35
    +    notStage0 _ = True
    
    32 36
     
    
    33 37
     -- | When cross compiling, enable for stage0 to get ghci
    
    34 38
     -- support. But when not cross compiling, disable for
    

  • rts/IOManager.h
    ... ... @@ -21,6 +21,15 @@
    21 21
     
    
    22 22
     #include "sm/GC.h" // for evac_fn
    
    23 23
     
    
    24
    +#if defined(mingw32_HOST_OS)
    
    25
    +/* Global var (only on Windows) that is exported (hence before BeginPrivate.h)
    
    26
    + * to be shared with the I/O code in the base library to tell us which style
    
    27
    + * of I/O manager we are using: one that uses the Windows native API HANDLEs,
    
    28
    + * or one that uses Posix style fds.
    
    29
    + */
    
    30
    +extern bool rts_IOManagerIsWin32Native;
    
    31
    +#endif
    
    32
    +
    
    24 33
     #include "BeginPrivate.h"
    
    25 34
     
    
    26 35
     /* The ./configure gives us a set of CPP flags, one for each named I/O manager:
    
    ... ... @@ -160,14 +169,6 @@ typedef enum {
    160 169
     /* Global var to tell us which I/O manager impl we are using */
    
    161 170
     extern IOManagerType iomgr_type;
    
    162 171
     
    
    163
    -#if defined(mingw32_HOST_OS)
    
    164
    -/* Global var (only on Windows) that is exported to be shared with the I/O code
    
    165
    - * in the base library to tell us which style of I/O manager we are using: one
    
    166
    - * that uses the Windows native API HANDLEs, or one that uses Posix style fds.
    
    167
    - */
    
    168
    -extern bool rts_IOManagerIsWin32Native;
    
    169
    -#endif
    
    170
    -
    
    171 172
     
    
    172 173
     /* The CapIOManager is the per-capability data structure belonging to the I/O
    
    173 174
      * manager. It is defined in full in IOManagerInternals.h. The opaque forward
    

  • rts/Linker.c
    ... ... @@ -478,16 +478,7 @@ initLinker_ (int retain_cafs)
    478 478
         symhash = allocStrHashTable();
    
    479 479
     
    
    480 480
         /* populate the symbol table with stuff from the RTS */
    
    481
    -    IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
    
    482
    -    for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
    
    483
    -        IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
    
    484
    -        if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
    
    485
    -                                    symhash, sym->lbl, sym->addr,
    
    486
    -                                    sym->strength, sym->type, 0, NULL)) {
    
    487
    -            barf("ghciInsertSymbolTable failed");
    
    488
    -        }
    
    489
    -    }
    
    490
    -    IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
    
    481
    +    initLinkerRtsSyms(symhash);
    
    491 482
     
    
    492 483
         /* Add extra symbols. rtsExtraSyms() is a weakly defined symbol in the rts,
    
    493 484
          * that can be overrided by linking in an object with a corresponding
    

  • rts/RtsSymbols.c
    ... ... @@ -9,6 +9,8 @@
    9 9
     #include "ghcplatform.h"
    
    10 10
     #include "Rts.h"
    
    11 11
     #include "RtsSymbols.h"
    
    12
    +#include "LinkerInternals.h"
    
    13
    +#include "PathUtils.h"
    
    12 14
     
    
    13 15
     #include "TopHandler.h"
    
    14 16
     #include "HsFFI.h"
    
    ... ... @@ -51,6 +53,19 @@ extern char **environ;
    51 53
     
    
    52 54
     /* -----------------------------------------------------------------------------
    
    53 55
      * Symbols to be inserted into the RTS symbol table.
    
    56
    + *
    
    57
    + * Note [Naming Scheme for Symbol Macros]
    
    58
    + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    59
    + *
    
    60
    + * SymI_*: symbol is internal to the RTS. It resides in an object
    
    61
    + *         file/library that is statically.
    
    62
    + * SymE_*: symbol is external to the RTS library. It might be linked
    
    63
    + *         dynamically.
    
    64
    + *
    
    65
    + * Sym*_HasProto  : the symbol prototype is imported in an include file
    
    66
    + *                  or defined explicitly
    
    67
    + * Sym*_NeedsProto: the symbol is undefined and we add a dummy
    
    68
    + *                  default proto extern void sym(void);
    
    54 69
      */
    
    55 70
     
    
    56 71
     #define Maybe_Stable_Names      SymI_HasProto(stg_mkWeakzh)                   \
    
    ... ... @@ -162,7 +177,7 @@ extern char **environ;
    162 177
           SymI_HasProto(stg_asyncWritezh)                    \
    
    163 178
           SymI_HasProto(stg_asyncDoProczh)                   \
    
    164 179
           SymI_HasProto(rts_InstallConsoleEvent)             \
    
    165
    -      SymI_HasProto(rts_IOManagerIsWin32Native)          \
    
    180
    +      SymI_HasDataProto(rts_IOManagerIsWin32Native)          \
    
    166 181
           SymI_HasProto(rts_ConsoleHandlerDone)              \
    
    167 182
           SymI_NeedsProto(__mingw_module_is_dll)             \
    
    168 183
           RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms))      \
    
    ... ... @@ -912,7 +927,7 @@ extern char **environ;
    912 927
           SymI_HasProto(freeExecPage)                                       \
    
    913 928
           SymI_HasProto(getAllocations)                                     \
    
    914 929
           SymI_HasProto(revertCAFs)                                         \
    
    915
    -      SymI_HasProto(RtsFlags)                                           \
    
    930
    +      SymI_HasDataProto(RtsFlags)                                           \
    
    916 931
           SymI_NeedsDataProto(rts_breakpoint_io_action)                     \
    
    917 932
           SymI_NeedsDataProto(rts_stop_next_breakpoint)                     \
    
    918 933
           SymI_NeedsDataProto(rts_stop_on_exception)                        \
    
    ... ... @@ -923,9 +938,9 @@ extern char **environ;
    923 938
           SymI_NeedsProto(rts_enableStopAfterReturn)                        \
    
    924 939
           SymI_NeedsProto(rts_disableStopAfterReturn)                       \
    
    925 940
           SymI_HasProto(stopTimer)                                          \
    
    926
    -      SymI_HasProto(n_capabilities)                                     \
    
    927
    -      SymI_HasProto(max_n_capabilities)                                 \
    
    928
    -      SymI_HasProto(enabled_capabilities)                               \
    
    941
    +      SymI_HasDataProto(n_capabilities)                                     \
    
    942
    +      SymI_HasDataProto(max_n_capabilities)                                 \
    
    943
    +      SymI_HasDataProto(enabled_capabilities)                               \
    
    929 944
           SymI_HasDataProto(stg_traceEventzh)                                   \
    
    930 945
           SymI_HasDataProto(stg_traceMarkerzh)                                  \
    
    931 946
           SymI_HasDataProto(stg_traceBinaryEventzh)                             \
    
    ... ... @@ -1143,12 +1158,27 @@ extern char **environ;
    1143 1158
           SymI_HasProto(hs_word2float64)
    
    1144 1159
     
    
    1145 1160
     
    
    1146
    -/* entirely bogus claims about types of these symbols */
    
    1147
    -#define SymI_NeedsProto(vvv)  extern void vvv(void);
    
    1148
    -#define SymI_NeedsDataProto(vvv)  extern StgWord vvv[];
    
    1149
    -#define SymE_NeedsProto(vvv)  SymI_NeedsProto(vvv);
    
    1150
    -#define SymE_NeedsDataProto(vvv)  SymI_NeedsDataProto(vvv);
    
    1151
    -#define SymE_HasProto(vvv)    SymI_HasProto(vvv);
    
    1161
    +/* Declare prototypes for the symbols that need it, so we can refer
    
    1162
    + * to them in the rtsSyms table below.
    
    1163
    + *
    
    1164
    + * In particular, for the external ones (SymE_*) we use the dllimport attribute
    
    1165
    + * to indicate that (on Windows) they come from external DLLs. This attribute
    
    1166
    + * is ignored on other platforms.
    
    1167
    + *
    
    1168
    + * The claims about the types of these symbols are entirely bogus.
    
    1169
    + */
    
    1170
    +#if defined(mingw32_HOST_OS) && defined(DYNAMIC)
    
    1171
    +#define DLLIMPORT __attribute__((dllimport))
    
    1172
    +#else
    
    1173
    +#define DLLIMPORT /**/
    
    1174
    +#endif
    
    1175
    +
    
    1176
    +#define SymI_NeedsProto(vvv)      extern           void vvv(void);
    
    1177
    +#define SymI_NeedsDataProto(vvv)  extern           StgWord vvv[];
    
    1178
    +#define SymE_NeedsProto(vvv)      extern DLLIMPORT void vvv(void);
    
    1179
    +#define SymE_NeedsDataProto(vvv)  extern DLLIMPORT StgWord vvv[];
    
    1180
    +
    
    1181
    +#define SymE_HasProto(vvv) /**/
    
    1152 1182
     #define SymI_HasProto(vvv) /**/
    
    1153 1183
     #define SymI_HasDataProto(vvv) /**/
    
    1154 1184
     #define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/
    
    ... ... @@ -1177,6 +1207,8 @@ RTS_SYMBOLS_PRIM
    1177 1207
     #undef SymE_NeedsProto
    
    1178 1208
     #undef SymE_NeedsDataProto
    
    1179 1209
     
    
    1210
    +/* See Note [Naming Scheme for Symbol Macros] */
    
    1211
    +
    
    1180 1212
     #define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
    
    1181 1213
                         (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
    
    1182 1214
     #define SymI_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
    
    ... ... @@ -1197,7 +1229,16 @@ RTS_SYMBOLS_PRIM
    1197 1229
         { MAYBE_LEADING_UNDERSCORE_STR(#vvv),    \
    
    1198 1230
           (void*)(&(xxx)), strength, ty },
    
    1199 1231
     
    
    1200
    -RtsSymbolVal rtsSyms[] = {
    
    1232
    +
    
    1233
    +/* Populate the symbol table with stuff from the RTS. */
    
    1234
    +void initLinkerRtsSyms (StrHashTable *symhash) {
    
    1235
    +
    
    1236
    +    /* The address of data symbols with the dllimport attribute are not
    
    1237
    +     * compile-time constants and so cannot be used in constant initialisers.
    
    1238
    +     * For this reason, rtsSyms is a local variable within this function
    
    1239
    +     * rather than a global constant (as it was historically).
    
    1240
    +     */
    
    1241
    +    const RtsSymbolVal rtsSyms[] = {
    
    1201 1242
           RTS_SYMBOLS
    
    1202 1243
           RTS_RET_SYMBOLS
    
    1203 1244
           RTS_POSIX_ONLY_SYMBOLS
    
    ... ... @@ -1212,7 +1253,19 @@ RtsSymbolVal rtsSyms[] = {
    1212 1253
           RTS_SYMBOLS_PRIM
    
    1213 1254
           SymI_HasDataProto(nonmoving_write_barrier_enabled)
    
    1214 1255
           { 0, 0, STRENGTH_NORMAL, SYM_TYPE_CODE } /* sentinel */
    
    1215
    -};
    
    1256
    +    };
    
    1257
    +
    
    1258
    +    IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
    
    1259
    +    for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
    
    1260
    +        IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
    
    1261
    +        if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
    
    1262
    +                                    symhash, sym->lbl, sym->addr,
    
    1263
    +                                    sym->strength, sym->type, 0, NULL)) {
    
    1264
    +            barf("ghciInsertSymbolTable failed");
    
    1265
    +        }
    
    1266
    +    }
    
    1267
    +    IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
    
    1268
    +}
    
    1216 1269
     
    
    1217 1270
     
    
    1218 1271
     // Note [Extra RTS symbols]
    

  • rts/RtsSymbols.h
    ... ... @@ -9,6 +9,7 @@
    9 9
     #pragma once
    
    10 10
     
    
    11 11
     #include "ghcautoconf.h"
    
    12
    +#include "Hash.h"
    
    12 13
     
    
    13 14
     #if defined(LEADING_UNDERSCORE)
    
    14 15
     #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
    
    ... ... @@ -46,7 +47,7 @@ typedef struct _RtsSymbolVal {
    46 47
         SymType type;
    
    47 48
     } RtsSymbolVal;
    
    48 49
     
    
    49
    -extern RtsSymbolVal rtsSyms[];
    
    50
    +void initLinkerRtsSyms (StrHashTable *symhash);
    
    50 51
     
    
    51 52
     extern RtsSymbolVal* __attribute__((weak)) rtsExtraSyms(void);
    
    52 53