[Git][ghc/ghc][wip/bump-win32-tarballs] 9 commits: Hadrian: correctly detect AR at-file support

Matthew Pickering (@mpickering) gitlab at gitlab.haskell.org
Thu Jan 26 12:03:14 UTC 2023



Matthew Pickering pushed to branch wip/bump-win32-tarballs at Glasgow Haskell Compiler / GHC


Commits:
e987e345 by Sylvain Henry at 2023-01-25T14:47:41-05:00
Hadrian: correctly detect AR at-file support

Stage0's ar may not support at-files. Take it into account.

Found while cross-compiling from Darwin to Windows.

- - - - -
48131ee2 by Sylvain Henry at 2023-01-25T14:47:41-05:00
Hadrian: fix Windows cross-compilation

Decision to build either unix or Win32 package must be stage specific
for cross-compilation to be supported.

- - - - -
288fa017 by Sylvain Henry at 2023-01-25T14:47:41-05:00
Fix RTS build on Windows

This change fixes a cross-compilation issue from ArchLinux to Windows
because these symbols weren't found.

- - - - -
2fdf22ae by Sylvain Henry at 2023-01-25T14:47:41-05:00
configure: support "windows" as an OS

- - - - -
13a0566b by Simon Peyton Jones at 2023-01-25T14:48:16-05:00
Fix in-scope set in specImports

Nothing deep here; I had failed to bring some
floated dictionary binders into scope.

Exposed by -fspecialise-aggressively

Fixes #22715.

- - - - -
b7efdb24 by Matthew Pickering at 2023-01-25T14:48:51-05:00
ci: Disable HLint job due to excessive runtime

The HLint jobs takes much longer to run (20 minutes) after "Give the RTS it's own configure script" eb5a6b91

Now the CI job will build the stage0 compiler before it generates the necessary RTS headers.

We either need to:

* Fix the linting rules so they take much less time
* Revert the commit
* Remove the linting of base from the hlint job
* Remove the hlint job

This is highest priority as it is affecting all CI pipelines.

For now I am just disabling the job because there are many more pressing
matters at hand.

Ticket #22830

- - - - -
ae72228c by Ryan Scott at 2023-01-26T12:02:33+00:00
Windows: Remove mingwex dependency

The clang based toolchain uses ucrt as its math library
and so mingwex is no longer needed.  In fact using mingwex
will cause incompatibilities as the default routines in both
have differing ULPs and string formatting modifiers.

```
$ LIBRARY_PATH=/mingw64/lib ghc/_build/stage1/bin/ghc Bug.hs -fforce-recomp && ./Bug.exe
[1 of 2] Compiling Main             ( Bug.hs, Bug.o )
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__imp___p__environ'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `__hscore_get_errno'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziError_errnoToIOError_info'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziWindows_failIf2_closure'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePageziAPI_mkCodePageEncoding_info'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncodingziCodePage_currentCodePage_closure'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziEncoding_getForeignEncoding_closure'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_ForeignziCziString_withCStringLen1_info'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziInternals_zdwflushCharReadBuffer_info'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziIOziHandleziText_hGetBuf1_info'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziFingerprint_fingerprintString_closure'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_DataziTypeableziInternal_mkTrCon_closure'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziException_errorCallWithCallStackException_closure'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\base-4.17.0.0\libHSbase-4.17.0.0.a: unknown symbol `base_GHCziErr_error_info'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `base_DataziMaybe_fromJust1_info'
ghc.exe:  | C:\Users\winferno\Software\ghc\_build\stage1\lib\x86_64-windows-ghc-9.5.20220908\template-haskell-2.19.0.0\libHStemplate-haskell-2.19.0.0.a: unknown symbol `templatezmhaskell_LanguageziHaskellziTHziSyntax_IntPrimL_con_info'
ghc.exe: ^^ Could not load 'templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure', dependency unresolved. See top entry above.

<no location info>: error:

GHC.ByteCode.Linker.lookupCE
During interactive linking, GHCi couldn't find the following symbol:
  templatezmhaskell_LanguageziHaskellziTHziLibziInternal_stringL_closure
This may be due to you not asking GHCi to load extra object files,
archives or DLLs needed by your current session.  Restart GHCi, specifying
the missing library using the -L/path/to/object/dir and -lmissinglibname
flags, or simply by naming the relevant files on the GHCi command line.
Alternatively, this link failure might indicate a bug in GHCi.
If you suspect the latter, please report this as a GHC bug:
  https://www.haskell.org/ghc/reportabug
```

- - - - -
f8d7773e by Tamar Christina at 2023-01-26T12:02:35+00:00
linker: Fix BFD import libraries

This commit fixes the BFD style import library support in the runtime
linker.  This was accidentally broken during the refactoring to clang
and went unnoticed because clang itself is unable to generate the BFD
style import libraries.

With this change we can not link against both GCC or Clang produced
libraries again and intermix code produced by both compilers.

- - - - -
9f5971c3 by Ben Gamari at 2023-01-26T12:02:35+00:00
Bump Windows toolchain

Updates to LLVM 14, hopefully fixing #21964.

- - - - -


30 changed files:

- .gitlab-ci.yml
- compiler/GHC/Core/Opt/Specialise.hs
- configure.ac
- hadrian/cfg/system.config.in
- hadrian/src/Builder.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- libraries/base/System/Posix/Internals.hs
- libraries/base/base.cabal
- libraries/base/configure.ac
- libraries/base/include/HsBase.h
- libraries/ghc-prim/ghc-prim.cabal
- m4/fptools_set_haskell_platform_vars.m4
- m4/ghc_convert_os.m4
- mk/get-win32-tarballs.py
- rts/Linker.c
- rts/LinkerInternals.h
- rts/RtsSymbols.c
- rts/linker/PEi386.c
- rts/rts.cabal.in
- testsuite/tests/ghci/linking/dyn/Makefile
- testsuite/tests/ghci/linking/dyn/all.T
- + testsuite/tests/ghci/linking/dyn/bin_impl_gcc/ASimpL.dll
- + testsuite/tests/ghci/linking/dyn/bin_impl_gcc/libASx.dll.a
- testsuite/tests/rts/all.T
- + testsuite/tests/simplCore/should_compile/T22715_2.hs
- + testsuite/tests/simplCore/should_compile/T22715_2a.hs
- testsuite/tests/simplCore/should_compile/all.T


Changes:

=====================================
.gitlab-ci.yml
=====================================
@@ -6,7 +6,7 @@ variables:
 
   # Sequential version number of all cached things.
   # Bump to invalidate GitLab CI cache.
-  CACHE_REV: 9
+  CACHE_REV: 10
 
   # Disable shallow clones; they break our linting rules
   GIT_DEPTH: 0
@@ -329,7 +329,8 @@ lint-submods-branch:
     paths:
       - cabal-cache
 
-hlint-ghc-and-base:
+# Disabled due to #22830
+.hlint-ghc-and-base:
   extends: .lint-params
   image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV"
   variables:


=====================================
compiler/GHC/Core/Opt/Specialise.hs
=====================================
@@ -33,6 +33,7 @@ import GHC.Core.Utils     ( exprIsTrivial
 import GHC.Core.FVs
 import GHC.Core.TyCo.FVs ( tyCoVarsOfTypeList )
 import GHC.Core.Opt.Arity( collectBindersPushingCo )
+-- import GHC.Core.Ppr( pprIds )
 
 import GHC.Builtin.Types  ( unboxedUnitTy )
 
@@ -736,7 +737,8 @@ specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls })
   = return ([], wrapDictBinds dict_binds [])
 
   | otherwise
