Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

29 changed files:

Changes:

  • compiler/GHC.hs
    ... ... @@ -859,6 +859,7 @@ setProgramDynFlags_ invalidate_needed dflags = do
    859 859
                   , ue_namever         = ghcNameVersion dflags1
    
    860 860
                   , ue_home_unit_graph = home_unit_graph
    
    861 861
                   , ue_current_unit    = ue_currentUnit old_unit_env
    
    862
    +              , ue_module_graph    = ue_module_graph old_unit_env
    
    862 863
                   , ue_eps             = ue_eps old_unit_env
    
    863 864
                   }
    
    864 865
             modifySession $ \h -> hscSetFlags dflags1 h{ hsc_unit_env = unit_env }
    
    ... ... @@ -916,6 +917,7 @@ setProgramHUG_ invalidate_needed new_hug0 = do
    916 917
                 , ue_home_unit_graph = home_unit_graph
    
    917 918
                 , ue_current_unit    = ue_currentUnit unit_env0
    
    918 919
                 , ue_eps             = ue_eps unit_env0
    
    920
    +            , ue_module_graph    = ue_module_graph unit_env0
    
    919 921
                 }
    
    920 922
           modifySession $ \h ->
    
    921 923
             -- hscSetFlags takes care of updating the logger as well.
    
    ... ... @@ -996,7 +998,7 @@ setProgramHUG_ invalidate_needed new_hug0 = do
    996 998
     --
    
    997 999
     invalidateModSummaryCache :: GhcMonad m => m ()
    
    998 1000
     invalidateModSummaryCache =
    
    999
    -  modifySession $ \h -> h { hsc_mod_graph = mapMG inval (hsc_mod_graph h) }
    
    1001
    +  modifySession $ \hsc_env -> setModuleGraph (mapMG inval (hsc_mod_graph hsc_env)) hsc_env
    
    1000 1002
      where
    
    1001 1003
       inval ms = ms { ms_hs_hash = fingerprint0 }
    
    1002 1004
     
    

  • compiler/GHC/Core/Opt/Pipeline.hs
    ... ... @@ -97,10 +97,11 @@ core2core hsc_env guts@(ModGuts { mg_module = mod
    97 97
       where
    
    98 98
         dflags         = hsc_dflags hsc_env
    
    99 99
         logger         = hsc_logger hsc_env
    
    100
    +    unit_env       = hsc_unit_env hsc_env
    
    100 101
         extra_vars     = interactiveInScope (hsc_IC hsc_env)
    
    101 102
         home_pkg_rules = hugRulesBelow hsc_env (moduleUnitId mod)
    
    102 103
                           (GWIB { gwib_mod = moduleName mod, gwib_isBoot = NotBoot })
    
    103
    -    name_ppr_ctx   = mkNamePprCtx ptc (hsc_unit_env hsc_env) rdr_env
    
    104
    +    name_ppr_ctx   = mkNamePprCtx ptc unit_env rdr_env
    
    104 105
         ptc            = initPromotionTickContext dflags
    
    105 106
         -- mod: get the module out of the current HscEnv so we can retrieve it from the monad.
    
    106 107
         -- This is very convienent for the users of the monad (e.g. plugins do not have to
    

  • compiler/GHC/Driver/Backpack.hs
    ... ... @@ -457,6 +457,7 @@ addUnit u = do
    457 457
                         (homeUnitId home_unit)
    
    458 458
                         (HUG.mkHomeUnitEnv unit_state (Just dbs) dflags (ue_hpt old_unit_env) (Just home_unit))
    
    459 459
               , ue_eps       = ue_eps old_unit_env
    
    460
    +          , ue_module_graph = ue_module_graph old_unit_env
    
    460 461
               }
    
    461 462
         setSession $ hscSetFlags dflags $ hsc_env { hsc_unit_env = unit_env }
    
    462 463
     
    

  • compiler/GHC/Driver/Env.hs
    ... ... @@ -2,6 +2,8 @@
    2 2
     module GHC.Driver.Env
    
    3 3
        ( Hsc(..)
    
    4 4
        , HscEnv (..)
    
    5
    +   , hsc_mod_graph
    
    6
    +   , setModuleGraph
    
    5 7
        , hscUpdateFlags
    
    6 8
        , hscSetFlags
    
    7 9
        , hsc_home_unit
    
    ... ... @@ -130,6 +132,9 @@ hsc_HUE = ue_currentHomeUnitEnv . hsc_unit_env
    130 132
     hsc_HUG :: HscEnv -> HomeUnitGraph
    
    131 133
     hsc_HUG = ue_home_unit_graph . hsc_unit_env
    
    132 134
     
    
    135
    +hsc_mod_graph :: HscEnv -> ModuleGraph
    
    136
    +hsc_mod_graph = ue_module_graph . hsc_unit_env
    
    137
    +
    
    133 138
     hsc_all_home_unit_ids :: HscEnv -> Set.Set UnitId
    
    134 139
     hsc_all_home_unit_ids = HUG.allUnits . hsc_HUG
    
    135 140
     
    
    ... ... @@ -139,6 +144,9 @@ hscInsertHPT hmi hsc_env = UnitEnv.insertHpt hmi (hsc_unit_env hsc_env)
    139 144
     hscUpdateHUG :: (HomeUnitGraph -> HomeUnitGraph) -> HscEnv -> HscEnv
    
    140 145
     hscUpdateHUG f hsc_env = hsc_env { hsc_unit_env = updateHug f (hsc_unit_env hsc_env) }
    
    141 146
     
    
    147
    +setModuleGraph :: ModuleGraph -> HscEnv -> HscEnv
    
    148
    +setModuleGraph mod_graph hsc_env = hsc_env { hsc_unit_env = (hsc_unit_env hsc_env) { ue_module_graph = mod_graph } }
    
    149
    +
    
    142 150
     {-
    
    143 151
     
    
    144 152
     Note [Target code interpreter]
    
    ... ... @@ -220,15 +228,15 @@ hscEPS hsc_env = readIORef (euc_eps (ue_eps (hsc_unit_env hsc_env)))
    220 228
     -- | Find all rules in modules that are in the transitive closure of the given
    
    221 229
     -- module.
    
    222 230
     hugRulesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase
    
    223
    -hugRulesBelow hsc uid mn = foldr (flip extendRuleBaseList) emptyRuleBase <$>
    
    224
    -  hugSomeThingsBelowUs (md_rules . hm_details) False hsc uid mn
    
    231
    +hugRulesBelow hsc_env uid mn = foldr (flip extendRuleBaseList) emptyRuleBase <$>
    
    232
    +  hugSomeThingsBelowUs (md_rules . hm_details) False hsc_env uid mn
    
    225 233
     
    
    226 234
     -- | Get annotations from all modules "below" this one (in the dependency
    
    227 235
     -- sense) within the home units. If the module is @Nothing@, returns /all/
    
    228 236
     -- annotations in the home units.
    
    229 237
     hugAnnsBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv
    
    230
    -hugAnnsBelow hsc uid mn = foldr (flip extendAnnEnvList) emptyAnnEnv <$>
    
    231
    -  hugSomeThingsBelowUs (md_anns . hm_details) False hsc uid mn
    
    238
    +hugAnnsBelow hsc_env uid mn = foldr (flip extendAnnEnvList) emptyAnnEnv <$>
    
    239
    +  hugSomeThingsBelowUs (md_anns . hm_details) False hsc_env uid mn
    
    232 240
     
    
    233 241
     -- | Find all COMPLETE pragmas in modules that are in the transitive closure of the
    
    234 242
     -- given module.
    
    ... ... @@ -237,7 +245,7 @@ hugCompleteSigsBelow hsc uid mn = foldr (++) [] <$>
    237 245
       hugSomeThingsBelowUs (md_complete_matches . hm_details) False hsc uid mn
    
    238 246
     
    
    239 247
     -- | Find instances visible from the given set of imports
    
    240
    -hugInstancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst])
    
    248
    +hugInstancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [(Module, FamInstEnv)])
    
    241 249
     hugInstancesBelow hsc_env uid mnwib = do
    
    242 250
      let mn = gwib_mod mnwib
    
    243 251
      (insts, famInsts) <-
    
    ... ... @@ -247,7 +255,7 @@ hugInstancesBelow hsc_env uid mnwib = do
    247 255
                                       -- Don't include instances for the current module
    
    248 256
                                       in if moduleName (mi_module (hm_iface mod_info)) == mn
    
    249 257
                                            then []
    
    250
    -                                       else [(md_insts details, md_fam_insts details)])
    
    258
    +                                       else [(md_insts details, [(mi_module $ hm_iface mod_info, extendFamInstEnvList emptyFamInstEnv $ md_fam_insts details)])])
    
    251 259
                               True -- Include -hi-boot
    
    252 260
                               hsc_env
    
    253 261
                               uid
    
    ... ... @@ -260,7 +268,8 @@ hugInstancesBelow hsc_env uid mnwib = do
    260 268
     hugSomeThingsBelowUs :: (HomeModInfo -> [a]) -> Bool -> HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO [[a]]
    
    261 269
     -- An explicit check to see if we are in one-shot mode to avoid poking the ModuleGraph thunk
    
    262 270
     -- These things are currently stored in the EPS for home packages. (See #25795 for
    
    263
    --- progress in removing these kind of checks)
    
    271
    +-- progress in removing these kind of checks; and making these functions of
    
    272
    +-- `UnitEnv` rather than `HscEnv`)
    
    264 273
     -- See Note [Downsweep and the ModuleGraph]
    
    265 274
     hugSomeThingsBelowUs _ _ hsc_env _ _ | isOneShot (ghcMode (hsc_dflags hsc_env)) = return []
    
    266 275
     hugSomeThingsBelowUs extract include_hi_boot hsc_env uid mn
    

  • compiler/GHC/Driver/Env/Types.hs
    ... ... @@ -18,7 +18,6 @@ import GHC.Types.Name.Cache
    18 18
     import GHC.Types.Target
    
    19 19
     import GHC.Types.TypeEnv
    
    20 20
     import GHC.Unit.Finder.Types
    
    21
    -import GHC.Unit.Module.Graph
    
    22 21
     import GHC.Unit.Env
    
    23 22
     import GHC.Utils.Logger
    
    24 23
     import GHC.Utils.TmpFs
    
    ... ... @@ -65,10 +64,6 @@ data HscEnv
    65 64
             hsc_targets :: [Target],
    
    66 65
                     -- ^ The targets (or roots) of the current session
    
    67 66
     
    
    68
    -        hsc_mod_graph :: ModuleGraph,
    
    69
    -                -- ^ The module graph of the current session
    
    70
    -                -- See Note [Downsweep and the ModuleGraph] for when this is constructed.
    
    71
    -
    
    72 67
             hsc_IC :: InteractiveContext,
    
    73 68
                     -- ^ The context for evaluating interactive statements
    
    74 69
     
    
    ... ... @@ -113,3 +108,4 @@ data HscEnv
    113 108
             , hsc_llvm_config :: !LlvmConfigCache
    
    114 109
                     -- ^ LLVM configuration cache.
    
    115 110
      }
    
    111
    +

  • compiler/GHC/Driver/Main.hs
    ... ... @@ -332,7 +332,6 @@ newHscEnvWithHUG top_dir top_dynflags cur_unit home_unit_graph = do
    332 332
         return HscEnv { hsc_dflags         = top_dynflags
    
    333 333
                       , hsc_logger         = setLogFlags logger (initLogFlags top_dynflags)
    
    334 334
                       , hsc_targets        = []
    
    335
    -                  , hsc_mod_graph      = emptyMG
    
    336 335
                       , hsc_IC             = emptyInteractiveContext dflags
    
    337 336
                       , hsc_NC             = nc_var
    
    338 337
                       , hsc_FC             = fc_var
    

  • compiler/GHC/Driver/Make.hs
    ... ... @@ -190,12 +190,12 @@ depanalE diag_wrapper msg excluded_mods allow_dup_roots = do
    190 190
     
    
    191 191
             all_errs <- liftIO $ HUG.unitEnv_foldWithKey one_unit_messages (return emptyMessages) (hsc_HUG hsc_env)
    
    192 192
             logDiagnostics (GhcDriverMessage <$> all_errs)
    
    193
    -        setSession hsc_env { hsc_mod_graph = mod_graph }
    
    193
    +        setSession (setModuleGraph mod_graph hsc_env)
    
    194 194
             pure (emptyMessages, mod_graph)
    
    195 195
           else do
    
    196 196
             -- We don't have a complete module dependency graph,
    
    197 197
             -- The graph may be disconnected and is unusable.
    
    198
    -        setSession hsc_env { hsc_mod_graph = emptyMG }
    
    198
    +        setSession (setModuleGraph emptyMG hsc_env)
    
    199 199
             pure (errs, emptyMG)
    
    200 200
     
    
    201 201
     
    
    ... ... @@ -616,7 +616,7 @@ load' mhmi_cache how_much diag_wrapper mHscMessage mod_graph = do
    616 616
         -- for any client who might interact with GHC via load'.
    
    617 617
         -- See Note [Timing of plugin initialization]
    
    618 618
         initializeSessionPlugins
    
    619
    -    modifySession $ \hsc_env -> hsc_env { hsc_mod_graph = mod_graph }
    
    619
    +    modifySession (setModuleGraph mod_graph)
    
    620 620
         guessOutputFile
    
    621 621
         hsc_env <- getSession
    
    622 622
     
    

  • compiler/GHC/Driver/Pipeline/Execute.hs
    ... ... @@ -768,8 +768,9 @@ runHscPhase pipe_env hsc_env0 input_fn src_flavour = do
    768 768
       -- files. See GHC.Tc.Utils.TcGblEnv.tcg_type_env_var.
    
    769 769
       -- See also Note [hsc_type_env_var hack]
    
    770 770
       type_env_var <- newIORef emptyNameEnv
    
    771
    -  let hsc_env' = hsc_env { hsc_type_env_vars = knotVarsFromModuleEnv (mkModuleEnv [(mod, type_env_var)])
    
    772
    -                         , hsc_mod_graph = mg }
    
    771
    +  let hsc_env' =
    
    772
    +        setModuleGraph mg
    
    773
    +          hsc_env { hsc_type_env_vars = knotVarsFromModuleEnv (mkModuleEnv [(mod, type_env_var)]) }
    
    773 774
     
    
    774 775
     
    
    775 776
     
    

  • compiler/GHC/Iface/Load.hs
    ... ... @@ -671,7 +671,7 @@ dontLeakTheHUG thing_inside = do
    671 671
              -- oneshot mode does not support backpack
    
    672 672
              -- and we want to avoid prodding the hsc_mod_graph thunk
    
    673 673
              | isOneShot (ghcMode (hsc_dflags hsc_env)) = False
    
    674
    -         | mgHasHoles (hsc_mod_graph hsc_env) = True
    
    674
    +         | mgHasHoles (ue_module_graph old_unit_env) = True
    
    675 675
              | otherwise = False
    
    676 676
             pruneHomeUnitEnv hme = do
    
    677 677
               -- NB: These are empty HPTs because Iface/Load first consults the HPT
    
    ... ... @@ -683,19 +683,19 @@ dontLeakTheHUG thing_inside = do
    683 683
               | otherwise
    
    684 684
               = do
    
    685 685
                 hug' <- traverse pruneHomeUnitEnv (ue_home_unit_graph old_unit_env)
    
    686
    +            let !new_mod_graph = emptyMG { mg_mss = panic "cleanTopEnv: mg_mss"
    
    687
    +                                         , mg_graph = panic "cleanTopEnv: mg_graph"
    
    688
    +                                         , mg_has_holes = keepFor20509 }
    
    686 689
                 return old_unit_env
    
    687 690
                   { ue_home_unit_graph = hug'
    
    691
    +              , ue_module_graph    = new_mod_graph
    
    688 692
                   }
    
    689 693
           in do
    
    690 694
             !unit_env <- unit_env_io
    
    691 695
             -- mg_has_holes will be checked again, but nothing else about the module graph
    
    692
    -        let !new_mod_graph = emptyMG { mg_mss = panic "cleanTopEnv: mg_mss"
    
    693
    -                                     , mg_graph = panic "cleanTopEnv: mg_graph"
    
    694
    -                                     , mg_has_holes = keepFor20509 }
    
    695 696
             pure $
    
    696 697
               hsc_env
    
    697 698
                     {  hsc_targets      = panic "cleanTopEnv: hsc_targets"
    
    698
    -                ,  hsc_mod_graph    = new_mod_graph
    
    699 699
                     ,  hsc_IC           = panic "cleanTopEnv: hsc_IC"
    
    700 700
                     ,  hsc_type_env_vars = case maybe_type_vars of
    
    701 701
                                                Just vars -> vars
    

  • compiler/GHC/Tc/Instance/Family.hs
    ... ... @@ -286,8 +286,8 @@ why we still do redundant checks.
    286 286
     -- We don't need to check the current module, this is done in
    
    287 287
     -- tcExtendLocalFamInstEnv.
    
    288 288
     -- See Note [The type family instance consistency story].
    
    289
    -checkFamInstConsistency :: [Module] -> TcM ()
    
    290
    -checkFamInstConsistency directlyImpMods
    
    289
    +checkFamInstConsistency :: ModuleEnv FamInstEnv -> [Module] -> TcM ()
    
    290
    +checkFamInstConsistency hpt_fam_insts directlyImpMods
    
    291 291
       = do { (eps, hug) <- getEpsAndHug
    
    292 292
            ; traceTc "checkFamInstConsistency" (ppr directlyImpMods)
    
    293 293
            ; let { -- Fetch the iface of a given module.  Must succeed as
    
    ... ... @@ -317,7 +317,6 @@ checkFamInstConsistency directlyImpMods
    317 317
                  -- See Note [Order of type family consistency checks]
    
    318 318
                  }
    
    319 319
     
    
    320
    -       ; hpt_fam_insts <- liftIO $ HUG.allFamInstances hug
    
    321 320
            ; debug_consistent_set <- mapM (\x -> (\y -> (x, length y)) <$> modConsistent x) directlyImpMods
    
    322 321
            ; traceTc "init_consistent_set" (ppr debug_consistent_set)
    
    323 322
            ; let init_consistent_set = map fst (reverse (sortOn snd debug_consistent_set))
    

  • compiler/GHC/Tc/Module.hs
    ... ... @@ -120,7 +120,7 @@ import GHC.Core.TyCo.Ppr( debugPprType )
    120 120
     import GHC.Core.TyCo.Tidy( tidyTopType )
    
    121 121
     import GHC.Core.FamInstEnv
    
    122 122
        ( FamInst, pprFamInst, famInstsRepTyCons, orphNamesOfFamInst
    
    123
    -   , famInstEnvElts, extendFamInstEnvList, normaliseType )
    
    123
    +   , famInstEnvElts, extendFamInstEnvList, normaliseType, emptyFamInstEnv, unionFamInstEnv )
    
    124 124
     
    
    125 125
     import GHC.Parser.Header       ( mkPrelImports )
    
    126 126
     
    
    ... ... @@ -467,8 +467,8 @@ tcRnImports hsc_env import_decls
    467 467
       = do  { (rn_imports, imp_user_spec, rdr_env, imports) <- rnImports import_decls
    
    468 468
             -- Get the default declarations for the classes imported by this module
    
    469 469
             -- and group them by class.
    
    470
    -        ; tc_defaults <-(NE.groupBy ((==) `on` cd_class) . (concatMap defaultList))
    
    471
    -                        <$> tcGetClsDefaults (M.keys $ imp_mods imports)
    
    470
    +        ; tc_defaults <- NE.groupBy ((==) `on` cd_class) . (concatMap defaultList)
    
    471
    +                         <$> tcGetClsDefaults (M.keys $ imp_mods imports)
    
    472 472
             ; this_mod <- getModule
    
    473 473
             ; gbl_env <- getGblEnv
    
    474 474
             ; let unitId = homeUnitId $ hsc_home_unit hsc_env
    
    ... ... @@ -480,8 +480,10 @@ tcRnImports hsc_env import_decls
    480 480
                     -- filtering also ensures that we don't see instances from
    
    481 481
                     -- modules batch (@--make@) compiled before this one, but
    
    482 482
                     -- which are not below this one.
    
    483
    -              ; (home_insts, home_fam_insts) <- liftIO $
    
    483
    +              ; (home_insts, home_mod_fam_inst_env) <- liftIO $
    
    484 484
                         hugInstancesBelow hsc_env unitId mnwib
    
    485
    +              ; let home_fam_inst_env = foldl' unionFamInstEnv emptyFamInstEnv $ snd <$> home_mod_fam_inst_env
    
    486
    +              ; let hpt_fam_insts = mkModuleEnv home_mod_fam_inst_env
    
    485 487
     
    
    486 488
                     -- We use 'unsafeInterleaveIO' to avoid redundant memory allocations
    
    487 489
                     -- See Note [Lazily loading COMPLETE pragmas] from GHC.HsToCore.Monad
    
    ... ... @@ -507,8 +509,7 @@ tcRnImports hsc_env import_decls
    507 509
                   tcg_rn_imports   = rn_imports,
    
    508 510
                   tcg_default      = foldMap subsume tc_defaults,
    
    509 511
                   tcg_inst_env     = tcg_inst_env gbl `unionInstEnv` home_insts,
    
    510
    -              tcg_fam_inst_env = extendFamInstEnvList (tcg_fam_inst_env gbl)
    
    511
    -                                                      home_fam_insts
    
    512
    +              tcg_fam_inst_env = unionFamInstEnv (tcg_fam_inst_env gbl) home_fam_inst_env
    
    512 513
                 }) $ do {
    
    513 514
     
    
    514 515
             ; traceRn "rn1" (ppr (imp_direct_dep_mods imports))
    
    ... ... @@ -538,7 +539,7 @@ tcRnImports hsc_env import_decls
    538 539
                                  $ imports }
    
    539 540
             ; logger <- getLogger
    
    540 541
             ; withTiming logger (text "ConsistencyCheck"<+>brackets (ppr this_mod)) (const ())
    
    541
    -            $ checkFamInstConsistency dir_imp_mods
    
    542
    +            $ checkFamInstConsistency hpt_fam_insts dir_imp_mods
    
    542 543
             ; traceRn "rn1: } checking family instance consistency" empty
    
    543 544
     
    
    544 545
             ; gbl_env <- getGblEnv
    
    ... ... @@ -2109,7 +2110,7 @@ for the unit portion of the graph, if it's not already been performed.
    2109 2110
     withInteractiveModuleNode :: HscEnv -> TcM a -> TcM a
    
    2110 2111
     withInteractiveModuleNode hsc_env thing_inside = do
    
    2111 2112
       mg <- liftIO $ downsweepInteractiveImports hsc_env (hsc_IC hsc_env)
    
    2112
    -  updTopEnv (\env -> env { hsc_mod_graph = mg }) thing_inside
    
    2113
    +  updTopEnv (setModuleGraph mg) thing_inside
    
    2113 2114
     
    
    2114 2115
     
    
    2115 2116
     runTcInteractive :: HscEnv -> TcRn a -> IO (Messages TcRnMessage, Maybe a)
    

  • compiler/GHC/Unit/Env.hs
    ... ... @@ -23,21 +23,22 @@
    23 23
     -- ┌▽────────────┐    │                     │
    
    24 24
     -- │HomeUnitGraph│    │                     │
    
    25 25
     -- └┬────────────┘    │                     │
    
    26
    --- ┌▽─────────────────▽┐                    │
    
    27
    --- │UnitEnv            │                    │
    
    28
    --- └┬──────────────────┘                    │
    
    29
    --- ┌▽───────────────────────────────────────▽┐
    
    30
    --- │HscEnv                                   │
    
    31
    --- └─────────────────────────────────────────┘
    
    26
    +-- ┌▽─────────────────▽─────────────────────▽┐
    
    27
    +-- │UnitEnv                                  │
    
    28
    +-- └┬─────────────-──────────────────────────┘
    
    29
    +--  │
    
    30
    +--  │
    
    31
    +-- ┌▽──────────────────────────────────────▽┐
    
    32
    +-- │HscEnv                                  │
    
    33
    +-- └────────────────────────────────────────┘
    
    32 34
     -- @
    
    33 35
     --
    
    34
    --- The 'UnitEnv' references both the 'HomeUnitGraph' (with all the home unit
    
    35
    --- modules) and the 'ExternalPackageState' (information about all
    
    36
    --- non-home/external units). The 'HscEnv' references this 'UnitEnv' and the
    
    37
    --- 'ModuleGraph' (which describes the relationship between the modules being
    
    38
    --- compiled). The 'HomeUnitGraph' has one 'HomePackageTable' for every unit.
    
    39
    ---
    
    40
    --- TODO: Arguably, the 'ModuleGraph' should be part of 'UnitEnv' rather than being in the 'HscEnv'.
    
    36
    +-- The 'UnitEnv' references the 'HomeUnitGraph' (with all the home unit
    
    37
    +-- modules), the 'ExternalPackageState' (information about all
    
    38
    +-- non-home/external units), and the 'ModuleGraph' (which describes the
    
    39
    +-- relationship between the modules being compiled).
    
    40
    +-- The 'HscEnv' references this 'UnitEnv'.
    
    41
    +-- The 'HomeUnitGraph' has one 'HomePackageTable' for every unit.
    
    41 42
     module GHC.Unit.Env
    
    42 43
         ( UnitEnv (..)
    
    43 44
         , initUnitEnv
    
    ... ... @@ -119,6 +120,7 @@ import GHC.Unit.Home.ModInfo
    119 120
     import GHC.Unit.Home.PackageTable
    
    120 121
     import GHC.Unit.Home.Graph (HomeUnitGraph, HomeUnitEnv)
    
    121 122
     import qualified GHC.Unit.Home.Graph as HUG
    
    123
    +import GHC.Unit.Module.Graph
    
    122 124
     
    
    123 125
     import GHC.Platform
    
    124 126
     import GHC.Settings
    
    ... ... @@ -163,6 +165,10 @@ data UnitEnv = UnitEnv
    163 165
     
    
    164 166
         , ue_current_unit    :: UnitId
    
    165 167
     
    
    168
    +    , ue_module_graph    :: ModuleGraph
    
    169
    +        -- ^ The module graph of the current session
    
    170
    +        -- See Note [Downsweep and the ModuleGraph] for when this is constructed.
    
    171
    +
    
    166 172
         , ue_home_unit_graph :: !HomeUnitGraph
    
    167 173
             -- See Note [Multiple Home Units]
    
    168 174
     
    
    ... ... @@ -182,6 +188,7 @@ initUnitEnv cur_unit hug namever platform = do
    182 188
       return $ UnitEnv
    
    183 189
         { ue_eps             = eps
    
    184 190
         , ue_home_unit_graph = hug
    
    191
    +    , ue_module_graph    = emptyMG
    
    185 192
         , ue_current_unit    = cur_unit
    
    186 193
         , ue_platform        = platform
    
    187 194
         , ue_namever         = namever
    

  • compiler/GHC/Unit/Home/Graph.hs
    ... ... @@ -43,7 +43,6 @@ module GHC.Unit.Home.Graph
    43 43
     
    
    44 44
       -- * Very important queries
    
    45 45
       , allInstances
    
    46
    -  , allFamInstances
    
    47 46
       , allAnns
    
    48 47
       , allCompleteSigs
    
    49 48
     
    
    ... ... @@ -110,10 +109,6 @@ allInstances hug = foldr go (pure (emptyInstEnv, [])) hug where
    110 109
       go hue = liftA2 (\(a,b) (a',b') -> (a `unionInstEnv` a', b ++ b'))
    
    111 110
                       (hptAllInstances (homeUnitEnv_hpt hue))
    
    112 111
     
    
    113
    -allFamInstances :: HomeUnitGraph -> IO (ModuleEnv FamInstEnv)
    
    114
    -allFamInstances hug = foldr go (pure emptyModuleEnv) hug where
    
    115
    -  go hue = liftA2 plusModuleEnv (hptAllFamInstances (homeUnitEnv_hpt hue))
    
    116
    -
    
    117 112
     allAnns :: HomeUnitGraph -> IO AnnEnv
    
    118 113
     allAnns hug = foldr go (pure emptyAnnEnv) hug where
    
    119 114
       go hue = liftA2 plusAnnEnv (hptAllAnnotations (homeUnitEnv_hpt hue))
    

  • compiler/GHC/Unit/Home/PackageTable.hs
    ... ... @@ -41,7 +41,6 @@ module GHC.Unit.Home.PackageTable
    41 41
         -- * Queries about home modules
    
    42 42
       , hptCompleteSigs
    
    43 43
       , hptAllInstances
    
    44
    -  , hptAllFamInstances
    
    45 44
       , hptAllAnnotations
    
    46 45
     
    
    47 46
         -- ** More Traversal-based queries
    
    ... ... @@ -208,14 +207,6 @@ hptAllInstances hpt = do
    208 207
       let (insts, famInsts) = unzip hits
    
    209 208
       return (foldl' unionInstEnv emptyInstEnv insts, concat famInsts)
    
    210 209
     
    
    211
    --- | Find all the family instance declarations from the HPT
    
    212
    -hptAllFamInstances :: HomePackageTable -> IO (ModuleEnv FamInstEnv)
    
    213
    -hptAllFamInstances = fmap mkModuleEnv . concatHpt (\hmi -> [(hmiModule hmi, hmiFamInstEnv hmi)])
    
    214
    -  where
    
    215
    -    hmiModule     = mi_module . hm_iface
    
    216
    -    hmiFamInstEnv = extendFamInstEnvList emptyFamInstEnv
    
    217
    -                      . md_fam_insts . hm_details
    
    218
    -
    
    219 210
     -- | All annotations from the HPT
    
    220 211
     hptAllAnnotations :: HomePackageTable -> IO AnnEnv
    
    221 212
     hptAllAnnotations = fmap mkAnnEnv . concatHpt (md_anns . hm_details)
    

  • distrib/configure.ac.in
    ... ... @@ -216,7 +216,7 @@ AC_SUBST([LlvmAsCmd])
    216 216
     
    
    217 217
     dnl We know that `clang` supports `--target` and it is necessary to pass it
    
    218 218
     dnl lest we see #25793.
    
    219
    -if test -z "$LlvmAsFlags" ; then
    
    219
    +if test -z "$LlvmAsFlags" && ! test -z "$LlvmTarget"; then
    
    220 220
         LlvmAsFlags="--target=$LlvmTarget"
    
    221 221
     fi
    
    222 222
     AC_SUBST([LlvmAsFlags])
    

  • ghc/GHCi/UI.hs
    ... ... @@ -4680,7 +4680,7 @@ clearHPTs = do
    4680 4680
       let pruneHomeUnitEnv hme = liftIO $ do
    
    4681 4681
             emptyHpt <- emptyHomePackageTable
    
    4682 4682
             pure  hme{ homeUnitEnv_hpt = emptyHpt }
    
    4683
    -      discardMG hsc = hsc { hsc_mod_graph = GHC.emptyMG }
    
    4683
    +      discardMG hsc = setModuleGraph GHC.emptyMG hsc
    
    4684 4684
       modifySessionM $ \hsc_env -> do
    
    4685 4685
         hug' <- traverse pruneHomeUnitEnv $ hsc_HUG hsc_env
    
    4686 4686
         pure $ discardMG $ discardIC $ hscUpdateHUG (const hug') hsc_env
    

  • hadrian/cfg/default.host.target.in
    ... ... @@ -38,5 +38,10 @@ Target
    38 38
     , tgtRanlib = Nothing
    
    39 39
     , tgtNm = Nm {nmProgram = Program {prgPath = "", prgFlags = []}}
    
    40 40
     , tgtMergeObjs = Just (MergeObjs {mergeObjsProgram = Program {prgPath = "@LD_STAGE0@", prgFlags = ["-r"]}, mergeObjsSupportsResponseFiles = False})
    
    41
    +, tgtLlc = Nothing
    
    42
    +, tgtOpt = Nothing
    
    43
    +, tgtLlvmAs = Nothing
    
    41 44
     , tgtWindres = Nothing
    
    45
    +, tgtOtool = Nothing
    
    46
    +, tgtInstallNameTool = Nothing
    
    42 47
     }

  • hadrian/cfg/default.target.in
    ... ... @@ -38,5 +38,10 @@ Target
    38 38
     , tgtRanlib = Just (Ranlib {ranlibProgram = Program {prgPath = "@RanlibCmd@", prgFlags = []}})
    
    39 39
     , tgtNm = Nm {nmProgram = Program {prgPath = "@NmCmd@", prgFlags = []}}
    
    40 40
     , tgtMergeObjs = @MergeObjsCmdMaybe@
    
    41
    +, tgtLlc = @LlcCmdMaybeProg@
    
    42
    +, tgtOpt = @OptCmdMaybeProg@
    
    43
    +, tgtLlvmAs = @LlvmAsCmdMaybeProg@
    
    41 44
     , tgtWindres = @WindresCmdMaybeProg@
    
    45
    +, tgtOtool = @OtoolCmdMaybeProg@
    
    46
    +, tgtInstallNameTool = @InstallNameToolCmdMaybeProg@
    
    42 47
     }

  • hadrian/cfg/system.config.in
    ... ... @@ -79,13 +79,6 @@ project-git-commit-id = @ProjectGitCommitId@
    79 79
     # generated by configure, to generated being by the build system. Many of these
    
    80 80
     # might become redundant.
    
    81 81
     # See Note [tooldir: How GHC finds mingw on Windows]
    
    82
    -
    
    83
    -settings-otool-command = @SettingsOtoolCommand@
    
    84
    -settings-install_name_tool-command = @SettingsInstallNameToolCommand@
    
    85
    -settings-llc-command = @SettingsLlcCommand@
    
    86
    -settings-opt-command = @SettingsOptCommand@
    
    87
    -settings-llvm-as-command = @SettingsLlvmAsCommand@
    
    88
    -settings-llvm-as-flags = @SettingsLlvmAsFlags@
    
    89 82
     settings-use-distro-mingw = @SettingsUseDistroMINGW@
    
    90 83
     
    
    91 84
     target-has-libm = @TargetHasLibm@
    

  • hadrian/src/Builder.hs
    ... ... @@ -34,7 +34,6 @@ import Base
    34 34
     import Context
    
    35 35
     import Oracles.Flag
    
    36 36
     import Oracles.Setting (setting, Setting(..))
    
    37
    -import Oracles.Setting (settingsFileSetting, ToolchainSetting(..))
    
    38 37
     import Packages
    
    39 38
     
    
    40 39
     import GHC.IO.Encoding (getFileSystemEncoding)
    
    ... ... @@ -240,7 +239,7 @@ instance H.Builder Builder where
    240 239
             Ghc _ st -> do
    
    241 240
                 root <- buildRoot
    
    242 241
                 unlitPath  <- builderPath Unlit
    
    243
    -            distro_mingw <- settingsFileSetting ToolchainSetting_DistroMinGW
    
    242
    +            distro_mingw <- lookupSystemConfig "settings-use-distro-mingw"
    
    244 243
                 libffi_adjustors <- useLibffiForAdjustors
    
    245 244
                 use_system_ffi <- flag UseSystemFfi
    
    246 245
     
    

  • hadrian/src/Oracles/Setting.hs
    ... ... @@ -2,7 +2,6 @@ module Oracles.Setting (
    2 2
         configFile,
    
    3 3
         -- * Settings
    
    4 4
         Setting (..), setting, getSetting,
    
    5
    -    ToolchainSetting (..), settingsFileSetting,
    
    6 5
     
    
    7 6
         -- * Helpers
    
    8 7
         ghcCanonVersion, cmdLineLengthLimit, targetSupportsRPaths, topDirectory,
    
    ... ... @@ -75,25 +74,6 @@ data Setting = CursesIncludeDir
    75 74
                  | BourneShell
    
    76 75
                  | EmsdkVersion
    
    77 76
     
    
    78
    --- TODO compute solely in Hadrian, removing these variables' definitions
    
    79
    --- from aclocal.m4 whenever they can be calculated from other variables
    
    80
    --- already fed into Hadrian.
    
    81
    -
    
    82
    --- | All 'ToolchainSetting's are computed by the ghc-toolchain utility for configuring toolchains.
    
    83
    --- This used to be defined by 'FP_SETTINGS' in aclocal.m4.
    
    84
    ---
    
    85
    --- TODO: We should be able to drop this completely, after moving all the toolchain settings to ghc-toolchain
    
    86
    --- Move to ghc-toolchain and to the Target files generated by configure and ghc-toolchain
    
    87
    --- * First we will get rid of DistroMinGW when we fix the windows build
    
    88
    -data ToolchainSetting
    
    89
    -    = ToolchainSetting_OtoolCommand
    
    90
    -    | ToolchainSetting_InstallNameToolCommand
    
    91
    -    | ToolchainSetting_LlcCommand
    
    92
    -    | ToolchainSetting_OptCommand
    
    93
    -    | ToolchainSetting_LlvmAsCommand
    
    94
    -    | ToolchainSetting_LlvmAsFlags
    
    95
    -    | ToolchainSetting_DistroMinGW
    
    96
    -
    
    97 77
     -- | Look up the value of a 'Setting' in @cfg/system.config@, tracking the
    
    98 78
     -- result.
    
    99 79
     setting :: Setting -> Action String
    
    ... ... @@ -134,20 +114,6 @@ setting key = lookupSystemConfig $ case key of
    134 114
         BourneShell        -> "bourne-shell"
    
    135 115
         EmsdkVersion       -> "emsdk-version"
    
    136 116
     
    
    137
    --- | Look up the value of a 'SettingList' in @cfg/system.config@, tracking the
    
    138
    --- result.
    
    139
    --- See Note [tooldir: How GHC finds mingw on Windows]
    
    140
    --- ROMES:TODO: This should be queryTargetTargetConfig
    
    141
    -settingsFileSetting :: ToolchainSetting -> Action String
    
    142
    -settingsFileSetting key = lookupSystemConfig $ case key of
    
    143
    -    ToolchainSetting_OtoolCommand           -> "settings-otool-command"
    
    144
    -    ToolchainSetting_InstallNameToolCommand -> "settings-install_name_tool-command"
    
    145
    -    ToolchainSetting_LlcCommand             -> "settings-llc-command"
    
    146
    -    ToolchainSetting_OptCommand             -> "settings-opt-command"
    
    147
    -    ToolchainSetting_LlvmAsCommand          -> "settings-llvm-as-command"
    
    148
    -    ToolchainSetting_LlvmAsFlags            -> "settings-llvm-as-flags"
    
    149
    -    ToolchainSetting_DistroMinGW            -> "settings-use-distro-mingw" -- ROMES:TODO: This option doesn't seem to be in ghc-toolchain yet. It corresponds to EnableDistroToolchain
    
    150
    -
    
    151 117
     -- | An expression that looks up the value of a 'Setting' in @cfg/system.config@,
    
    152 118
     -- tracking the result.
    
    153 119
     getSetting :: Setting -> Expr c b String
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -424,7 +424,7 @@ bindistRules = do
    424 424
         , interpolateSetting "LlvmMinVersion" LlvmMinVersion
    
    425 425
         , interpolateVar "LlvmTarget" $ getTarget tgtLlvmTarget
    
    426 426
         , interpolateSetting "ProjectVersion" ProjectVersion
    
    427
    -    , interpolateVar "SettingsUseDistroMINGW" $ settingsFileSetting ToolchainSetting_DistroMinGW
    
    427
    +    , interpolateVar "SettingsUseDistroMINGW" $ lookupSystemConfig "settings-use-distro-mingw"
    
    428 428
         , interpolateVar "TablesNextToCode" $ yesNo <$> getTarget tgtTablesNextToCode
    
    429 429
         , interpolateVar "TargetHasLibm" $ lookupSystemConfig "target-has-libm"
    
    430 430
         , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple
    
    ... ... @@ -508,9 +508,9 @@ generateSettings settingsFile = do
    508 508
             , ("ar flags",            queryTarget arFlags)
    
    509 509
             , ("ar supports at file", queryTarget arSupportsAtFile')
    
    510 510
             , ("ar supports -L",      queryTarget arSupportsDashL')
    
    511
    -        , ("ranlib command", queryTarget ranlibPath)
    
    512
    -        , ("otool command", expr $ settingsFileSetting ToolchainSetting_OtoolCommand)
    
    513
    -        , ("install_name_tool command", expr $ settingsFileSetting ToolchainSetting_InstallNameToolCommand)
    
    511
    +        , ("ranlib command",      queryTarget ranlibPath)
    
    512
    +        , ("otool command",       queryTarget otoolPath)
    
    513
    +        , ("install_name_tool command", queryTarget installNameToolPath)
    
    514 514
             , ("windres command", queryTarget (maybe "/bin/false" prgPath . tgtWindres)) -- TODO: /bin/false is not available on many distributions by default, but we keep it as it were before the ghc-toolchain patch. Fix-me.
    
    515 515
             , ("unlit command", ("$topdir/../bin/" <>) <$> expr (programName (ctx { Context.package = unlit })))
    
    516 516
             , ("cross compiling", expr $ yesNo <$> flag CrossCompiling)
    
    ... ... @@ -525,11 +525,11 @@ generateSettings settingsFile = do
    525 525
             , ("target has libm", expr $  lookupSystemConfig "target-has-libm")
    
    526 526
             , ("Unregisterised", queryTarget (yesNo . tgtUnregisterised))
    
    527 527
             , ("LLVM target", queryTarget tgtLlvmTarget)
    
    528
    -        , ("LLVM llc command", expr $ settingsFileSetting ToolchainSetting_LlcCommand)
    
    529
    -        , ("LLVM opt command", expr $ settingsFileSetting ToolchainSetting_OptCommand)
    
    530
    -        , ("LLVM llvm-as command", expr $ settingsFileSetting ToolchainSetting_LlvmAsCommand)
    
    531
    -        , ("LLVM llvm-as flags", expr $ settingsFileSetting ToolchainSetting_LlvmAsFlags)
    
    532
    -        , ("Use inplace MinGW toolchain", expr $ settingsFileSetting ToolchainSetting_DistroMinGW)
    
    528
    +        , ("LLVM llc command", queryTarget llcPath)
    
    529
    +        , ("LLVM opt command", queryTarget optPath)
    
    530
    +        , ("LLVM llvm-as command", queryTarget llvmAsPath)
    
    531
    +        , ("LLVM llvm-as flags", queryTarget llvmAsFlags)
    
    532
    +        , ("Use inplace MinGW toolchain", expr $ lookupSystemConfig "settings-use-distro-mingw")
    
    533 533
     
    
    534 534
             , ("target RTS linker only supports shared libraries", expr $ yesNo <$> targetRTSLinkerOnlySupportsSharedLibs)
    
    535 535
             , ("Use interpreter", expr $ yesNo <$> ghcWithInterpreter (predStage stage))
    
    ... ... @@ -571,10 +571,16 @@ generateSettings settingsFile = do
    571 571
         linkSupportsFilelist        = yesNo . ccLinkSupportsFilelist . tgtCCompilerLink
    
    572 572
         linkSupportsCompactUnwind   = yesNo . ccLinkSupportsCompactUnwind . tgtCCompilerLink
    
    573 573
         linkIsGnu                   = yesNo . ccLinkIsGnu . tgtCCompilerLink
    
    574
    +    llcPath = maybe "" prgPath . tgtLlc
    
    575
    +    optPath = maybe "" prgPath . tgtOpt
    
    576
    +    llvmAsPath = maybe "" prgPath . tgtLlvmAs
    
    577
    +    llvmAsFlags = escapeArgs . maybe [] prgFlags . tgtLlvmAs
    
    574 578
         arPath  = prgPath . arMkArchive . tgtAr
    
    575 579
         arFlags = escapeArgs . prgFlags . arMkArchive . tgtAr
    
    576 580
         arSupportsAtFile' = yesNo . arSupportsAtFile . tgtAr
    
    577 581
         arSupportsDashL' = yesNo . arSupportsDashL . tgtAr
    
    582
    +    otoolPath = maybe "" prgPath . tgtOtool
    
    583
    +    installNameToolPath = maybe "" prgPath . tgtInstallNameTool
    
    578 584
         ranlibPath  = maybe "" (prgPath . ranlibProgram) . tgtRanlib
    
    579 585
         mergeObjsSupportsResponseFiles' = maybe "NO" (yesNo . mergeObjsSupportsResponseFiles) . tgtMergeObjs
    
    580 586
     
    

  • hadrian/src/Settings/Builders/RunTest.hs
    ... ... @@ -127,9 +127,9 @@ inTreeCompilerArgs stg = do
    127 127
         platform    <- queryTargetTarget targetPlatformTriple
    
    128 128
         wordsize    <- show @Int . (*8) <$> queryTargetTarget (wordSize2Bytes . tgtWordSize)
    
    129 129
     
    
    130
    -    llc_cmd   <- settingsFileSetting ToolchainSetting_LlcCommand
    
    131
    -    llvm_as_cmd <- settingsFileSetting ToolchainSetting_LlvmAsCommand
    
    132
    -    have_llvm <- liftIO (all isJust <$> mapM findExecutable [llc_cmd, llvm_as_cmd])
    
    130
    +    llc_cmd   <- queryTargetTarget tgtLlc
    
    131
    +    llvm_as_cmd <- queryTargetTarget tgtLlvmAs
    
    132
    +    let have_llvm = all isJust [llc_cmd, llvm_as_cmd]
    
    133 133
     
    
    134 134
         top         <- topDirectory
    
    135 135
     
    

  • m4/fp_settings.m4
    ... ... @@ -136,14 +136,7 @@ AC_DEFUN([FP_SETTINGS],
    136 136
         fi
    
    137 137
     
    
    138 138
         # Mac-only tools
    
    139
    -    if test -z "$OtoolCmd"; then
    
    140
    -        OtoolCmd="otool"
    
    141
    -    fi
    
    142 139
         SettingsOtoolCommand="$OtoolCmd"
    
    143
    -
    
    144
    -    if test -z "$InstallNameToolCmd"; then
    
    145
    -        InstallNameToolCmd="install_name_tool"
    
    146
    -    fi
    
    147 140
         SettingsInstallNameToolCommand="$InstallNameToolCmd"
    
    148 141
     
    
    149 142
         SettingsCCompilerSupportsNoPie="$CONF_GCC_SUPPORTS_NO_PIE"
    

  • m4/ghc_toolchain.m4
    ... ... @@ -107,6 +107,9 @@ AC_DEFUN([FIND_GHC_TOOLCHAIN],
    107 107
         echo "--merge-objs=$MergeObjsCmd" >> acargs
    
    108 108
         echo "--readelf=$READELF" >> acargs
    
    109 109
         echo "--windres=$WindresCmd" >> acargs
    
    110
    +    echo "--llc=$LlcCmd" >> acargs
    
    111
    +    echo "--opt=$OptCmd" >> acargs
    
    112
    +    echo "--llvm-as=$LlvmAsCmd" >> acargs
    
    110 113
     
    
    111 114
         if test -n "$USER_LD"; then
    
    112 115
           echo "--ld=$USER_LD" >> acargs
    

  • m4/prep_target_file.m4
    ... ... @@ -10,6 +10,38 @@
    10 10
     # This toolchain will additionally be used to validate the one generated by
    
    11 11
     # ghc-toolchain. See Note [ghc-toolchain consistency checking].
    
    12 12
     
    
    13
    +# PREP_LIST
    
    14
    +# ============
    
    15
    +#
    
    16
    +# Issue a substitution with ["list","of","args"] of [$1List] when $1 is a
    
    17
    +# space-separated list of args
    
    18
    +# i.e.
    
    19
    +# "arg1 arg2 arg3"
    
    20
    +# ==>
    
    21
    +# ["arg1","arg2","arg3"]
    
    22
    +#
    
    23
    +# $1 = list variable to substitute
    
    24
    +dnl In autoconf, '@<:@' stands for '[', and '@:>@' for ']'.
    
    25
    +AC_DEFUN([PREP_LIST],[
    
    26
    +    # shell array
    
    27
    +    set -- $$1
    
    28
    +    $1List="@<:@"
    
    29
    +    if test "[$]#" -eq 0; then
    
    30
    +        # no arguments
    
    31
    +        true
    
    32
    +    else
    
    33
    +        $1List="${$1List}\"[$]1\""
    
    34
    +        shift # drop first elem
    
    35
    +        for arg in "[$]@"
    
    36
    +        do
    
    37
    +            $1List="${$1List},\"$arg\""
    
    38
    +        done
    
    39
    +    fi
    
    40
    +    $1List="${$1List}@:>@"
    
    41
    +
    
    42
    +    AC_SUBST([$1List])
    
    43
    +])
    
    44
    +
    
    13 45
     # PREP_MAYBE_SIMPLE_PROGRAM
    
    14 46
     # =========================
    
    15 47
     #
    
    ... ... @@ -27,6 +59,25 @@ AC_DEFUN([PREP_MAYBE_SIMPLE_PROGRAM],[
    27 59
         AC_SUBST([$1MaybeProg])
    
    28 60
     ])
    
    29 61
     
    
    62
    +# PREP_MAYBE_PROGRAM
    
    63
    +# =========================
    
    64
    +#
    
    65
    +# Introduce a substitution [$1MaybeProg] with
    
    66
    +# * Nothing, if $$1 is empty
    
    67
    +# * Just (Program {prgPath = "$$1", prgFlags = [elements of $$2]}), otherwise
    
    68
    +#
    
    69
    +# $1 = optional program path
    
    70
    +# $2 = program arguments
    
    71
    +AC_DEFUN([PREP_MAYBE_PROGRAM],[
    
    72
    +    if test -z "$$1"; then
    
    73
    +        $1MaybeProg=Nothing
    
    74
    +    else
    
    75
    +        PREP_LIST([$2])
    
    76
    +        $1MaybeProg="Just (Program {prgPath = \"$$1\", prgFlags = $$2List})"
    
    77
    +    fi
    
    78
    +    AC_SUBST([$1MaybeProg])
    
    79
    +])
    
    80
    +
    
    30 81
     # PREP_MAYBE_STRING
    
    31 82
     # =========================
    
    32 83
     #
    
    ... ... @@ -86,38 +137,6 @@ AC_DEFUN([PREP_NOT_BOOLEAN],[
    86 137
         AC_SUBST([Not$1Bool])
    
    87 138
     ])
    
    88 139
     
    
    89
    -# PREP_LIST
    
    90
    -# ============
    
    91
    -#
    
    92
    -# Issue a substitution with ["list","of","args"] of [$1List] when $1 is a
    
    93
    -# space-separated list of args
    
    94
    -# i.e.
    
    95
    -# "arg1 arg2 arg3"
    
    96
    -# ==>
    
    97
    -# ["arg1","arg2","arg3"]
    
    98
    -#
    
    99
    -# $1 = list variable to substitute
    
    100
    -dnl In autoconf, '@<:@' stands for '[', and '@:>@' for ']'.
    
    101
    -AC_DEFUN([PREP_LIST],[
    
    102
    -    # shell array
    
    103
    -    set -- $$1
    
    104
    -    $1List="@<:@"
    
    105
    -    if test "[$]#" -eq 0; then
    
    106
    -        # no arguments
    
    107
    -        true
    
    108
    -    else
    
    109
    -        $1List="${$1List}\"[$]1\""
    
    110
    -        shift # drop first elem
    
    111
    -        for arg in "[$]@"
    
    112
    -        do
    
    113
    -            $1List="${$1List},\"$arg\""
    
    114
    -        done
    
    115
    -    fi
    
    116
    -    $1List="${$1List}@:>@"
    
    117
    -
    
    118
    -    AC_SUBST([$1List])
    
    119
    -])
    
    120
    -
    
    121 140
     # Eventually: PREP_BUILD_TARGET_FILE, PREP_HOST_TARGET_FILE, PREP_TARGET_TARGET_FILE
    
    122 141
     # Prepares required substitutions to generate the target file
    
    123 142
     AC_DEFUN([PREP_TARGET_FILE],[
    
    ... ... @@ -148,7 +167,12 @@ AC_DEFUN([PREP_TARGET_FILE],[
    148 167
         PREP_LIST([JavaScriptCPPArgs])
    
    149 168
         PREP_LIST([CmmCPPArgs])
    
    150 169
         PREP_LIST([CmmCPPArgs_STAGE0])
    
    170
    +    PREP_MAYBE_SIMPLE_PROGRAM([LlcCmd])
    
    171
    +    PREP_MAYBE_SIMPLE_PROGRAM([OptCmd])
    
    172
    +    PREP_MAYBE_PROGRAM([LlvmAsCmd], [LlvmAsFlags])
    
    151 173
         PREP_MAYBE_SIMPLE_PROGRAM([WindresCmd])
    
    174
    +    PREP_MAYBE_SIMPLE_PROGRAM([OtoolCmd])
    
    175
    +    PREP_MAYBE_SIMPLE_PROGRAM([InstallNameToolCmd])
    
    152 176
         PREP_MAYBE_STRING([TargetVendor_CPP])
    
    153 177
         PREP_MAYBE_STRING([HostVendor_CPP])
    
    154 178
         PREP_LIST([CONF_CPP_OPTS_STAGE2])
    

  • rts/linker/LoadArchive.c
    ... ... @@ -33,6 +33,7 @@
    33 33
     
    
    34 34
     #define DEBUG_LOG(...) IF_DEBUG(linker, debugBelch("loadArchive: " __VA_ARGS__))
    
    35 35
     
    
    36
    +
    
    36 37
     #if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
    
    37 38
     /* Read 4 bytes and convert to host byte order */
    
    38 39
     static uint32_t read4Bytes(const char buf[static 4])
    
    ... ... @@ -40,7 +41,7 @@ static uint32_t read4Bytes(const char buf[static 4])
    40 41
         return ntohl(*(uint32_t*)buf);
    
    41 42
     }
    
    42 43
     
    
    43
    -static StgBool loadFatArchive(char tmp[static 20], FILE* f, pathchar* path)
    
    44
    +static bool loadFatArchive(char input[static 20], FILE* f, pathchar* path)
    
    44 45
     {
    
    45 46
         uint32_t nfat_arch, nfat_offset, cputype, cpusubtype;
    
    46 47
     #if defined(i386_HOST_ARCH)
    
    ... ... @@ -58,8 +59,9 @@ static StgBool loadFatArchive(char tmp[static 20], FILE* f, pathchar* path)
    58 59
     #error Unknown Darwin architecture
    
    59 60
     #endif
    
    60 61
     
    
    61
    -    nfat_arch = read4Bytes(tmp + 4);
    
    62
    +    nfat_arch = read4Bytes(input + 4);
    
    62 63
         DEBUG_LOG("found a fat archive containing %d architectures\n", nfat_arch);
    
    64
    +    char tmp[20];
    
    63 65
         nfat_offset = 0;
    
    64 66
         for (uint32_t i = 0; i < nfat_arch; i++) {
    
    65 67
             /* search for the right arch */
    
    ... ... @@ -90,6 +92,7 @@ static StgBool loadFatArchive(char tmp[static 20], FILE* f, pathchar* path)
    90 92
             }
    
    91 93
     
    
    92 94
             /* Read the header */
    
    95
    +        char tmp[20];
    
    93 96
             n = fread(tmp, 1, 8, f);
    
    94 97
             if (n != 8) {
    
    95 98
                 errorBelch("Failed reading header from `%" PATH_FMT "'", path);
    
    ... ... @@ -107,10 +110,51 @@ static StgBool loadFatArchive(char tmp[static 20], FILE* f, pathchar* path)
    107 110
     }
    
    108 111
     #endif
    
    109 112
     
    
    110
    -static StgBool readThinArchiveMember(int n, int memberSize, pathchar* path,
    
    113
    +enum ObjectFileFormat {
    
    114
    +    NotObject,
    
    115
    +    COFFAmd64,
    
    116
    +    COFFI386,
    
    117
    +    COFFAArch64,
    
    118
    +    ELF,
    
    119
    +    MachO32,
    
    120
    +    MachO64,
    
    121
    +};
    
    122
    +
    
    123
    +static enum ObjectFileFormat identifyObjectFile_(char* buf, size_t sz)
    
    124
    +{
    
    125
    +    if (sz > 2 && ((uint16_t*)buf)[0] == 0x8664) {
    
    126
    +        return COFFAmd64;
    
    127
    +    }
    
    128
    +    if (sz > 2 && ((uint16_t*)buf)[0] == 0x014c) {
    
    129
    +        return COFFI386;
    
    130
    +    }
    
    131
    +    if (sz > 2 && ((uint16_t*)buf)[0] == 0xaa64) {
    
    132
    +        return COFFAArch64;
    
    133
    +    }
    
    134
    +    if (sz > 4 && memcmp(buf, "\x7f" "ELF", 4) == 0) {
    
    135
    +        return ELF;
    
    136
    +    }
    
    137
    +    if (sz > 4 && ((uint32_t*)buf)[0] == 0xfeedface) {
    
    138
    +        return MachO32;
    
    139
    +    }
    
    140
    +    if (sz > 4 && ((uint32_t*)buf)[0] == 0xfeedfacf) {
    
    141
    +        return MachO64;
    
    142
    +    }
    
    143
    +    return NotObject;
    
    144
    +}
    
    145
    +
    
    146
    +static enum ObjectFileFormat identifyObjectFile(FILE *f)
    
    147
    +{
    
    148
    +    char buf[32];
    
    149
    +    ssize_t sz = fread(buf, 1, 32, f);
    
    150
    +    CHECK(fseek(f, -sz, SEEK_CUR) == 0);
    
    151
    +    return identifyObjectFile_(buf, sz);
    
    152
    +}
    
    153
    +
    
    154
    +static bool readThinArchiveMember(int n, int memberSize, pathchar* path,
    
    111 155
             char* fileName, char* image)
    
    112 156
     {
    
    113
    -    StgBool has_succeeded = false;
    
    157
    +    bool has_succeeded = false;
    
    114 158
         FILE* member = NULL;
    
    115 159
         pathchar *pathCopy, *dirName, *memberPath, *objFileName;
    
    116 160
         memberPath = NULL;
    
    ... ... @@ -148,10 +192,9 @@ inner_fail:
    148 192
         return has_succeeded;
    
    149 193
     }
    
    150 194
     
    
    151
    -static StgBool checkFatArchive(char magic[static 20], FILE* f, pathchar* path)
    
    195
    +static bool checkFatArchive(char magic[static 4], FILE* f, pathchar* path)
    
    152 196
     {
    
    153
    -    StgBool success;
    
    154
    -    success = false;
    
    197
    +    bool success = false;
    
    155 198
     #if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
    
    156 199
         /* Not a standard archive, look for a fat archive magic number: */
    
    157 200
         if (read4Bytes(magic) == FAT_MAGIC)
    
    ... ... @@ -175,7 +218,7 @@ static StgBool checkFatArchive(char magic[static 20], FILE* f, pathchar* path)
    175 218
      * be reallocated on return; the old value is now _invalid_.
    
    176 219
      * @param gnuFileIndexSize The size of the index.
    
    177 220
      */
    
    178
    -static StgBool
    
    221
    +static bool
    
    179 222
     lookupGNUArchiveIndex(int gnuFileIndexSize, char **fileName_,
    
    180 223
         char* gnuFileIndex, pathchar* path, size_t* thisFileNameSize,
    
    181 224
         size_t* fileNameSize)
    
    ... ... @@ -241,47 +284,21 @@ lookupGNUArchiveIndex(int gnuFileIndexSize, char **fileName_,
    241 284
         return true;
    
    242 285
     }
    
    243 286
     
    
    244
    -HsInt loadArchive_ (pathchar *path)
    
    245
    -{
    
    246
    -    char *image = NULL;
    
    247
    -    HsInt retcode = 0;
    
    248
    -    int memberSize;
    
    249
    -    int memberIdx = 0;
    
    250
    -    FILE *f = NULL;
    
    251
    -    int n;
    
    252
    -    size_t thisFileNameSize = (size_t)-1; /* shut up bogus GCC warning */
    
    253
    -    char *fileName;
    
    254
    -    size_t fileNameSize;
    
    255
    -    int isObject, isGnuIndex, isThin, isImportLib;
    
    256
    -    char tmp[20];
    
    257
    -    char *gnuFileIndex;
    
    258
    -    int gnuFileIndexSize;
    
    259
    -    int misalignment = 0;
    
    260
    -
    
    261
    -    DEBUG_LOG("start\n");
    
    262
    -    DEBUG_LOG("Loading archive `%" PATH_FMT "'\n", path);
    
    287
    +enum ArchiveFormat {
    
    288
    +    StandardArchive,
    
    289
    +    ThinArchive,
    
    290
    +    FatArchive,
    
    291
    +};
    
    263 292
     
    
    264
    -    /* Check that we haven't already loaded this archive.
    
    265
    -       Ignore requests to load multiple times */
    
    266
    -    if (isAlreadyLoaded(path)) {
    
    267
    -        IF_DEBUG(linker,
    
    268
    -                 debugBelch("ignoring repeated load of %" PATH_FMT "\n", path));
    
    269
    -        return 1; /* success */
    
    293
    +static bool identifyArchiveFormat(FILE *f, pathchar *path, enum ArchiveFormat *out)
    
    294
    +{
    
    295
    +    char tmp[8];
    
    296
    +    size_t n = fread(tmp, 1, 8, f);
    
    297
    +    if (n != 8) {
    
    298
    +        errorBelch("loadArchive: Failed reading header from `%" PATH_FMT "'", path); \
    
    299
    +        return false;
    
    270 300
         }
    
    271 301
     
    
    272
    -    gnuFileIndex = NULL;
    
    273
    -    gnuFileIndexSize = 0;
    
    274
    -
    
    275
    -    fileNameSize = 32;
    
    276
    -    fileName = stgMallocBytes(fileNameSize, "loadArchive(fileName)");
    
    277
    -
    
    278
    -    isThin = 0;
    
    279
    -    isImportLib = 0;
    
    280
    -
    
    281
    -    f = pathopen(path, WSTR("rb"));
    
    282
    -    if (!f)
    
    283
    -        FAIL("loadObj: can't read `%" PATH_FMT "'", path);
    
    284
    -
    
    285 302
         /* Check if this is an archive by looking for the magic "!<arch>\n"
    
    286 303
          * string.  Usually, if this fails, we belch an error and return.  On
    
    287 304
          * Darwin however, we may have a fat archive, which contains archives for
    
    ... ... @@ -300,12 +317,10 @@ HsInt loadArchive_ (pathchar *path)
    300 317
          * its magic "!<arch>\n" string and continue processing just as if
    
    301 318
          * we had a single architecture archive.
    
    302 319
          */
    
    303
    -
    
    304
    -    n = fread ( tmp, 1, 8, f );
    
    305
    -    if (n != 8) {
    
    306
    -        FAIL("Failed reading header from `%" PATH_FMT "'", path);
    
    320
    +    if (strncmp(tmp, "!<arch>\n", 8) == 0) {
    
    321
    +        *out = StandardArchive;
    
    322
    +        return true;
    
    307 323
         }
    
    308
    -    if (strncmp(tmp, "!<arch>\n", 8) == 0) {}
    
    309 324
         /* Check if this is a thin archive by looking for the magic string "!<thin>\n"
    
    310 325
          *
    
    311 326
          * ar thin libraries have the exact same format as normal archives except they
    
    ... ... @@ -322,16 +337,59 @@ HsInt loadArchive_ (pathchar *path)
    322 337
          *
    
    323 338
          */
    
    324 339
         else if (strncmp(tmp, "!<thin>\n", 8) == 0) {
    
    325
    -        isThin = 1;
    
    340
    +        *out = ThinArchive;
    
    341
    +        return true;
    
    326 342
         }
    
    327 343
         else {
    
    328
    -        StgBool success = checkFatArchive(tmp, f, path);
    
    329
    -        if (!success)
    
    330
    -            goto fail;
    
    344
    +        bool success = checkFatArchive(tmp, f, path);
    
    345
    +        if (!success) {
    
    346
    +            return false;
    
    347
    +        }
    
    348
    +        *out = FatArchive;
    
    349
    +        return true;
    
    331 350
         }
    
    351
    +}
    
    352
    +
    
    353
    +HsInt loadArchive_ (pathchar *path)
    
    354
    +{
    
    355
    +    char *image = NULL;
    
    356
    +    HsInt retcode = 0;
    
    357
    +    int memberIdx = 0;
    
    358
    +    FILE *f = NULL;
    
    359
    +    size_t thisFileNameSize = (size_t) -1; /* shut up bogus GCC warning */
    
    360
    +    int misalignment = 0;
    
    361
    +
    
    362
    +    DEBUG_LOG("start\n");
    
    363
    +    DEBUG_LOG("Loading archive `%" PATH_FMT "'\n", path);
    
    364
    +
    
    365
    +    /* Check that we haven't already loaded this archive.
    
    366
    +       Ignore requests to load multiple times */
    
    367
    +    if (isAlreadyLoaded(path)) {
    
    368
    +        IF_DEBUG(linker,
    
    369
    +                 debugBelch("ignoring repeated load of %" PATH_FMT "\n", path));
    
    370
    +        return 1; /* success */
    
    371
    +    }
    
    372
    +
    
    373
    +    char *gnuFileIndex = NULL;
    
    374
    +    int gnuFileIndexSize = 0;
    
    375
    +
    
    376
    +    size_t fileNameSize = 32;
    
    377
    +    char *fileName = stgMallocBytes(fileNameSize, "loadArchive(fileName)");
    
    378
    +
    
    379
    +    f = pathopen(path, WSTR("rb"));
    
    380
    +    if (!f)
    
    381
    +        FAIL("loadObj: can't read `%" PATH_FMT "'", path);
    
    382
    +
    
    383
    +    enum ArchiveFormat archive_fmt;
    
    384
    +    if (!identifyArchiveFormat(f, path, &archive_fmt)) {
    
    385
    +        FAIL("failed to identify archive format of %" PATH_FMT ".", path);
    
    386
    +    }
    
    387
    +    bool isThin = archive_fmt == ThinArchive;
    
    388
    +
    
    332 389
         DEBUG_LOG("loading archive contents\n");
    
    333 390
     
    
    334 391
         while (1) {
    
    392
    +        size_t n;
    
    335 393
             DEBUG_LOG("reading at %ld\n", ftell(f));
    
    336 394
             n = fread ( fileName, 1, 16, f );
    
    337 395
             if (n != 16) {
    
    ... ... @@ -351,6 +409,7 @@ HsInt loadArchive_ (pathchar *path)
    351 409
             }
    
    352 410
     #endif
    
    353 411
     
    
    412
    +        char tmp[32];
    
    354 413
             n = fread ( tmp, 1, 12, f );
    
    355 414
             if (n != 12)
    
    356 415
                 FAIL("Failed reading mod time from `%" PATH_FMT "'", path);
    
    ... ... @@ -369,9 +428,16 @@ HsInt loadArchive_ (pathchar *path)
    369 428
             tmp[10] = '\0';
    
    370 429
             for (n = 0; isdigit(tmp[n]); n++);
    
    371 430
             tmp[n] = '\0';
    
    372
    -        memberSize = atoi(tmp);
    
    431
    +        size_t memberSize;
    
    432
    +        {
    
    433
    +            char *end;
    
    434
    +            memberSize = strtol(tmp, &end, 10);
    
    435
    +            if (tmp == end) {
    
    436
    +                FAIL("Failed to decode member size");
    
    437
    +            }
    
    438
    +        }
    
    373 439
     
    
    374
    -        DEBUG_LOG("size of this archive member is %d\n", memberSize);
    
    440
    +        DEBUG_LOG("size of this archive member is %zd\n", memberSize);
    
    375 441
             n = fread ( tmp, 1, 2, f );
    
    376 442
             if (n != 2)
    
    377 443
                 FAIL("Failed reading magic from `%" PATH_FMT "'", path);
    
    ... ... @@ -379,7 +445,7 @@ HsInt loadArchive_ (pathchar *path)
    379 445
                 FAIL("Failed reading magic from `%" PATH_FMT "' at %ld. Got %c%c",
    
    380 446
                      path, ftell(f), tmp[0], tmp[1]);
    
    381 447
     
    
    382
    -        isGnuIndex = 0;
    
    448
    +        bool isGnuIndex = false;
    
    383 449
             /* Check for BSD-variant large filenames */
    
    384 450
             if (0 == strncmp(fileName, "#1/", 3)) {
    
    385 451
                 size_t n = 0;
    
    ... ... @@ -419,7 +485,7 @@ HsInt loadArchive_ (pathchar *path)
    419 485
             else if (0 == strncmp(fileName, "//", 2)) {
    
    420 486
                 fileName[0] = '\0';
    
    421 487
                 thisFileNameSize = 0;
    
    422
    -            isGnuIndex = 1;
    
    488
    +            isGnuIndex = true;
    
    423 489
             }
    
    424 490
             /* Check for a file in the GNU file index */
    
    425 491
             else if (fileName[0] == '/') {
    
    ... ... @@ -460,12 +526,8 @@ HsInt loadArchive_ (pathchar *path)
    460 526
     
    
    461 527
             DEBUG_LOG("Found member file `%s'\n", fileName);
    
    462 528
     
    
    463
    -        /* TODO: Stop relying on file extensions to determine input formats.
    
    464
    -                 Instead try to match file headers. See #13103.  */
    
    465
    -        isObject = (thisFileNameSize >= 2 && strncmp(fileName + thisFileNameSize - 2, ".o"  , 2) == 0)
    
    466
    -                || (thisFileNameSize >= 3 && strncmp(fileName + thisFileNameSize - 3, ".lo" , 3) == 0)
    
    467
    -                || (thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".p_o", 4) == 0)
    
    468
    -                || (thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".obj", 4) == 0);
    
    529
    +        bool is_symbol_table = strcmp("", fileName) == 0;
    
    530
    +        enum ObjectFileFormat object_fmt = is_symbol_table ? NotObject : identifyObjectFile(f);
    
    469 531
     
    
    470 532
     #if defined(OBJFORMAT_PEi386)
    
    471 533
             /*
    
    ... ... @@ -479,15 +541,15 @@ HsInt loadArchive_ (pathchar *path)
    479 541
             *
    
    480 542
             * Linker members (e.g. filename / are skipped since they are not needed)
    
    481 543
             */
    
    482
    -        isImportLib = thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".dll", 4) == 0;
    
    544
    +        bool isImportLib = thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".dll", 4) == 0;
    
    545
    +#else
    
    546
    +        bool isImportLib = false;
    
    483 547
     #endif // windows
    
    484 548
     
    
    485 549
             DEBUG_LOG("\tthisFileNameSize = %d\n", (int)thisFileNameSize);
    
    486
    -        DEBUG_LOG("\tisObject = %d\n", isObject);
    
    487
    -
    
    488
    -        if (isObject) {
    
    489
    -            pathchar *archiveMemberName;
    
    550
    +        DEBUG_LOG("\tisObject = %d\n", object_fmt);
    
    490 551
     
    
    552
    +        if ((!is_symbol_table && isThin) || object_fmt != NotObject) {
    
    491 553
                 DEBUG_LOG("Member is an object file...loading...\n");
    
    492 554
     
    
    493 555
     #if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
    
    ... ... @@ -505,14 +567,13 @@ HsInt loadArchive_ (pathchar *path)
    505 567
                 image = stgMallocBytes(memberSize, "loadArchive(image)");
    
    506 568
     #endif
    
    507 569
                 if (isThin) {
    
    508
    -                if (!readThinArchiveMember(n, memberSize, path,
    
    509
    -                        fileName, image)) {
    
    570
    +                if (!readThinArchiveMember(n, memberSize, path, fileName, image)) {
    
    510 571
                         goto fail;
    
    511 572
                     }
    
    512 573
                 }
    
    513 574
                 else
    
    514 575
                 {
    
    515
    -                n = fread ( image, 1, memberSize, f );
    
    576
    +                size_t n = fread ( image, 1, memberSize, f );
    
    516 577
                     if (n != memberSize) {
    
    517 578
                         FAIL("error whilst reading `%" PATH_FMT "'", path);
    
    518 579
                     }
    
    ... ... @@ -523,16 +584,18 @@ HsInt loadArchive_ (pathchar *path)
    523 584
                 // I don't understand why this extra +1 is needed here; pathprintf
    
    524 585
                 // should have given us the correct length but in practice it seems
    
    525 586
                 // to be one byte short on Win32.
    
    526
    -            archiveMemberName = stgMallocBytes((size+1+1) * sizeof(pathchar), "loadArchive(file)");
    
    587
    +            pathchar *archiveMemberName = stgMallocBytes((size+1+1) * sizeof(pathchar), "loadArchive(file)");
    
    527 588
                 pathprintf(archiveMemberName, size+1, WSTR("%" PATH_FMT "(#%d:%.*s)"),
    
    528 589
                            path, memberIdx, (int)thisFileNameSize, fileName);
    
    529 590
     
    
    530 591
                 ObjectCode *oc = mkOc(STATIC_OBJECT, path, image, memberSize, false, archiveMemberName,
    
    531 592
                                       misalignment);
    
    532 593
     #if defined(OBJFORMAT_MACHO)
    
    594
    +            ASSERT(object_fmt == MachO32 || object_fmt == MachO64);
    
    533 595
                 ocInit_MachO( oc );
    
    534 596
     #endif
    
    535 597
     #if defined(OBJFORMAT_ELF)
    
    598
    +            ASSERT(object_fmt == ELF);
    
    536 599
                 ocInit_ELF( oc );
    
    537 600
     #endif
    
    538 601
     
    
    ... ... @@ -577,7 +640,7 @@ while reading filename from `%" PATH_FMT "'", path);
    577 640
                               "Skipping...\n");
    
    578 641
                     n = fseek(f, memberSize, SEEK_CUR);
    
    579 642
                     if (n != 0)
    
    580
    -                    FAIL("error whilst seeking by %d in `%" PATH_FMT "'",
    
    643
    +                    FAIL("error whilst seeking by %zd in `%" PATH_FMT "'",
    
    581 644
                         memberSize, path);
    
    582 645
                 }
    
    583 646
     #endif
    
    ... ... @@ -588,7 +651,7 @@ while reading filename from `%" PATH_FMT "'", path);
    588 651
                 if (!isThin || thisFileNameSize == 0) {
    
    589 652
                     n = fseek(f, memberSize, SEEK_CUR);
    
    590 653
                     if (n != 0)
    
    591
    -                    FAIL("error whilst seeking by %d in `%" PATH_FMT "'",
    
    654
    +                    FAIL("error whilst seeking by %zd in `%" PATH_FMT "'",
    
    592 655
                              memberSize, path);
    
    593 656
                 }
    
    594 657
             }
    

  • utils/ghc-toolchain/exe/Main.hs
    ... ... @@ -52,7 +52,12 @@ data Opts = Opts
    52 52
         , optNm        :: ProgOpt
    
    53 53
         , optReadelf   :: ProgOpt
    
    54 54
         , optMergeObjs :: ProgOpt
    
    55
    +    , optLlc       :: ProgOpt
    
    56
    +    , optOpt       :: ProgOpt
    
    57
    +    , optLlvmAs    :: ProgOpt
    
    55 58
         , optWindres   :: ProgOpt
    
    59
    +    , optOtool     :: ProgOpt
    
    60
    +    , optInstallNameTool :: ProgOpt
    
    56 61
         -- Note we don't actually configure LD into anything but
    
    57 62
         -- see #23857 and #22550 for the very unfortunate story.
    
    58 63
         , optLd        :: ProgOpt
    
    ... ... @@ -99,8 +104,13 @@ emptyOpts = Opts
    99 104
         , optNm        = po0
    
    100 105
         , optReadelf   = po0
    
    101 106
         , optMergeObjs = po0
    
    107
    +    , optLlc       = po0
    
    108
    +    , optOpt       = po0
    
    109
    +    , optLlvmAs    = po0
    
    102 110
         , optWindres   = po0
    
    103 111
         , optLd        = po0
    
    112
    +    , optOtool     = po0
    
    113
    +    , optInstallNameTool = po0
    
    104 114
         , optUnregisterised = Nothing
    
    105 115
         , optTablesNextToCode = Nothing
    
    106 116
         , optUseLibFFIForAdjustors = Nothing
    
    ... ... @@ -112,7 +122,8 @@ emptyOpts = Opts
    112 122
         po0 = emptyProgOpt
    
    113 123
     
    
    114 124
     _optCc, _optCxx, _optCpp, _optHsCpp, _optJsCpp, _optCmmCpp, _optCcLink, _optAr,
    
    115
    -    _optRanlib, _optNm, _optReadelf, _optMergeObjs, _optWindres, _optLd
    
    125
    +    _optRanlib, _optNm, _optReadelf, _optMergeObjs, _optLlc, _optOpt, _optLlvmAs,
    
    126
    +    _optWindres, _optLd, _optOtool, _optInstallNameTool
    
    116 127
         :: Lens Opts ProgOpt
    
    117 128
     _optCc      = Lens optCc      (\x o -> o {optCc=x})
    
    118 129
     _optCxx     = Lens optCxx     (\x o -> o {optCxx=x})
    
    ... ... @@ -126,8 +137,13 @@ _optRanlib = Lens optRanlib (\x o -> o {optRanlib=x})
    126 137
     _optNm      = Lens optNm      (\x o -> o {optNm=x})
    
    127 138
     _optReadelf = Lens optReadelf (\x o -> o {optReadelf=x})
    
    128 139
     _optMergeObjs = Lens optMergeObjs (\x o -> o {optMergeObjs=x})
    
    140
    +_optLlc     = Lens optLlc     (\x o -> o {optLlc=x})
    
    141
    +_optOpt     = Lens optOpt     (\x o -> o {optOpt=x})
    
    142
    +_optLlvmAs  = Lens optLlvmAs  (\x o -> o {optLlvmAs=x})
    
    129 143
     _optWindres = Lens optWindres (\x o -> o {optWindres=x})
    
    130
    -_optLd = Lens optLd (\x o -> o {optLd= x})
    
    144
    +_optLd      = Lens optLd (\x o -> o {optLd=x})
    
    145
    +_optOtool   = Lens optOtool (\x o -> o {optOtool=x})
    
    146
    +_optInstallNameTool = Lens optInstallNameTool (\x o -> o {optInstallNameTool=x})
    
    131 147
     
    
    132 148
     _optTriple :: Lens Opts (Maybe String)
    
    133 149
     _optTriple = Lens optTriple (\x o -> o {optTriple=x})
    
    ... ... @@ -183,8 +199,13 @@ options =
    183 199
         , progOpts "nm" "nm archiver" _optNm
    
    184 200
         , progOpts "readelf" "readelf utility" _optReadelf
    
    185 201
         , progOpts "merge-objs" "linker for merging objects" _optMergeObjs
    
    202
    +    , progOpts "llc" "LLVM llc utility" _optLlc
    
    203
    +    , progOpts "opt" "LLVM opt utility" _optOpt
    
    204
    +    , progOpts "llvm-as" "Assembler used for LLVM backend (typically clang)" _optLlvmAs
    
    186 205
         , progOpts "windres" "windres utility" _optWindres
    
    187 206
         , progOpts "ld" "linker" _optLd
    
    207
    +    , progOpts "otool" "otool utility" _optOtool
    
    208
    +    , progOpts "install-name-tool" "install-name-tool utility" _optInstallNameTool
    
    188 209
         ]
    
    189 210
       where
    
    190 211
         progOpts :: String -> String -> Lens Opts ProgOpt -> [OptDescr (Opts -> Opts)]
    
    ... ... @@ -436,6 +457,11 @@ mkTarget opts = do
    436 457
         when (isNothing mergeObjs && not (arSupportsDashL ar)) $
    
    437 458
           throwE "Neither a object-merging tool (e.g. ld -r) nor an ar that supports -L is available"
    
    438 459
     
    
    460
    +    -- LLVM toolchain
    
    461
    +    llc <- optional $ findProgram "llc" (optLlc opts) ["llc"]
    
    462
    +    opt <- optional $ findProgram "opt" (optOpt opts) ["opt"]
    
    463
    +    llvmAs <- optional $ findProgram "llvm assembler" (optLlvmAs opts) ["clang"]
    
    464
    +
    
    439 465
         -- Windows-specific utilities
    
    440 466
         windres <-
    
    441 467
             case archOS_OS archOs of
    
    ... ... @@ -444,6 +470,15 @@ mkTarget opts = do
    444 470
                 return (Just windres)
    
    445 471
               _ -> return Nothing
    
    446 472
     
    
    473
    +    -- Darwin-specific utilities
    
    474
    +    (otool, installNameTool) <-
    
    475
    +        case archOS_OS archOs of
    
    476
    +          OSDarwin -> do
    
    477
    +            otool <- findProgram "otool" (optOtool opts) ["otool"]
    
    478
    +            installNameTool <- findProgram "install_name_tool" (optInstallNameTool opts) ["install_name_tool"]
    
    479
    +            return (Just otool, Just installNameTool)
    
    480
    +          _ -> return (Nothing, Nothing)
    
    481
    +
    
    447 482
         -- various other properties of the platform
    
    448 483
         tgtWordSize <- checkWordSize cc
    
    449 484
         tgtEndianness <- checkEndianness cc
    
    ... ... @@ -480,7 +515,12 @@ mkTarget opts = do
    480 515
                        , tgtRanlib = ranlib
    
    481 516
                        , tgtNm = nm
    
    482 517
                        , tgtMergeObjs = mergeObjs
    
    518
    +                   , tgtLlc = llc
    
    519
    +                   , tgtOpt = opt
    
    520
    +                   , tgtLlvmAs = llvmAs
    
    483 521
                        , tgtWindres = windres
    
    522
    +                   , tgtOtool = otool
    
    523
    +                   , tgtInstallNameTool = installNameTool
    
    484 524
                        , tgtWordSize
    
    485 525
                        , tgtEndianness
    
    486 526
                        , tgtUnregisterised
    

  • utils/ghc-toolchain/src/GHC/Toolchain/Target.hs
    ... ... @@ -22,15 +22,6 @@ data WordSize = WS4 | WS8
    22 22
     data Endianness = LittleEndian | BigEndian
    
    23 23
         deriving (Show, Read, Eq, Ord)
    
    24 24
     
    
    25
    --- TODO(#23674): Move the remaining relevant `settings-xxx` to Target:
    
    26
    --- * llc command
    
    27
    --- * opt command
    
    28
    --- * install_name_tool
    
    29
    --- * otool command
    
    30
    ---
    
    31
    --- Those are all things that are put into GHC's settings, and that might be
    
    32
    --- different across targets
    
    33
    -
    
    34 25
     -- | A 'Target' consists of:
    
    35 26
     --
    
    36 27
     -- * a target architecture and operating system
    
    ... ... @@ -72,8 +63,18 @@ data Target = Target
    72 63
         , tgtMergeObjs :: Maybe MergeObjs
    
    73 64
         -- ^ We don't need a merge objects tool if we @Ar@ supports @-L@
    
    74 65
     
    
    66
    +      -- LLVM backend toolchain
    
    67
    +    , tgtLlc :: Maybe Program
    
    68
    +    , tgtOpt :: Maybe Program
    
    69
    +    , tgtLlvmAs :: Maybe Program
    
    70
    +    -- ^ assembler used to assemble LLVM backend output; typically @clang@
    
    71
    +
    
    75 72
           -- Windows-specific tools
    
    76 73
         , tgtWindres :: Maybe Program
    
    74
    +
    
    75
    +      -- Darwin-specific tools
    
    76
    +    , tgtOtool   :: Maybe Program
    
    77
    +    , tgtInstallNameTool :: Maybe Program
    
    77 78
         }
    
    78 79
         deriving (Read, Eq, Ord)
    
    79 80
     
    
    ... ... @@ -121,6 +122,11 @@ instance Show Target where
    121 122
         , ", tgtRanlib = " ++ show tgtRanlib
    
    122 123
         , ", tgtNm = " ++ show tgtNm
    
    123 124
         , ", tgtMergeObjs = " ++ show tgtMergeObjs
    
    125
    +    , ", tgtLlc = " ++ show tgtLlc
    
    126
    +    , ", tgtOpt = " ++ show tgtOpt
    
    127
    +    , ", tgtLlvmAs = " ++ show tgtLlvmAs
    
    124 128
         , ", tgtWindres = " ++ show tgtWindres
    
    129
    +    , ", tgtOtool = " ++ show tgtOtool
    
    130
    +    , ", tgtInstallNameTool = " ++ show tgtInstallNameTool
    
    125 131
         , "}"
    
    126 132
         ]