diff options
author | Ben Gamari <bgamari.foss@gmail.com> | 2017-08-22 11:41:47 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-08-22 18:01:05 -0400 |
commit | 3625728a0e3a9b56c2b85ae7ea8bcabdd83ece6a (patch) | |
tree | c8d0ff7e921436d011e70018c5cea974dcf67f23 /compiler/nativeGen | |
parent | dbaa9a237b6d9771c0e9bde0e50fd2134c2f4dd0 (diff) | |
download | haskell-3625728a0e3a9b56c2b85ae7ea8bcabdd83ece6a.tar.gz |
Add support for producing position-independent executables
Previously due to #12759 we disabled PIE support entirely. However, this
breaks the user's ability to produce PIEs. Add an explicit flag, -fPIE,
allowing the user to build PIEs.
Test Plan: Validate
Reviewers: rwbarton, austin, simonmar
Subscribers: trommler, simonmar, trofi, jrtc27, thomie
GHC Trac Issues: #12759, #13702
Differential Revision: https://phabricator.haskell.org/D3589
Diffstat (limited to 'compiler/nativeGen')
-rw-r--r-- | compiler/nativeGen/AsmCodeGen.hs | 6 | ||||
-rw-r--r-- | compiler/nativeGen/PIC.hs | 33 | ||||
-rw-r--r-- | compiler/nativeGen/PPC/CodeGen.hs | 6 | ||||
-rw-r--r-- | compiler/nativeGen/SPARC/CodeGen.hs | 2 | ||||
-rw-r--r-- | compiler/nativeGen/X86/CodeGen.hs | 4 |
5 files changed, 26 insertions, 25 deletions
diff --git a/compiler/nativeGen/AsmCodeGen.hs b/compiler/nativeGen/AsmCodeGen.hs index 45d170e28d..314d726b50 100644 --- a/compiler/nativeGen/AsmCodeGen.hs +++ b/compiler/nativeGen/AsmCodeGen.hs @@ -1212,15 +1212,15 @@ cmmExprNative referenceKind expr = do -- to use the register table, so we replace these registers -- with the corresponding labels: CmmReg (CmmGlobal EagerBlackholeInfo) - | arch == ArchPPC && not (gopt Opt_PIC dflags) + | arch == ArchPPC && not (positionIndependent dflags) -> cmmExprNative referenceKind $ CmmLit (CmmLabel (mkCmmCodeLabel rtsUnitId (fsLit "__stg_EAGER_BLACKHOLE_info"))) CmmReg (CmmGlobal GCEnter1) - | arch == ArchPPC && not (gopt Opt_PIC dflags) + | arch == ArchPPC && not (positionIndependent dflags) -> cmmExprNative referenceKind $ CmmLit (CmmLabel (mkCmmCodeLabel rtsUnitId (fsLit "__stg_gc_enter_1"))) CmmReg (CmmGlobal GCFun) - | arch == ArchPPC && not (gopt Opt_PIC dflags) + | arch == ArchPPC && not (positionIndependent dflags) -> cmmExprNative referenceKind $ CmmLit (CmmLabel (mkCmmCodeLabel rtsUnitId (fsLit "__stg_gc_fun"))) diff --git a/compiler/nativeGen/PIC.hs b/compiler/nativeGen/PIC.hs index bef0a21235..de1fbaa8d4 100644 --- a/compiler/nativeGen/PIC.hs +++ b/compiler/nativeGen/PIC.hs @@ -176,7 +176,7 @@ cmmMakePicReference dflags lbl (platformOS $ targetPlatform dflags) lbl ] - | (gopt Opt_PIC dflags || WayDyn `elem` ways dflags) && absoluteLabel lbl + | (positionIndependent dflags || WayDyn `elem` ways dflags) && absoluteLabel lbl = CmmMachOp (MO_Add (wordWidth dflags)) [ CmmReg (CmmGlobal PicBaseReg) , CmmLit $ picRelative @@ -272,7 +272,7 @@ howToAccessLabel dflags arch OSDarwin this_mod DataReference lbl -- we'd need to pass the current Module all the way in to -- this function. | arch /= ArchX86_64 - , gopt Opt_PIC dflags && externallyVisibleCLabel lbl + , positionIndependent dflags && externallyVisibleCLabel lbl = AccessViaSymbolPtr | otherwise @@ -313,8 +313,8 @@ howToAccessLabel _dflags _arch OSAIX _this_mod kind _lbl -- -- ELF tries to pretend to the main application code that dynamic linking does -- not exist. While this may sound convenient, it tends to mess things up in --- very bad ways, so we have to be careful when we generate code for the main --- program (-dynamic but no -fPIC). +-- very bad ways, so we have to be careful when we generate code for a non-PIE +-- main program (-dynamic but no -fPIC). -- -- Indirect access is required for references to imported symbols -- from position independent code. It is also required from the main program @@ -337,7 +337,7 @@ howToAccessLabel dflags _ os _ _ _ -- if we don't dynamically link to Haskell code, -- it actually manages to do so without messing things up. | osElfTarget os - , not (gopt Opt_PIC dflags) && WayDyn `notElem` ways dflags + , not (positionIndependent dflags) && WayDyn `notElem` ways dflags = AccessDirectly howToAccessLabel dflags arch os this_mod DataReference lbl @@ -351,7 +351,7 @@ howToAccessLabel dflags arch os this_mod DataReference lbl -- via a symbol pointer (see below for an explanation why -- PowerPC32 Linux is especially broken). | arch == ArchPPC - , gopt Opt_PIC dflags + , positionIndependent dflags -> AccessViaSymbolPtr | otherwise @@ -372,12 +372,13 @@ howToAccessLabel dflags arch os this_mod DataReference lbl howToAccessLabel dflags arch os this_mod CallReference lbl | osElfTarget os - , labelDynamic dflags this_mod lbl && not (gopt Opt_PIC dflags) + , labelDynamic dflags this_mod lbl && not (positionIndependent dflags) = AccessDirectly | osElfTarget os , arch /= ArchX86 - , labelDynamic dflags this_mod lbl && gopt Opt_PIC dflags + , labelDynamic dflags this_mod lbl + , positionIndependent dflags = AccessViaStub howToAccessLabel dflags _ os this_mod _ lbl @@ -388,7 +389,7 @@ howToAccessLabel dflags _ os this_mod _ lbl -- all other platforms howToAccessLabel dflags _ _ _ _ _ - | not (gopt Opt_PIC dflags) + | not (positionIndependent dflags) = AccessDirectly | otherwise @@ -467,7 +468,7 @@ needImportedSymbols dflags arch os -- PowerPC Linux: -fPIC or -dynamic | osElfTarget os , arch == ArchPPC - = gopt Opt_PIC dflags || WayDyn `elem` ways dflags + = positionIndependent dflags || WayDyn `elem` ways dflags -- PowerPC 64 Linux: always | osElfTarget os @@ -477,7 +478,7 @@ needImportedSymbols dflags arch os -- i386 (and others?): -dynamic but not -fPIC | osElfTarget os , arch /= ArchPPC_64 ELF_V1 && arch /= ArchPPC_64 ELF_V2 - = WayDyn `elem` ways dflags && not (gopt Opt_PIC dflags) + = WayDyn `elem` ways dflags && not (positionIndependent dflags) | otherwise = False @@ -499,7 +500,7 @@ gotLabel -- However, for PIC on x86, we need a small helper function. pprGotDeclaration :: DynFlags -> Arch -> OS -> SDoc pprGotDeclaration dflags ArchX86 OSDarwin - | gopt Opt_PIC dflags + | positionIndependent dflags = vcat [ text ".section __TEXT,__textcoal_nt,coalesced,no_toc", text ".weak_definition ___i686.get_pc_thunk.ax", @@ -540,7 +541,7 @@ pprGotDeclaration _ (ArchPPC_64 _) _ pprGotDeclaration dflags arch os | osElfTarget os , arch /= ArchPPC_64 ELF_V1 && arch /= ArchPPC_64 ELF_V2 - , not (gopt Opt_PIC dflags) + , not (positionIndependent dflags) = empty | osElfTarget os @@ -565,7 +566,7 @@ pprGotDeclaration _ _ _ pprImportedSymbol :: DynFlags -> Platform -> CLabel -> SDoc pprImportedSymbol dflags platform@(Platform { platformArch = ArchPPC, platformOS = OSDarwin }) importedLbl | Just (CodeStub, lbl) <- dynamicLinkerLabelInfo importedLbl - = case gopt Opt_PIC dflags of + = case positionIndependent dflags of False -> vcat [ text ".symbol_stub", @@ -619,7 +620,7 @@ pprImportedSymbol dflags platform@(Platform { platformArch = ArchPPC, platformOS pprImportedSymbol dflags platform@(Platform { platformArch = ArchX86, platformOS = OSDarwin }) importedLbl | Just (CodeStub, lbl) <- dynamicLinkerLabelInfo importedLbl - = case gopt Opt_PIC dflags of + = case positionIndependent dflags of False -> vcat [ text ".symbol_stub", @@ -652,7 +653,7 @@ pprImportedSymbol dflags platform@(Platform { platformArch = ArchX86, platformOS text "\tjmp dyld_stub_binding_helper" ] $+$ vcat [ text ".section __DATA, __la_sym_ptr" - <> (if gopt Opt_PIC dflags then int 2 else int 3) + <> (if positionIndependent dflags then int 2 else int 3) <> text ",lazy_symbol_pointers", text "L" <> pprCLabel platform lbl <> ptext (sLit "$lazy_ptr:"), text "\t.indirect_symbol" <+> pprCLabel platform lbl, diff --git a/compiler/nativeGen/PPC/CodeGen.hs b/compiler/nativeGen/PPC/CodeGen.hs index 1e88a1d025..1a802d34b2 100644 --- a/compiler/nativeGen/PPC/CodeGen.hs +++ b/compiler/nativeGen/PPC/CodeGen.hs @@ -1598,7 +1598,7 @@ genCCall' dflags gcp target dest_regs args uses_pic_base_implicitly = do -- See Note [implicit register in PPC PIC code] -- on why we claim to use PIC register here - when (gopt Opt_PIC dflags && target32Bit platform) $ do + when (positionIndependent dflags && target32Bit platform) $ do _ <- getPicBaseNat $ archWordFormat True return () @@ -1950,7 +1950,7 @@ genSwitch dflags expr targets ] return code - | (gopt Opt_PIC dflags) || (not $ target32Bit $ targetPlatform dflags) + | (positionIndependent dflags) || (not $ target32Bit $ targetPlatform dflags) = do (reg,e_code) <- getSomeReg (cmmOffset dflags expr offset) let fmt = archWordFormat $ target32Bit $ targetPlatform dflags @@ -1988,7 +1988,7 @@ generateJumpTableForInstr :: DynFlags -> Instr -> Maybe (NatCmmDecl CmmStatics Instr) generateJumpTableForInstr dflags (BCTR ids (Just lbl)) = let jumpTable - | (gopt Opt_PIC dflags) + | (positionIndependent dflags) || (not $ target32Bit $ targetPlatform dflags) = map jumpTableEntryRel ids | otherwise = map (jumpTableEntry dflags) ids diff --git a/compiler/nativeGen/SPARC/CodeGen.hs b/compiler/nativeGen/SPARC/CodeGen.hs index 71d320fa63..72e25b945f 100644 --- a/compiler/nativeGen/SPARC/CodeGen.hs +++ b/compiler/nativeGen/SPARC/CodeGen.hs @@ -313,7 +313,7 @@ genCondJump bid bool = do genSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> NatM InstrBlock genSwitch dflags expr targets - | gopt Opt_PIC dflags + | positionIndependent dflags = error "MachCodeGen: sparc genSwitch PIC not finished\n" | otherwise diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs index bd4774ae2c..8f7fbd292b 100644 --- a/compiler/nativeGen/X86/CodeGen.hs +++ b/compiler/nativeGen/X86/CodeGen.hs @@ -2696,7 +2696,7 @@ outOfLineCmmOp mop res args genSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> NatM InstrBlock genSwitch dflags expr targets - | gopt Opt_PIC dflags + | positionIndependent dflags = do (reg,e_code) <- getNonClobberedReg (cmmOffset dflags expr offset) -- getNonClobberedReg because it needs to survive across t_code @@ -2759,7 +2759,7 @@ createJumpTable :: DynFlags -> [Maybe BlockId] -> Section -> CLabel -> GenCmmDecl (Alignment, CmmStatics) h g createJumpTable dflags ids section lbl = let jumpTable - | gopt Opt_PIC dflags = + | positionIndependent dflags = let jumpTableEntryRel Nothing = CmmStaticLit (CmmInt 0 (wordWidth dflags)) jumpTableEntryRel (Just blockid) |