summaryrefslogtreecommitdiff
path: root/compiler/nativeGen/PIC.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/nativeGen/PIC.hs')
-rw-r--r--compiler/nativeGen/PIC.hs66
1 files changed, 36 insertions, 30 deletions
diff --git a/compiler/nativeGen/PIC.hs b/compiler/nativeGen/PIC.hs
index bef0a21235..2f300c4614 100644
--- a/compiler/nativeGen/PIC.hs
+++ b/compiler/nativeGen/PIC.hs
@@ -47,6 +47,8 @@ module PIC (
where
+import GhcPrelude
+
import qualified PPC.Instr as PPC
import qualified PPC.Regs as PPC
@@ -162,7 +164,7 @@ cmmMakePicReference dflags lbl
| OSAIX <- platformOS $ targetPlatform dflags
= CmmMachOp (MO_Add W32)
[ CmmReg (CmmGlobal PicBaseReg)
- , CmmLit $ picRelative
+ , CmmLit $ picRelative dflags
(platformArch $ targetPlatform dflags)
(platformOS $ targetPlatform dflags)
lbl ]
@@ -171,15 +173,16 @@ cmmMakePicReference dflags lbl
| ArchPPC_64 _ <- platformArch $ targetPlatform dflags
= CmmMachOp (MO_Add W32) -- code model medium
[ CmmReg (CmmGlobal PicBaseReg)
- , CmmLit $ picRelative
+ , CmmLit $ picRelative dflags
(platformArch $ targetPlatform dflags)
(platformOS $ targetPlatform dflags)
lbl ]
- | (gopt Opt_PIC dflags || WayDyn `elem` ways dflags) && absoluteLabel lbl
+ | (positionIndependent dflags || gopt Opt_ExternalDynamicRefs dflags)
+ && absoluteLabel lbl
= CmmMachOp (MO_Add (wordWidth dflags))
[ CmmReg (CmmGlobal PicBaseReg)
- , CmmLit $ picRelative
+ , CmmLit $ picRelative dflags
(platformArch $ targetPlatform dflags)
(platformOS $ targetPlatform dflags)
lbl ]
@@ -236,7 +239,7 @@ howToAccessLabel
howToAccessLabel dflags _ OSMinGW32 this_mod _ lbl
-- Assume all symbols will be in the same PE, so just access them directly.
- | WayDyn `notElem` ways dflags
+ | not (gopt Opt_ExternalDynamicRefs dflags)
= AccessDirectly
-- If the target symbol is in another PE we need to access it via the
@@ -272,7 +275,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 +316,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 +340,8 @@ 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) &&
+ not (gopt Opt_ExternalDynamicRefs dflags)
= AccessDirectly
howToAccessLabel dflags arch os this_mod DataReference lbl
@@ -351,7 +355,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 +376,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 +393,7 @@ howToAccessLabel dflags _ os this_mod _ lbl
-- all other platforms
howToAccessLabel dflags _ _ _ _ _
- | not (gopt Opt_PIC dflags)
+ | not (positionIndependent dflags)
= AccessDirectly
| otherwise
@@ -397,10 +402,10 @@ howToAccessLabel dflags _ _ _ _ _
-- -------------------------------------------------------------------
--- | Says what we we have to add to our 'PIC base register' in order to
+-- | Says what we have to add to our 'PIC base register' in order to
-- get the address of a label.
-picRelative :: Arch -> OS -> CLabel -> CmmLit
+picRelative :: DynFlags -> Arch -> OS -> CLabel -> CmmLit
-- Darwin, but not x86_64:
-- The PIC base register points to the PIC base label at the beginning
@@ -409,15 +414,15 @@ picRelative :: Arch -> OS -> CLabel -> CmmLit
-- We have already made sure that all labels that are not from the current
-- module are accessed indirectly ('as' can't calculate differences between
-- undefined labels).
-picRelative arch OSDarwin lbl
+picRelative dflags arch OSDarwin lbl
| arch /= ArchX86_64
- = CmmLabelDiffOff lbl mkPicBaseLabel 0
+ = CmmLabelDiffOff lbl mkPicBaseLabel 0 (wordWidth dflags)
-- On AIX we use an indirect local TOC anchored by 'gotLabel'.
-- This way we use up only one global TOC entry per compilation-unit
-- (this is quite similiar to GCC's @-mminimal-toc@ compilation mode)
-picRelative _ OSAIX lbl
- = CmmLabelDiffOff lbl gotLabel 0
+picRelative dflags _ OSAIX lbl
+ = CmmLabelDiffOff lbl gotLabel 0 (wordWidth dflags)
-- PowerPC Linux:
-- The PIC base register points to our fake GOT. Use a label difference
@@ -425,9 +430,9 @@ picRelative _ OSAIX lbl
-- We have made sure that *everything* is accessed indirectly, so this
-- is only used for offsets from the GOT to symbol pointers inside the
-- GOT.
-picRelative ArchPPC os lbl
+picRelative dflags ArchPPC os lbl
| osElfTarget os
- = CmmLabelDiffOff lbl gotLabel 0
+ = CmmLabelDiffOff lbl gotLabel 0 (wordWidth dflags)
-- Most Linux versions:
@@ -437,7 +442,7 @@ picRelative ArchPPC os lbl
-- The PIC base register is %rip, we use foo@gotpcrel for symbol pointers,
-- and a GotSymbolOffset label for other things.
-- For reasons of tradition, the symbol offset label is written as a plain label.
-picRelative arch os lbl
+picRelative _ arch os lbl
| osElfTarget os || (os == OSDarwin && arch == ArchX86_64)
= let result
| Just (SymbolPtr, lbl') <- dynamicLinkerLabelInfo lbl
@@ -448,7 +453,7 @@ picRelative arch os lbl
in result
-picRelative _ _ _
+picRelative _ _ _ _
= panic "PositionIndependentCode.picRelative undefined for this platform"
@@ -467,7 +472,7 @@ needImportedSymbols dflags arch os
-- PowerPC Linux: -fPIC or -dynamic
| osElfTarget os
, arch == ArchPPC
- = gopt Opt_PIC dflags || WayDyn `elem` ways dflags
+ = positionIndependent dflags || gopt Opt_ExternalDynamicRefs dflags
-- PowerPC 64 Linux: always
| osElfTarget os
@@ -477,7 +482,8 @@ 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)
+ = gopt Opt_ExternalDynamicRefs dflags &&
+ not (positionIndependent dflags)
| otherwise
= False
@@ -499,7 +505,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 +546,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 +571,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 +625,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 +658,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,