-  = do { (_env, spec_rules, spec_binds) <- spec_imports top_env [] dict_binds calls
+  = do { let env_w_dict_bndrs = top_env `bringFloatedDictsIntoScope` dict_binds
+       ; (_env, spec_rules, spec_binds) <- spec_imports env_w_dict_bndrs [] dict_binds calls
 
              -- Don't forget to wrap the specialized bindings with
              -- bindings for the needed dictionaries.
@@ -752,6 +754,7 @@ specImports top_env (MkUD { ud_binds = dict_binds, ud_calls = calls })
 
 -- | Specialise a set of calls to imported bindings
 spec_imports :: SpecEnv          -- Passed in so that all top-level Ids are in scope
+                                 ---In-scope set includes the FloatedDictBinds
              -> [Id]             -- Stack of imported functions being specialised
                                  -- See Note [specImport call stack]
              -> FloatedDictBinds -- Dict bindings, used /only/ for filterCalls
@@ -781,6 +784,7 @@ spec_imports env callers dict_binds calls
            ; return (env, rules1 ++ rules2, spec_binds1 ++ spec_binds2) }
 
 spec_import :: SpecEnv               -- Passed in so that all top-level Ids are in scope
+                                     ---In-scope set includes the FloatedDictBinds
             -> [Id]                  -- Stack of imported functions being specialised
                                      -- See Note [specImport call stack]
             -> FloatedDictBinds      -- Dict bindings, used /only/ for filterCalls
@@ -806,23 +810,35 @@ spec_import env callers dict_binds cis@(CIS fn _)
        ; eps_rules <- getExternalRuleBase
        ; let rule_env = se_rules env `updExternalPackageRules` eps_rules
 
---       ; debugTraceMsg (text "specImport1" <+> vcat [ppr fn, ppr good_calls
---                                                    , ppr (getRules rule_env fn), ppr rhs])
+--       ; debugTraceMsg (text "specImport1" <+> vcat
+--           [ text "function:" <+> ppr fn
+--           , text "good calls:" <+> ppr good_calls
+--           , text "existing rules:" <+> ppr (getRules rule_env fn)
+--           , text "rhs:" <+> ppr rhs
+--           , text "dict_binds:" <+> ppr dict_binds ])
+
        ; (rules1, spec_pairs, MkUD { ud_binds = dict_binds1, ud_calls = new_calls })
-            <- runSpecM $ specCalls True env dict_binds
-                                    (getRules rule_env fn) good_calls fn rhs
+            <- runSpecM $ specCalls True env (getRules rule_env fn) good_calls fn rhs
 
        ; let spec_binds1 = [NonRec b r | (b,r) <- spec_pairs]
-             -- After the rules kick in we may get recursion, but
-             -- we rely on a global GlomBinds to sort that out later
+             -- After the rules kick in, via fireRewriteRules, we may get recursion,
+             -- but we rely on a global GlomBinds to sort that out later
              -- See Note [Glom the bindings if imported functions are specialised]
+             -- Meanwhile, though, bring the binders into scope
 
              new_subst = se_subst env `Core.extendSubstInScopeList` map fst spec_pairs
              new_env   = env { se_rules = rule_env `addLocalRules` rules1
                              , se_subst = new_subst }
+                         `bringFloatedDictsIntoScope` dict_binds1
+
+       -- Now specialise any cascaded calls
+--       ; debugTraceMsg (text "specImport 2" <+> vcat
+--           [ text "function:" <+> ppr fn
+--           , text "rules1:" <+> ppr rules1
+--           , text "spec_binds1" <+> ppr spec_binds1
+--           , text "dict_binds1" <+> ppr dict_binds1
+--           , text "new_calls" <+> ppr new_calls ])
 
-              -- Now specialise any cascaded calls
---       ; debugTraceMsg (text "specImport 2" <+> (ppr fn $$ ppr rules1 $$ ppr spec_binds1))
        ; (env, rules2, spec_binds2)
             <- spec_imports new_env (fn:callers)
                                     (dict_binds `thenFDBs` dict_binds1)
@@ -1561,10 +1577,11 @@ specDefn :: SpecEnv
 specDefn env body_uds fn rhs
   = do { let (body_uds_without_me, calls_for_me) = callsForMe fn body_uds
              rules_for_me = idCoreRules fn
-             dict_binds   = ud_binds body_uds
+             -- Bring into scope the binders from the floated dicts
+             env_w_dict_bndrs = bringFloatedDictsIntoScope env (ud_binds body_uds)
 
-       ; (rules, spec_defns, spec_uds) <- specCalls False env dict_binds
-                                               rules_for_me calls_for_me fn rhs
+       ; (rules, spec_defns, spec_uds) <- specCalls False env_w_dict_bndrs
+                                                    rules_for_me calls_for_me fn rhs
 
        ; return ( fn `addIdSpecialisations` rules
                 , spec_defns
@@ -1580,7 +1597,6 @@ specDefn env body_uds fn rhs
 specCalls :: Bool              -- True  =>  specialising imported fn
                                -- False =>  specialising local fn
           -> SpecEnv
-          -> FloatedDictBinds  -- Just so that we can extend the in-scope set
           -> [CoreRule]        -- Existing RULES for the fn
           -> [CallInfo]
           -> OutId -> InExpr
@@ -1594,7 +1610,7 @@ type SpecInfo = ( [CoreRule]       -- Specialisation rules
                 , [(Id,CoreExpr)]  -- Specialised definition
                 , UsageDetails )   -- Usage details from specialised RHSs
 
-specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs
+specCalls spec_imp env existing_rules calls_for_me fn rhs
         -- The first case is the interesting one
   |  notNull calls_for_me               -- And there are some calls to specialise
   && not (isNeverActive (idInlineActivation fn))
@@ -1610,8 +1626,11 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs
 --      See Note [Inline specialisations] for why we do not
 --      switch off specialisation for inline functions
 
-  = -- pprTrace "specCalls: some" (ppr fn $$ ppr calls_for_me $$ ppr existing_rules) $
-    foldlM spec_call ([], [], emptyUDs) calls_for_me
+  = do { -- debugTraceMsg (text "specCalls: some" <+> vcat
+         --   [ text "function" <+> ppr fn
+         --   , text "calls:" <+> ppr calls_for_me
+         --   , text "subst" <+> ppr (se_subst env) ])
+       ; foldlM spec_call ([], [], emptyUDs) calls_for_me }
 
   | otherwise   -- No calls or RHS doesn't fit our preconceptions
   = warnPprTrace (not (exprIsTrivial rhs) && notNull calls_for_me && not (isClassOpId fn))
@@ -1639,9 +1658,6 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs
     (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs
                             -- See Note [Account for casts in binding]
 
-    -- Bring into scope the binders from the floated dicts
-    env_with_dict_bndrs = bringFloatedDictsIntoScope env dict_binds
-
     already_covered :: SpecEnv -> [CoreRule] -> [CoreExpr] -> Bool
     already_covered env new_rules args      -- Note [Specialisations already covered]
        = isJust (specLookupRule env fn args (beginPhase inl_act)
@@ -1667,22 +1683,22 @@ specCalls spec_imp env dict_binds existing_rules calls_for_me fn rhs
 
            ; ( useful, rhs_env2, leftover_bndrs
              , rule_bndrs, rule_lhs_args
-             , spec_bndrs1, dx_binds, spec_args) <- specHeader env_with_dict_bndrs
-                                                               rhs_bndrs all_call_args
-
---           ; pprTrace "spec_call" (vcat [ text "fun:       "  <+> ppr fn
---                                        , text "call info: "  <+> ppr _ci
---                                        , text "useful:    "  <+> ppr useful
---                                        , text "rule_bndrs:"  <+> ppr rule_bndrs
---                                        , text "lhs_args:  "  <+> ppr rule_lhs_args
---                                        , text "spec_bndrs1:" <+> ppr spec_bndrs1
---                                        , text "leftover_bndrs:" <+> pprIds leftover_bndrs
---                                        , text "spec_args: "  <+> ppr spec_args
---                                        , text "dx_binds:  "  <+> ppr dx_binds
---                                        , text "rhs_body"     <+> ppr rhs_body
---                                        , text "rhs_env2:  "  <+> ppr (se_subst rhs_env2)
---                                        , ppr dx_binds ]) $
---             return ()
+             , spec_bndrs1, dx_binds, spec_args) <- specHeader env rhs_bndrs all_call_args
+
+--           ; debugTraceMsg (text "spec_call" <+> vcat
+--                [ text "fun:       "  <+> ppr fn
+--                , text "call info: "  <+> ppr _ci
+--                , text "useful:    "  <+> ppr useful
+--                , text "rule_bndrs:"  <+> ppr rule_bndrs
+--                , text "lhs_args:  "  <+> ppr rule_lhs_args
+--                , text "spec_bndrs1:" <+> ppr spec_bndrs1
+--                , text "leftover_bndrs:" <+> pprIds leftover_bndrs
+--                , text "spec_args: "  <+> ppr spec_args
+--                , text "dx_binds:  "  <+> ppr dx_binds
+--                , text "rhs_bndrs"     <+> ppr rhs_bndrs
+--                , text "rhs_body"     <+> ppr rhs_body
+--                , text "rhs_env2:  "  <+> ppr (se_subst rhs_env2)
+--                , ppr dx_binds ]
 
            ; if not useful  -- No useful specialisation
                 || already_covered rhs_env2 rules_acc rule_lhs_args


=====================================
configure.ac
=====================================
@@ -934,17 +934,6 @@ AC_CHECK_DECLS([program_invocation_short_name], , ,
 [#define _GNU_SOURCE 1
 #include <errno.h>])
 
-dnl ** check for mingwex library
-AC_CHECK_LIB(
-  [mingwex],
-  [closedir],
-  [AC_SUBST([HaveLibMingwEx],[YES])] [AC_SUBST([CabalMingwex],[True])],
-  [AC_SUBST([HaveLibMingwEx],[NO])] [AC_SUBST([CabalMingwex],[False])])
-
-if test $HaveLibMingwEx = YES ; then
-  AC_DEFINE([HAVE_MINGWEX], [1], [Define to 1 if you have the mingwex library.])
-fi
-
 dnl ** check for math library
 dnl    Keep that check as early as possible.
 dnl    as we need to know whether we need libm


=====================================
hadrian/cfg/system.config.in
=====================================
@@ -40,6 +40,7 @@ python         = @PythonCmd@
 #============================
 
 ar-supports-at-file       = @ArSupportsAtFile@
+system-ar-supports-at-file = @ArSupportsAtFile_STAGE0@
 ar-supports-dash-l        = @ArSupportsDashL@
 system-ar-supports-dash-l = @ArSupportsDashL_STAGE0@
 cc-llvm-backend           = @CcLlvmBackend@
@@ -204,7 +205,6 @@ libnuma-lib-dir       = @LibNumaLibDir@
 
 use-lib-dw        = @UseLibdw@
 use-lib-numa      = @UseLibNuma@
-use-lib-mingw-ex  = @HaveLibMingwEx@
 use-lib-m         = @UseLibm@
 use-lib-rt        = @UseLibrt@
 use-lib-dl        = @UseLibdl@


=====================================
hadrian/src/Builder.hs
=====================================
@@ -312,8 +312,8 @@ instance H.Builder Builder where
                     -- see Note [Capture stdout as a ByteString]
                     writeFileChangedBS output stdout
             case builder of
-                Ar Pack _ -> do
-                    useTempFile <- flag ArSupportsAtFile
+                Ar Pack stg -> do
+                    useTempFile <- arSupportsAtFile stg
                     if useTempFile then runAr                path buildArgs buildInputs
                                    else runArWithoutTempFile path buildArgs buildInputs
 


=====================================
hadrian/src/Oracles/Flag.hs
=====================================
@@ -7,7 +7,8 @@ module Oracles.Flag (
     targetSupportsThreadedRts,
     targetSupportsSMP,
     useLibffiForAdjustors,
-    arSupportsDashL
+    arSupportsDashL,
+    arSupportsAtFile
     ) where
 
 import Hadrian.Oracles.TextFile
@@ -18,6 +19,7 @@ import Oracles.Setting
 
 data Flag = ArSupportsAtFile
           | ArSupportsDashL
+          | SystemArSupportsAtFile
           | SystemArSupportsDashL
           | CrossCompiling
           | CcLlvmBackend
@@ -33,7 +35,6 @@ data Flag = ArSupportsAtFile
           | UseLibffiForAdjustors
           | UseLibdw
           | UseLibnuma
-          | UseLibmingwex
           | UseLibm
           | UseLibrt
           | UseLibdl
@@ -48,6 +49,7 @@ flag f = do
     let key = case f of
             ArSupportsAtFile     -> "ar-supports-at-file"
             ArSupportsDashL      -> "ar-supports-dash-l"
+            SystemArSupportsAtFile-> "system-ar-supports-at-file"
             SystemArSupportsDashL-> "system-ar-supports-dash-l"
             CrossCompiling       -> "cross-compiling"
             CcLlvmBackend        -> "cc-llvm-backend"
@@ -63,7 +65,6 @@ flag f = do
             UseLibffiForAdjustors -> "use-libffi-for-adjustors"
             UseLibdw             -> "use-lib-dw"
             UseLibnuma           -> "use-lib-numa"
-            UseLibmingwex        -> "use-lib-mingw-ex"
             UseLibm              -> "use-lib-m"
             UseLibrt             -> "use-lib-rt"
             UseLibdl             -> "use-lib-dl"
@@ -89,6 +90,10 @@ arSupportsDashL :: Stage -> Action Bool
 arSupportsDashL (Stage0 {}) = flag SystemArSupportsDashL
 arSupportsDashL _           = flag ArSupportsDashL
 
+arSupportsAtFile :: Stage -> Action Bool
+arSupportsAtFile (Stage0 {}) = flag SystemArSupportsAtFile
+arSupportsAtFile _           = flag ArSupportsAtFile
+
 platformSupportsSharedLibs :: Action Bool
 platformSupportsSharedLibs = do
     windows       <- isWinTarget


=====================================
hadrian/src/Rules/Generate.hs
=====================================
@@ -267,7 +267,6 @@ templateRules = do
     target_word_size       <- settingWord TargetWordSize
     lib_dw                 <- flag UseLibdw
     lib_numa               <- flag UseLibnuma
-    lib_mingwex            <- flag UseLibmingwex
     lib_m                  <- flag UseLibm
     lib_rt                 <- flag UseLibrt
     lib_dl                 <- flag UseLibdl
@@ -284,7 +283,6 @@ templateRules = do
         subst = replace "@ProjectVersion@" project_version
                 . replace "@ProjectVersionMunged@" project_version_munged
                 . replace "@Cabal64bit@" (cabal_bool (target_word_size == 8))
-                . replace "@CabalMingwex@" (cabal_bool lib_mingwex)
                 . replace "@CabalHaveLibdw@" (cabal_bool lib_dw)
                 . replace "@CabalHaveLibm@" (cabal_bool lib_m)
                 . replace "@CabalHaveLibrt@" (cabal_bool lib_rt)


=====================================
hadrian/src/Settings/Default.hs
=====================================
@@ -72,7 +72,6 @@ stageBootPackages = return [lintersCommon, lintCommitMsg, lintSubmoduleRefs, lin
 stage0Packages :: Action [Package]
 stage0Packages = do
     cross <- flag CrossCompiling
-    winTarget  <- isWinTarget
     return $ [ binary
              , bytestring
              , cabalSyntax
@@ -102,7 +101,7 @@ stage0Packages = do
              , transformers
              , unlit
              , hp2ps
-             , if winTarget then win32 else unix
+             , if windowsHost then win32 else unix
              ]
           ++ [ terminfo | not windowsHost, not cross ]
           ++ [ timeout  | windowsHost                ]
@@ -111,7 +110,15 @@ stage0Packages = do
 -- | Packages built in 'Stage1' by default. You can change this in "UserSettings".
 stage1Packages :: Action [Package]
 stage1Packages = do
-    libraries0 <- filter isLibrary <$> stage0Packages
+    let good_stage0_package p
+          -- we only keep libraries for some reason
+          | not (isLibrary p) = False
+          -- but not win32/unix because it depends on cross-compilation target
+          | p == win32        = False
+          | p == unix         = False
+          | otherwise         = True
+
+    libraries0 <- filter good_stage0_package <$> stage0Packages
     cross      <- flag CrossCompiling
     winTarget  <- isWinTarget
 
@@ -138,6 +145,7 @@ stage1Packages = do
         , stm
         , unlit
         , xhtml
+        , if winTarget then win32 else unix
         ]
       , when (not cross)
         [ haddock


=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -403,8 +403,7 @@ rtsPackageArgs = package rts ? do
         , builder HsCpp ? pure
           [ "-DTOP="             ++ show top ]
 
-        , builder HsCpp ? flag UseLibdw ? arg "-DUSE_LIBDW"
-        , builder HsCpp ? flag UseLibmingwex ? arg "-DHAVE_LIBMINGWEX" ]
+        , builder HsCpp ? flag UseLibdw ? arg "-DUSE_LIBDW" ]
 
 -- Compile various performance-critical pieces *without* -fPIC -dynamic
 -- even when building a shared library.  If we don't do this, then the


=====================================
libraries/base/System/Posix/Internals.hs
=====================================
@@ -452,7 +452,6 @@ foreign import ccall unsafe "HsBase.h __hscore_fstat"
 
 foreign import ccall unsafe "HsBase.h __hscore_lstat"
    lstat :: CFilePath -> Ptr CStat -> IO CInt
-
 #endif
 
 #if defined(js_HOST_ARCH)
@@ -592,109 +591,95 @@ foreign import javascript unsafe "(($1,$2,$3_1,$3_2) => { return h$base_c_fcntl_
 
 #else
 
-{- Note: Win32 POSIX functions
-Functions that are not part of the POSIX standards were
-at some point deprecated by Microsoft. This deprecation
-was performed by renaming the functions according to the
-C++ ABI Section 17.6.4.3.2b. This was done to free up the
-namespace of normal Windows programs since Windows isn't
-POSIX compliant anyway.
+#if defined(mingw32_HOST_OS)
+-- See Note [Windows types]
+foreign import capi unsafe "HsBase.h _read"
+   c_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt
 
-These were working before since the RTS was re-exporting
-these symbols under the undeprecated names. This is no longer
-being done. See #11223
+-- See Note [Windows types]
+foreign import capi safe "HsBase.h _read"
+   c_safe_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt
 
-See https://msdn.microsoft.com/en-us/library/ms235384.aspx
-for more.
+foreign import ccall unsafe "HsBase.h _umask"
+   c_umask :: CMode -> IO CMode
 
-However since we can't hope to get people to support Windows
-packages we should support the deprecated names. See #12497
--}
-foreign import capi unsafe "unistd.h lseek"
-   c_lseek :: CInt -> COff -> CInt -> IO COff
+-- See Note [Windows types]
+foreign import capi unsafe "HsBase.h _write"
+   c_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt
 
-foreign import ccall unsafe "HsBase.h access"
+-- See Note [Windows types]
+foreign import capi safe "HsBase.h _write"
+   c_safe_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt
+
+foreign import ccall unsafe "HsBase.h _pipe"
+   c_pipe :: Ptr CInt -> IO CInt
+
+foreign import capi unsafe "HsBase.h _lseeki64"
+   c_lseek :: CInt -> Int64 -> CInt -> IO Int64
+
+foreign import capi unsafe "HsBase.h _access"
    c_access :: CString -> CInt -> IO CInt
 
 #if !defined(HAVE_CHMOD)
 c_chmod :: CString -> CMode -> IO CInt
-c_chmod _ _ = ioError (ioeSetLocation unsupportedOperation "chmod")
+c_chmod _ _ = ioError (ioeSetLocation unsupportedOperation "_chmod")
 #else
-foreign import ccall unsafe "HsBase.h chmod"
+foreign import ccall unsafe "HsBase.h _chmod"
    c_chmod :: CString -> CMode -> IO CInt
 #endif
 
-foreign import ccall unsafe "HsBase.h close"
+foreign import capi unsafe "HsBase.h _close"
    c_close :: CInt -> IO CInt
 
-foreign import ccall unsafe "HsBase.h creat"
+foreign import capi unsafe "HsBase.h _creat"
    c_creat :: CString -> CMode -> IO CInt
 
 #if !defined(HAVE_DUP)
 c_dup :: CInt -> IO CInt
-c_dup _ = ioError (ioeSetLocation unsupportedOperation "dup")
+c_dup _ = ioError (ioeSetLocation unsupportedOperation "_dup")
 
 c_dup2 :: CInt -> CInt -> IO CInt
-c_dup2 _ _ = ioError (ioeSetLocation unsupportedOperation "dup2")
+c_dup2 _ _ = ioError (ioeSetLocation unsupportedOperation "_dup2")
 #else
-foreign import ccall unsafe "HsBase.h dup"
+foreign import ccall unsafe "HsBase.h _dup"
    c_dup :: CInt -> IO CInt
 
-foreign import ccall unsafe "HsBase.h dup2"
+foreign import ccall unsafe "HsBase.h _dup2"
    c_dup2 :: CInt -> CInt -> IO CInt
 #endif
 
-foreign import ccall unsafe "HsBase.h isatty"
+foreign import capi unsafe "HsBase.h _isatty"
    c_isatty :: CInt -> IO CInt
 
-#if defined(mingw32_HOST_OS)
--- See Note: Windows types
-foreign import capi unsafe "HsBase.h _read"
-   c_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt
-
--- See Note: Windows types
-foreign import capi safe "HsBase.h _read"
-   c_safe_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt
-
-foreign import ccall unsafe "HsBase.h _umask"
-   c_umask :: CMode -> IO CMode
-
--- See Note: Windows types
-foreign import capi unsafe "HsBase.h _write"
-   c_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt
+foreign import capi unsafe "HsBase.h _unlink"
+   c_unlink :: CString -> IO CInt
 
--- See Note: Windows types
-foreign import capi safe "HsBase.h _write"
-   c_safe_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt
+foreign import capi unsafe "HsBase.h _utime"
+   c_utime :: CString -> Ptr CUtimbuf -> IO CInt
 
-foreign import ccall unsafe "HsBase.h _pipe"
-   c_pipe :: Ptr CInt -> IO CInt
+foreign import capi unsafe "HsBase.h _getpid"
+   c_getpid :: IO CPid
 #else
 -- We use CAPI as on some OSs (eg. Linux) this is wrapped by a macro
 -- which redirects to the 64-bit-off_t versions when large file
 -- support is enabled.
 
--- See Note: Windows types
+-- See Note [Windows types]
 foreign import capi unsafe "HsBase.h read"
    c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize
 
--- See Note: Windows types
+-- See Note [Windows types]
 foreign import capi safe "HsBase.h read"
    c_safe_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize
 
-#if defined(HAVE_UMASK)
 foreign import ccall unsafe "HsBase.h umask"
    c_umask :: CMode -> IO CMode
-#else
-c_umask :: CMode -> IO CMode
-c_umask _ = ioError (ioeSetLocation unsupportedOperation "umask")
-#endif
 
--- See Note: Windows types
+-- See Note [Windows types]
 foreign import capi unsafe "HsBase.h write"
    c_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize
 
--- See Note: Windows types
+-- See Note [Windows types]
 foreign import capi safe "HsBase.h write"
    c_safe_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize
 
@@ -705,8 +690,44 @@ c_pipe _ = ioError (ioeSetLocation unsupportedOperation "pipe")
 foreign import ccall unsafe "HsBase.h pipe"
    c_pipe :: Ptr CInt -> IO CInt
 #endif
+
+foreign import capi unsafe "unistd.h lseek"
+   c_lseek :: CInt -> COff -> CInt -> IO COff
+
+foreign import ccall unsafe "HsBase.h access"
+   c_access :: CString -> CInt -> IO CInt
+
+#if !defined(HAVE_CHMOD)
+c_chmod :: CString -> CMode -> IO CInt
+c_chmod _ _ = ioError (ioeSetLocation unsupportedOperation "chmod")
+#else
+foreign import ccall unsafe "HsBase.h chmod"
+   c_chmod :: CString -> CMode -> IO CInt
+#endif
+
+foreign import ccall unsafe "HsBase.h close"
+   c_close :: CInt -> IO CInt
+
+foreign import ccall unsafe "HsBase.h creat"
+   c_creat :: CString -> CMode -> IO CInt
+
+#if !defined(HAVE_DUP)
+c_dup :: CInt -> IO CInt
+c_dup _ = ioError (ioeSetLocation unsupportedOperation "dup")
+
+c_dup2 :: CInt -> CInt -> IO CInt
+c_dup2 _ _ = ioError (ioeSetLocation unsupportedOperation "dup2")
+#else
+foreign import ccall unsafe "HsBase.h dup"
+   c_dup :: CInt -> IO CInt
+
+foreign import ccall unsafe "HsBase.h dup2"
+   c_dup2 :: CInt -> CInt -> IO CInt
 #endif
 
+foreign import ccall unsafe "HsBase.h isatty"
+   c_isatty :: CInt -> IO CInt
+
 foreign import ccall unsafe "HsBase.h unlink"
    c_unlink :: CString -> IO CInt
 
@@ -720,6 +741,7 @@ c_getpid = pure 1
 foreign import ccall unsafe "HsBase.h getpid"
    c_getpid :: IO CPid
 #endif
+#endif
 
 #if !defined(js_HOST_ARCH)
 foreign import ccall unsafe "HsBase.h __hscore_stat"
@@ -881,7 +903,8 @@ foreign import capi  unsafe "stdio.h value SEEK_END" sEEK_END :: CInt
 #endif
 
 {-
-Note: Windows types
+Note [Windows types]
+~~~~~~~~~~~~~~~~~~~~
 
 Windows' _read and _write have types that differ from POSIX. They take an
 unsigned int for length and return a signed int where POSIX uses size_t and


=====================================
libraries/base/base.cabal
=====================================
@@ -396,7 +396,6 @@ Library
     if os(windows)
         -- Windows requires some extra libraries for linking because the RTS
         -- is no longer re-exporting them.
-        -- mingwex: provides C99 compatibility. libm is a stub on MingW.
         -- mingw32: Unfortunately required because of a resource leak between
         --          mingwex and mingw32. the __math_err symbol is defined in
         --          mingw32 which is required by mingwex.
@@ -409,7 +408,7 @@ Library
         -- advapi32: provides advanced kernel functions
         extra-libraries:
             wsock32, user32, shell32, mingw32, kernel32, advapi32,
-            mingwex, ws2_32, shlwapi, ole32, rpcrt4, ntdll
+            ws2_32, shlwapi, ole32, rpcrt4, ntdll
         -- Minimum supported Windows version.
         -- These numbers can be found at:
         --  https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx


=====================================
libraries/base/configure.ac
=====================================
@@ -39,7 +39,7 @@ AC_CHECK_LIB([rt], [clock_gettime])
 AC_CHECK_FUNCS([clock_gettime])
 AC_CHECK_DECLS([CLOCK_PROCESS_CPUTIME_ID], [], [], [[#include <time.h>]])
 AC_CHECK_FUNCS([getclock getrusage times])
-AC_CHECK_FUNCS([_chsize ftruncate])
+AC_CHECK_FUNCS([_chsize_s ftruncate])
 
 # event-related fun
 # The line below already defines HAVE_KQUEUE and HAVE_POLL, so technically some of the


=====================================
libraries/base/include/HsBase.h
=====================================
@@ -280,15 +280,12 @@ __hscore_o_nonblock( void )
 INLINE int
 __hscore_ftruncate( int fd, off_t where )
 {
-#if defined(HAVE_FTRUNCATE)
+#if defined(HAVE__CHSIZE_S)
+  return _chsize_s(fd,where);
+#elif defined(HAVE_FTRUNCATE)
   return ftruncate(fd,where);
-#elif defined(HAVE__CHSIZE)
-  return _chsize(fd,where);
 #else
-// ToDo: we should use _chsize_s() on Windows which allows a 64-bit
-// offset, but it doesn't seem to be available from mingw at this time
-// --SDM (01/2008)
-#error at least ftruncate or _chsize functions are required to build
+#error at least _chsize_s or ftruncate functions are required to build
 #endif
 }
 


=====================================
libraries/ghc-prim/ghc-prim.cabal
=====================================
@@ -66,15 +66,14 @@ Library
     if os(windows)
         -- Windows requires some extra libraries for linking because the RTS
         -- is no longer re-exporting them (see #11223)
-        -- msvcrt: standard C library. The RTS will automatically include this,
-        --         but is added for completeness.
-        -- mingwex: provides C99 compatibility. libm is a stub on MingW.
+        -- ucrt: standard C library. The RTS will automatically include this,
+        --       but is added for completeness.
         -- mingw32: Unfortunately required because of a resource leak between
         --          mingwex and mingw32. the __math_err symbol is defined in
         --          mingw32 which is required by mingwex.
         -- user32: provides access to apis to modify user components (UI etc)
         --         on Windows. Required because of mingw32.
-        extra-libraries: user32, mingw32, mingwex, ucrt
+        extra-libraries: user32, mingw32, ucrt
 
     if os(linux)
         -- we need libm, but for musl and other's we might need libc, as libm


=====================================
m4/fptools_set_haskell_platform_vars.m4
=====================================
@@ -82,7 +82,7 @@ AC_DEFUN([FPTOOLS_SET_HASKELL_PLATFORM_VARS_SHELL_FUNCTIONS],
         solaris2)
             test -z "[$]2" || eval "[$]2=OSSolaris2"
             ;;
-        mingw32)
+        mingw32|windows)
             test -z "[$]2" || eval "[$]2=OSMinGW32"
             ;;
         freebsd)


=====================================
m4/ghc_convert_os.m4
=====================================
@@ -22,8 +22,11 @@ AC_DEFUN([GHC_CONVERT_OS],[
       openbsd*)
         $3="openbsd"
         ;;
+      windows|mingw32)
+        $3="mingw32"
+        ;;
       # As far as I'm aware, none of these have relevant variants
-      freebsd|dragonfly|hpux|linuxaout|kfreebsdgnu|freebsd2|mingw32|darwin|nextstep2|nextstep3|sunos4|ultrix|haiku)
+      freebsd|dragonfly|hpux|linuxaout|kfreebsdgnu|freebsd2|darwin|nextstep2|nextstep3|sunos4|ultrix|haiku)
         $3="$1"
         ;;
       msys)


=====================================
mk/get-win32-tarballs.py
=====================================
@@ -8,7 +8,7 @@ import argparse
 import sys
 from sys import stderr
 
-TARBALL_VERSION = '0.7'
+TARBALL_VERSION = '0.8'
 BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION)
 DEST = Path('ghc-tarballs/mingw-w64')
 ARCHS = ['x86_64', 'sources']


=====================================
rts/Linker.c
=====================================
@@ -135,7 +135,7 @@ extern void iconv();
    This is to enable lazy loading of symbols. Eager loading is problematic
    as it means that all symbols must be available, even those which we will
    never use. This is especially painful on Windows, where the number of
-   libraries required to link things like mingwex grows to be quite high.
+   libraries required to link things like QT or WxWidgets grows to be quite high.
 
    We proceed through these stages as follows,
 
@@ -193,7 +193,7 @@ extern void iconv();
 
    1) Dependency chains, if A.o required a .o in libB but A.o isn't required to link
       then we don't need to load libB. This means the dependency chain for libraries
-      such as mingw32 and mingwex can be broken down.
+      such as ucrt can be broken down.
 
    2) The number of duplicate symbols, since now only symbols that are
       true duplicates will display the error.
@@ -226,7 +226,7 @@ static void ghciRemoveSymbolTable(StrHashTable *table, const SymbolName* key,
 static const char *
 symbolTypeString (SymType type)
 {
-    switch (type) {
+    switch (type & ~SYM_TYPE_DUP_DISCARD) {
         case SYM_TYPE_CODE: return "code";
         case SYM_TYPE_DATA: return "data";
         case SYM_TYPE_INDIRECT_DATA: return "indirect-data";
@@ -275,14 +275,18 @@ int ghciInsertSymbolTable(
       insertStrHashTable(table, key, pinfo);
       return 1;
    }
-   else if (pinfo->type != type)
+   else if (pinfo->type ^ type)
    {
-       debugBelch("Symbol type mismatch.\n");
-       debugBelch("Symbol %s was defined by %" PATH_FMT " to be a %s symbol.\n",
-                  key, obj_name, symbolTypeString(type));
-       debugBelch("      yet was defined by %" PATH_FMT " to be a %s symbol.\n",
-                  pinfo->owner ? pinfo->owner->fileName : WSTR("<builtin>"),
-                  symbolTypeString(pinfo->type));
+       /* We were asked to discard the symbol on duplicates, do so quietly.  */
+       if (!(type & SYM_TYPE_DUP_DISCARD))
+       {
+         debugBelch("Symbol type mismatch.\n");
+         debugBelch("Symbol %s was defined by %" PATH_FMT " to be a %s symbol.\n",
+                    key, obj_name, symbolTypeString(type));
+         debugBelch("      yet was defined by %" PATH_FMT " to be a %s symbol.\n",
+                    pinfo->owner ? pinfo->owner->fileName : WSTR("<builtin>"),
+                    symbolTypeString(pinfo->type));
+       }
        return 1;
    }
    else if (pinfo->strength == STRENGTH_STRONG)


=====================================
rts/LinkerInternals.h
=====================================
@@ -54,11 +54,16 @@ typedef struct _Section    Section;
  */
 
 /* What kind of thing a symbol identifies. We need to know this to determine how
- * to process overflowing relocations. See Note [Processing overflowed relocations]. */
+ * to process overflowing relocations. See Note [Processing overflowed relocations].
+ * This is bitfield however only the option SYM_TYPE_DUP_DISCARD can be combined
+ * with the other values. */
 typedef enum _SymType {
-    SYM_TYPE_CODE, /* the symbol is a function and can be relocated via a jump island */
-    SYM_TYPE_DATA, /* the symbol is data */
-    SYM_TYPE_INDIRECT_DATA, /* see Note [_iob_func symbol] */
+    SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */
+    SYM_TYPE_DATA = 1 << 1, /* the symbol is data */
+    SYM_TYPE_INDIRECT_DATA = 1 << 2, /* see Note [_iob_func symbol] */
+    SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library
+                                      however if a duplicate is found with a mismatching
+                                      SymType then discard this one.  */
 } SymType;
 
 


=====================================
rts/RtsSymbols.c
=====================================
@@ -113,26 +113,6 @@ extern char **environ;
  * by the RtsSymbols entry. To avoid this we introduce a horrible special case
  * in `ghciInsertSymbolTable`, ensure that `atexit` is never overridden.
  */
-/*
- * Note [Symbols for MinGW's printf]
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * The printf offered by Microsoft's libc implementation, msvcrt, is quite
- * incomplete, lacking support for even %ull. Consequently mingw-w64 offers its
- * own implementation which we enable. However, to be thread-safe the
- * implementation uses _lock_file. This would be fine except msvcrt.dll doesn't
- * export _lock_file, only numbered versions do (e.g. msvcrt90.dll).
- *
- * To work around this mingw-w64 packages a static archive of msvcrt which
- * includes their own implementation of _lock_file. However, this means that
- * the archive contains things which the dynamic library does not; consequently
- * we need to ensure that the runtime linker provides this symbol.
- *
- * It's all just so terrible.
- *
- * See also:
- * https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/
- * https://sourceforge.net/p/mingw-w64/discussion/723797/thread/55520785/
- */
 /* Note [_iob_func symbol]
  * ~~~~~~~~~~~~~~~~~~~~~~~
  * Microsoft in VS2013 to VS2015 transition made a backwards incompatible change
@@ -170,12 +150,6 @@ extern char **environ;
       SymI_NeedsProto(__mingw_module_is_dll)             \
       RTS_WIN32_ONLY(SymI_NeedsProto(___chkstk_ms))      \
       RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms))      \
-      RTS_WIN64_ONLY(SymI_HasProto(__stdio_common_vswprintf_s)) \
-      RTS_WIN64_ONLY(SymI_HasProto(__stdio_common_vswprintf)) \
-      RTS_WIN64_ONLY(SymI_HasProto(_errno))  \
-      /* see Note [Symbols for MinGW's printf] */        \
-      SymI_HasProto(_lock_file)                          \
-      SymI_HasProto(_unlock_file)                        \
       SymI_HasProto(__mingw_vsnwprintf)                  \
       /* ^^ Need to figure out why this is needed.  */   \
       /* See Note [_iob_func symbol] */                  \
@@ -187,120 +161,8 @@ extern char **environ;
       /* ^^ Need to figure out why this is needed.  */   \
       SymI_HasProto(__mingw_vfprintf)                    \
       /* ^^ Need to figure out why this is needed.  */
-
-#define RTS_MINGW_COMPAT_SYMBOLS                         \
-      SymI_HasProto_deprecated(access)                   \
-      SymI_HasProto_deprecated(cabs)                     \
-      SymI_HasProto_deprecated(cgets)                    \
-      SymI_HasProto_deprecated(chdir)                    \
-      SymI_HasProto_deprecated(chmod)                    \
-      SymI_HasProto_deprecated(chsize)                   \
-      SymI_HasProto_deprecated(close)                    \
-      SymI_HasProto_deprecated(cprintf)                  \
-      SymI_HasProto_deprecated(cputs)                    \
-      SymI_HasProto_deprecated(creat)                    \
-      SymI_HasProto_deprecated(cscanf)                   \
-      SymI_HasProto_deprecated(cwait)                    \
-      SymI_HasProto_deprecated(dup)                      \
-      SymI_HasProto_deprecated(dup2)                     \
-      SymI_HasProto_deprecated(ecvt)                     \
-      SymI_HasProto_deprecated(eof)                      \
-      SymI_HasProto_deprecated(execl)                    \
-      SymI_HasProto_deprecated(execle)                   \
-      SymI_HasProto_deprecated(execlp)                   \
-      SymI_HasProto_deprecated(execlpe)                  \
-      SymI_HasProto_deprecated(execv)                    \
-      SymI_HasProto_deprecated(execve)                   \
-      SymI_HasProto_deprecated(execvp)                   \
-      SymI_HasProto_deprecated(execvpe)                  \
-      SymI_HasProto_deprecated(fcloseall)                \
-      SymI_HasProto_deprecated(fcvt)                     \
-      SymI_HasProto_deprecated(fdopen)                   \
-      SymI_HasProto_deprecated(fgetchar)                 \
-      SymI_HasProto_deprecated(filelength)               \
-      SymI_HasProto_deprecated(fileno)                   \
-      SymI_HasProto_deprecated(flushall)                 \
-      SymI_HasProto_deprecated(fputchar)                 \
-      SymI_HasProto_deprecated(gcvt)                     \
-      SymI_HasProto_deprecated(getch)                    \
-      SymI_HasProto_deprecated(getche)                   \
-      SymI_HasProto_deprecated(getcwd)                   \
-      SymI_HasProto_deprecated(getpid)                   \
-      SymI_HasProto_deprecated(getw)                     \
-      SymI_HasProto_deprecated(hypot)                    \
-      SymI_HasProto_deprecated(inp)                      \
-      SymI_HasProto_deprecated(inpw)                     \
-      SymI_HasProto_deprecated(isascii)                  \
-      SymI_HasProto_deprecated(isatty)                   \
-      SymI_HasProto_deprecated(iscsym)                   \
-      SymI_HasProto_deprecated(iscsymf)                  \
-      SymI_HasProto_deprecated(itoa)                     \
-      SymI_HasProto_deprecated(j0)                       \
-      SymI_HasProto_deprecated(j1)                       \
-      SymI_HasProto_deprecated(jn)                       \
-      SymI_HasProto_deprecated(kbhit)                    \
-      SymI_HasProto_deprecated(lfind)                    \
-      SymI_HasProto_deprecated(locking)                  \
-      SymI_HasProto_deprecated(lsearch)                  \
-      SymI_HasProto_deprecated(lseek)                    \
-      SymI_HasProto_deprecated(ltoa)                     \
-      SymI_HasProto_deprecated(memccpy)                  \
-      SymI_HasProto_deprecated(memicmp)                  \
-      SymI_HasProto_deprecated(mkdir)                    \
-      SymI_HasProto_deprecated(mktemp)                   \
-      SymI_HasProto_deprecated(open)                     \
-      SymI_HasProto_deprecated(outp)                     \
-      SymI_HasProto_deprecated(outpw)                    \
-      SymI_HasProto_deprecated(putch)                    \
-      SymI_HasProto_deprecated(putenv)                   \
-      SymI_HasProto_deprecated(putw)                     \
-      SymI_HasProto_deprecated(read)                     \
-      SymI_HasProto_deprecated(rmdir)                    \
-      SymI_HasProto_deprecated(rmtmp)                    \
-      SymI_HasProto_deprecated(setmode)                  \
-      SymI_HasProto_deprecated(sopen)                    \
-      SymI_HasProto_deprecated(spawnl)                   \
-      SymI_HasProto_deprecated(spawnle)                  \
-      SymI_HasProto_deprecated(spawnlp)                  \
-      SymI_HasProto_deprecated(spawnlpe)                 \
-      SymI_HasProto_deprecated(spawnv)                   \
-      SymI_HasProto_deprecated(spawnve)                  \
-      SymI_HasProto_deprecated(spawnvp)                  \
-      SymI_HasProto_deprecated(spawnvpe)                 \
-      SymI_HasProto_deprecated(strcmpi)                  \
-      SymI_HasProto_deprecated(strdup)                   \
-      SymI_HasProto_deprecated(stricmp)                  \
-      SymI_HasProto_deprecated(strlwr)                   \
-      SymI_HasProto_deprecated(strnicmp)                 \
-      SymI_HasProto_deprecated(strnset)                  \
-      SymI_HasProto_deprecated(strrev)                   \
-      SymI_HasProto_deprecated(strset)                   \
-      SymI_HasProto_deprecated(strupr)                   \
-      SymI_HasProto_deprecated(swab)                     \
-      SymI_HasProto_deprecated(tell)                     \
-      SymI_HasProto_deprecated(tempnam)                  \
-      SymI_HasProto_deprecated(toascii)                  \
-      SymI_HasProto_deprecated(tzset)                    \
-      SymI_HasProto_deprecated(ultoa)                    \
-      SymI_HasProto_deprecated(umask)                    \
-      SymI_HasProto_deprecated(ungetch)                  \
-      SymI_HasProto_deprecated(unlink)                   \
-      SymI_HasProto_deprecated(wcsdup)                   \
-      SymI_HasProto_deprecated(wcsicmp)                  \
-      SymI_HasProto_deprecated(wcsicoll)                 \
-      SymI_HasProto_deprecated(wcslwr)                   \
-      SymI_HasProto_deprecated(wcsnicmp)                 \
-      SymI_HasProto_deprecated(wcsnset)                  \
-      SymI_HasProto_deprecated(wcsrev)                   \
-      SymI_HasProto_deprecated(wcsset)                   \
-      SymI_HasProto_deprecated(wcsupr)                   \
-      SymI_HasProto_deprecated(write)                    \
-      SymI_HasProto_deprecated(y0)                       \
-      SymI_HasProto_deprecated(y1)                       \
-      SymI_HasProto_deprecated(yn)
 #else
 #define RTS_MINGW_ONLY_SYMBOLS /**/
-#define RTS_MINGW_COMPAT_SYMBOLS /**/
 #endif
 
 
@@ -1123,7 +985,6 @@ extern char **environ;
 #define SymI_HasProto(vvv) /**/
 #define SymI_HasDataProto(vvv) /**/
 #define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/
-#define SymI_HasProto_deprecated(vvv) /**/
 
 RTS_SYMBOLS
 RTS_RET_SYMBOLS
@@ -1141,7 +1002,6 @@ RTS_LIBFFI_SYMBOLS
 #undef SymI_HasProto
 #undef SymI_HasDataProto
 #undef SymI_HasProto_redirect
-#undef SymI_HasProto_deprecated
 #undef SymE_HasProto
 #undef SymE_HasDataProto
 #undef SymE_NeedsProto
@@ -1167,22 +1027,11 @@ RTS_LIBFFI_SYMBOLS
     { MAYBE_LEADING_UNDERSCORE_STR(#vvv),    \
       (void*)(&(xxx)), strength, ty },
 
-// SymI_HasProto_deprecated allows us to redirect references from their deprecated
-// names to the undeprecated ones. e.g. access -> _access.
-// We use the hexspeak for unallocated memory 0xBAADF00D to signal the RTS
-// that this needs to be loaded from somewhere else.
-// These are inserted as weak symbols to prevent us overriding packages that do
-// define them, since on Windows these functions shouldn't be in the top level
-// namespace, but we have them for POSIX compatibility.
-#define SymI_HasProto_deprecated(vvv)   \
-   { #vvv, (void*)0xBAADF00D, STRENGTH_WEAK, SYM_TYPE_CODE },
-
 RtsSymbolVal rtsSyms[] = {
       RTS_SYMBOLS
       RTS_RET_SYMBOLS
       RTS_POSIX_ONLY_SYMBOLS
       RTS_MINGW_ONLY_SYMBOLS
-      RTS_MINGW_COMPAT_SYMBOLS
       RTS_DARWIN_ONLY_SYMBOLS
       RTS_OPENBSD_ONLY_SYMBOLS
       RTS_LIBGCC_SYMBOLS


=====================================
rts/linker/PEi386.c
=====================================
@@ -261,6 +261,54 @@
             .asciiz "libfoo_data"
 
 
+   Note [GHC Linking model and import libraries]
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   The above describes how import libraries work for static linking.
+   Fundamentally this does not apply to dynamic linking as we do in GHC.
+   The issue is two-folds:
+
+   1. In the linking model above it is expected that the .idata sections be
+      materialized into PLTs during linking.  However in GHC we never create
+      PLTs,  but have out own mechanism for this which is the jump island
+      machinery.   This is required for efficiency.  For one materializing the
+      .idata sections would result in wasting pages.   We'd use one page for
+      every ~100 bytes.  This is extremely wasteful and also fragments the
+      memory.  Secondly the dynamic linker is lazy.  We only perform the final
+      loading if the symbol is used, however with an import library we can
+      discard the actual OC immediately after reading it.   This prevents us from
+      keeping ~1k in memory per symbol for no reason.
+
+   2. GHC itself does not observe symbol visibility correctly during NGC.   This
+      in itself isn't an academic exercise.  The issue stems from GHC using one
+      mechanism for providing two incompatible linking modes:
+      a)  The first mode is generating Haskell shared libraries which are
+           intended to be used by other Haskell code.   This requires us to
+           export the info, data and closures.   For this GHC just re-exports
+           all symbols.  But it doesn't correcly mark data/code.  Symbol
+           visibility is overwritten by telling the linker to export all
+           symbols.
+      b)  The second code is producing code that's supposed to be call-able
+          through a C insterface.   This in reality does not require the
+          export of closures and info tables.  But also does not require the
+          inclusion of the RTS inside the DLL.  Hover this is done today
+          because we don't properly have the RTS as a dynamic library.
+          i.e.  GHC does not only export symbols denoted by foreign export.
+          Also GHC should depend on an RTS library, but at the moment it
+          cannot because of TNTC is incompatible with dynamic linking.
+
+   These two issues mean that for GHC we need to take a different approach
+   to handling import libraries.  For normal C libraries we have proper
+   differentiation between CODE and DATA.   For GHC produced import libraries
+   we do not.   As such the SYM_TYPE_DUP_DISCARD tells the linker that if a
+   duplicate symbol is found, and we were going to discard it anyway, just do
+   so quitely.  This works because the RTS symbols themselves are provided by
+   the currently loaded RTS as built-in symbols.
+
+   Secondly we cannot rely on a text symbol being available.   As such we
+   should only depend on the symbols as defined in the .idata sections,
+   otherwise we would not be able to correctly link against GHC produced
+   import libraries.
+
    Note [Memory allocation]
    ~~~~~~~~~~~~~~~~~~~~~~~~
    The loading of an object begins in `preloadObjectFile`, which allocates a buffer,
@@ -1658,7 +1706,10 @@ ocGetNames_PEi386 ( ObjectCode* oc )
       if (   secNumber != IMAGE_SYM_UNDEFINED
           && secNumber > 0
           && section
-          && section->kind != SECTIONKIND_BFD_IMPORT_LIBRARY) {
+          /* Skip all BFD import sections.  */
+          && section->kind != SECTIONKIND_IMPORT
+          && section->kind != SECTIONKIND_BFD_IMPORT_LIBRARY
+          && section->kind != SECTIONKIND_BFD_IMPORT_LIBRARY_HEAD) {
          /* This symbol is global and defined, viz, exported */
          /* for IMAGE_SYMCLASS_EXTERNAL
                 && !IMAGE_SYM_UNDEFINED,
@@ -1691,12 +1742,49 @@ ocGetNames_PEi386 ( ObjectCode* oc )
           IF_DEBUG(linker_verbose, debugBelch("bss symbol @ %p %u\n", addr, symValue));
       }
       else if (section && section->kind == SECTIONKIND_BFD_IMPORT_LIBRARY) {
-          setImportSymbol(oc, sname);
+          /* Disassembly of section .idata$5:
+
+             0000000000000000 <__imp_Insert>:
+             ...
+                        0: IMAGE_REL_AMD64_ADDR32NB     .idata$6
+
+             The first two bytes contain the ordinal of the function
+             in the format of lowpart highpart. The two bytes combined
+             for the total range of 16 bits which is the function export limit
+             of DLLs.  See note [GHC Linking model and import libraries].  */
+          sname = (SymbolName*)section->start+2;
+          COFF_symbol* sym = &oc->info->symbols[info->numberOfSymbols-1];
+          addr = get_sym_name( getSymShortName (info, sym), oc);
+
+          IF_DEBUG(linker,
+                   debugBelch("addImportSymbol `%s' => `%s'\n",
+                              sname, (char*)addr));
+          /* We're going to free the any data associated with the import
+             library without copying the sections.  So we have to duplicate
+             the symbol name and values before the pointers become invalid.  */
+          sname = strdup (sname);
+          addr  = strdup (addr);
+          type = has_code_section ? SYM_TYPE_CODE : SYM_TYPE_DATA;
+          type |= SYM_TYPE_DUP_DISCARD;
+          if (!ghciInsertSymbolTable(oc->fileName, symhash, sname,
+                                     addr, false, type, oc)) {
+             releaseOcInfo (oc);
+             stgFree (oc->image);
+             oc->image = NULL;
+             return false;
+          }
+          setImportSymbol (oc, sname);
+
+          /* Don't process this oc any further. Just exit.  */
+          oc->n_symbols = 0;
+          oc->symbols   = NULL;
+          stgFree (oc->image);
+          oc->image = NULL;
+          releaseOcInfo (oc);
           // There is nothing that we need to resolve in this object since we
           // will never call the import stubs in its text section
           oc->status = OBJECT_DONT_RESOLVE;
-
-          IF_DEBUG(linker_verbose, debugBelch("import symbol %s\n", sname));
+          return true;
       }
       else if (secNumber > 0
                && section
@@ -2171,21 +2259,7 @@ SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl, ObjectCode *dependent, SymType
     } else {
         if (type) *type = pinfo->type;
 
-        // If Windows, perform initialization of uninitialized
-        // Symbols from the C runtime which was loaded above.
-        // We do this on lookup to prevent the hit when
-        // The symbol isn't being used.
-        if (pinfo->value == (void*)0xBAADF00D)
-        {
-            char symBuffer[50];
-            const char *crt_impl = "ucrtbase";
-            sprintf(symBuffer, "_%s", lbl);
-            static HMODULE crt = NULL;
-            if (!crt) crt = GetModuleHandle(crt_impl);
-            pinfo->value = GetProcAddress(crt, symBuffer);
-            return pinfo->value;
-        }
-        else if (pinfo && pinfo->owner && isSymbolImport (pinfo->owner, lbl))
+        if (pinfo && pinfo->owner && isSymbolImport (pinfo->owner, lbl))
         {
             /* See Note [BFD import library].  */
             HINSTANCE dllInstance = (HINSTANCE)lookupDependentSymbol(pinfo->value, dependent, type);


=====================================
rts/rts.cabal.in
=====================================
@@ -39,8 +39,6 @@ flag need-pthread
   default: @CabalNeedLibpthread@
 flag libbfd
   default: @CabalHaveLibbfd@
-flag mingwex
-  default: @CabalMingwex@
 flag need-atomic
   default: @CabalNeedLibatomic@
 flag libdw
@@ -83,7 +81,6 @@ library
 
     exposed: True
     exposed-modules:
-
     if os(ghcjs)
 
       include-dirs: include
@@ -209,8 +206,6 @@ library
       if flag(libbfd)
          -- for debugging
          extra-libraries: bfd iberty
-      if flag(mingwex)
-         extra-libraries: mingwex
       if flag(libdw)
          -- for backtraces
          extra-libraries: elf dw


=====================================
testsuite/tests/ghci/linking/dyn/Makefile
=====================================
@@ -88,10 +88,6 @@ compile_libAB_dyn:
 
 .PHONY: compile_libAS_impl_gcc
 compile_libAS_impl_gcc:
-	rm -rf bin_impl_gcc
-	mkdir bin_impl_gcc
-	'$(TEST_HC)' $(MY_TEST_HC_OPTS) -odir "bin_impl_gcc" -shared A.c -o "bin_impl_gcc/$(call DLL,ASimpL)"
-	mv bin_impl_gcc/libASimpL.dll.a bin_impl_gcc/libASx.dll.a
 	echo "main" | '$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) T11072.hs -lASx -L./bin_impl_gcc
 
 .PHONY: compile_libAS_impl_msvc


=====================================
testsuite/tests/ghci/linking/dyn/all.T
=====================================
@@ -41,9 +41,9 @@ test('T10458',
       extra_hc_opts('-L"$PWD/T10458dir" -lAS')],
      ghci_script, ['T10458.script'])
 
-test('T11072gcc', [extra_files(['A.c', 'T11072.hs']),
-                   expect_broken(18718),
-                   unless(doing_ghci, skip), unless(opsys('mingw32'), skip)],
+test('T11072gcc', [extra_files(['A.c', 'T11072.hs', 'bin_impl_gcc/']),
+                   unless(doing_ghci, skip), unless(opsys('mingw32'), skip),
+                   unless(arch('x86_64'), skip)],
      makefile_test, ['compile_libAS_impl_gcc'])
 
 test('T11072msvc', [extra_files(['A.c', 'T11072.hs', 'libAS.def', 'i686/', 'x86_64/']),


=====================================
testsuite/tests/ghci/linking/dyn/bin_impl_gcc/ASimpL.dll
=====================================
Binary files /dev/null and b/testsuite/tests/ghci/linking/dyn/bin_impl_gcc/ASimpL.dll differ


=====================================
testsuite/tests/ghci/linking/dyn/bin_impl_gcc/libASx.dll.a
=====================================
Binary files /dev/null and b/testsuite/tests/ghci/linking/dyn/bin_impl_gcc/libASx.dll.a differ


=====================================
testsuite/tests/rts/all.T
=====================================
@@ -411,7 +411,7 @@ test('T10296b', [only_ways(['threaded2'])], compile_and_run, [''])
 test('numa001', [ extra_run_opts('8'), unless(unregisterised(), extra_ways(['debug_numa'])) ]
                 , compile_and_run, [''])
 
-test('T12497', [ unless(opsys('mingw32'), skip)
+test('T12497', [ unless(opsys('mingw32'), skip), expect_broken(22694)
                ],
                makefile_test, ['T12497'])
 


=====================================
testsuite/tests/simplCore/should_compile/T22715_2.hs
=====================================
@@ -0,0 +1,6 @@
+module T22715_2 where
+
+import T22715_2a
+
+debugTerminalKeys :: (forall m. CommandMonad m => m Char) -> Input IO Char
+debugTerminalKeys eval = runIdT eval


=====================================
testsuite/tests/simplCore/should_compile/T22715_2a.hs
=====================================
@@ -0,0 +1,29 @@
+{-# OPTIONS_GHC -Wno-missing-methods #-}
+
+module T22715_2a where
+
+newtype IdentityT m a = IdentityT (m a) deriving Functor
+newtype IdT m a = IdT {runIdT :: m a} deriving Functor
+
+class Functor m => SillyA m where
+  unused :: m a -> m a
+
+class SillyA m => SillyB m where
+  unused2 :: m a -> m a
+
+instance SillyA m => SillyA (IdentityT m) where
+instance SillyB m => SillyB (IdentityT m) where
+
+instance SillyA m => SillyA (IdT m) where
+instance SillyB m => SillyB (IdT m) where
+
+instance SillyA IO where
+instance SillyB IO where
+
+class Functor m => Special m
+instance Functor m => Special (IdT m)
+
+type Input m = IdentityT (IdentityT m)
+
+class (Special m, SillyB m) => CommandMonad m
+instance SillyB m => CommandMonad (IdT (Input m))


=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -469,4 +469,4 @@ test('T22662', normal, compile, [''])
 test('T22725', normal, compile, ['-O'])
 test('T22502', normal, compile, ['-O'])
 test('T22611', [when(wordsize(32), skip), grep_errmsg(r'\$salterF') ], compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-all'])
-
+test('T22715_2', normal, multimod_compile, ['T22715_2', '-v0 -O -fspecialise-aggressively'])



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2455cabfc7b2576179af90d5d918178ed58ed59d...9f5971c30e33e0518dae155302309da1509564ea

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2455cabfc7b2576179af90d5d918178ed58ed59d...9f5971c30e33e0518dae155302309da1509564ea
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230126/a74c5909/attachment-0001.html>


More information about the ghc-commits mailing list