Skip to content

Commit 0cca66e

Browse files
committed
Fixup windows relocs
1 parent d9dc867 commit 0cca66e

File tree

5 files changed

+302
-1
lines changed

5 files changed

+302
-1
lines changed

ci.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
|| (system == "aarch64-darwin" && !builtins.elem compiler-nix-name ["ghc884" "ghc902" "ghc928" "ghc948"])
8989
)) {
9090
inherit (lib.systems.examples) ghcjs;
91-
} // lib.optionalAttrs (true # (nixpkgsName != "unsable" || nixpkgs == "unstable")
91+
} // lib.optionalAttrs ((nixpkgsName != "unsable" || nixpkgName == "unstable") # build mingw for all for now.
9292
&& (__match ".*llvm" compiler-nix-name == null)
9393
&& ((system == "x86_64-linux" && !builtins.elem compiler-nix-name ["ghc884"])
9494
|| (system == "x86_64-darwin" && builtins.elem compiler-nix-name []))) { # TODO add ghc versions when we have more darwin build capacity

overlays/bootstrap.nix

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,13 @@ in {
279279
++ final.lib.optional (versionAtLeast "9.6" && versionLessThan "9.8" && (final.stdenv.targetPlatform.isWindows || final.stdenv.targetPlatform.isMusl)) ./patches/ghc/ghc-9.6-0006-Adds-support-for-Hidden-symbols.patch
280280
++ final.lib.optional (versionAtLeast "9.6" && versionLessThan "9.8" && (final.stdenv.targetPlatform.isWindows || final.stdenv.targetPlatform.isMusl)) ./patches/ghc/ghc-9.6-0006-Adds-support-for-Hidden-symbols-2.patch
281281
++ fromUntil "9.9" "9.12" ./patches/ghc/ghc-9.9-Cabal-3.11.patch
282+
283+
# This patch will make windows stop emitting absolute relocations. This is one way in which binutils 2.36+ (with ASLR enabled), will just choke on the
284+
# assembly we generate because it's always absolute (32bit) addressing modes.
285+
# GHC from 9.6+ seems to have https://gitlab.haskell.org/ghc/ghc/-/merge_requests/7449, which should fix this as well.
286+
++ final.lib.optional (versionAtLeast "8.10" && versionLessThan "9.0" && (final.stdenv.targetPlatform.isWindows)) ./patches/ghc/windows-pseudo-pic-8.10.patch
287+
++ final.lib.optional (versionAtLeast "9.0" && versionLessThan "9.2" && (final.stdenv.targetPlatform.isWindows)) ./patches/ghc/windows-pseudo-pic.patch
288+
++ final.lib.optional (versionAtLeast "9.2" && versionLessThan "9.4" && (final.stdenv.targetPlatform.isWindows)) ./patches/ghc/windows-pseudo-pic-9.2.patch
282289
;
283290
in ({
284291
ghc865 = final.callPackage ../compiler/ghc (traceWarnOld "8.6" {
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
diff --git a/compiler/nativeGen/AsmCodeGen.hs b/compiler/nativeGen/AsmCodeGen.hs
2+
index 7357273..196acc8 100644
3+
--- a/compiler/nativeGen/AsmCodeGen.hs
4+
+++ b/compiler/nativeGen/AsmCodeGen.hs
5+
@@ -321,6 +321,13 @@ nativeCodeGen' dflags this_mod modLoc ncgImpl h us cmms
6+
-- Pretty if it weren't for the fact that we do lots of little
7+
-- printDocs here (in order to do codegen in constant space).
8+
bufh <- newBufHandle h
9+
+ let Module _u nm = this_mod
10+
+ -- emit file prolue. Including file meta inforamtion. e.g. The
11+
+ -- current name of the compile file. This may show up during linking,
12+
+ -- and thus having the proper file name is essential.
13+
+ _ <- emitNativeCode dflags bufh $
14+
+ text "\t.file \"" <> ftext (moduleNameFS nm) <> text ".hs\""
15+
+
16+
let ngs0 = NGS [] [] [] [] [] [] emptyUFM mapEmpty
17+
(ngs, us', a) <- cmmNativeGenStream dflags this_mod modLoc ncgImpl bufh us
18+
cmms ngs0
19+
diff --git a/compiler/nativeGen/PIC.hs b/compiler/nativeGen/PIC.hs
20+
index 7ea68e1..af8cba2 100644
21+
--- a/compiler/nativeGen/PIC.hs
22+
+++ b/compiler/nativeGen/PIC.hs
23+
@@ -156,10 +156,17 @@ cmmMakeDynamicReference dflags referenceKind lbl
24+
cmmMakePicReference :: DynFlags -> CLabel -> CmmExpr
25+
cmmMakePicReference dflags lbl
26+
27+
- -- Windows doesn't need PIC,
28+
- -- everything gets relocated at runtime
29+
+ -- Windows used to be absolute 32bit only (small code model)
30+
+ -- however with ASLR, and high entropy base images, we assume
31+
+ -- everything to be RIP relative. This basically for windows
32+
+ -- we want always PIC relative addressing.
33+
| OSMinGW32 <- platformOS $ targetPlatform dflags
34+
- = CmmLit $ CmmLabel lbl
35+
+ = CmmMachOp (MO_Add (wordWidth dflags))
36+
+ [ CmmReg (CmmGlobal PicBaseReg)
37+
+ , CmmLit $ picRelative dflags
38+
+ (platformArch $ targetPlatform dflags)
39+
+ (platformOS $ targetPlatform dflags)
40+
+ lbl ]
41+
42+
| OSAIX <- platformOS $ targetPlatform dflags
43+
= CmmMachOp (MO_Add W32)
44+
@@ -453,6 +460,8 @@ picRelative _ arch os lbl
45+
46+
in result
47+
48+
+picRelative _ ArchX86_64 OSMinGW32 lbl = CmmLabel lbl
49+
+
50+
picRelative _ _ _ _
51+
= panic "PositionIndependentCode.picRelative undefined for this platform"
52+
53+
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs
54+
index e319931..3909a23 100644
55+
--- a/compiler/nativeGen/X86/CodeGen.hs
56+
+++ b/compiler/nativeGen/X86/CodeGen.hs
57+
@@ -343,6 +343,13 @@ stmtToInstrs bid stmt = do
58+
lbl <- mkAsmTempLabel <$> getUniqueM
59+
return $ unitOL $ UNWIND lbl tbl
60+
61+
+ CmmAssign reg src@(CmmLit lit)
62+
+ | isFloatType ty -> assignReg_FltCode format reg src
63+
+ | is32Bit && isWord64 ty -> assignReg_I64Code reg src
64+
+ | otherwise -> assignReg_IntCode format reg src
65+
+ where ty = cmmRegType dflags reg
66+
+ format = cmmTypeFormat ty
67+
+
68+
CmmAssign reg src
69+
| isFloatType ty -> assignReg_FltCode format reg src
70+
| is32Bit && isWord64 ty -> assignReg_I64Code reg src
71+
@@ -350,6 +357,13 @@ stmtToInstrs bid stmt = do
72+
where ty = cmmRegType dflags reg
73+
format = cmmTypeFormat ty
74+
75+
+ CmmStore addr src@(CmmLit lit)
76+
+ | isFloatType ty -> assignMem_FltCode format addr src
77+
+ | is32Bit && isWord64 ty -> assignMem_I64Code addr src
78+
+ | otherwise -> assignMem_IntCode format addr src
79+
+ where ty = cmmExprType dflags src
80+
+ format = cmmTypeFormat ty
81+
+
82+
CmmStore addr src
83+
| isFloatType ty -> assignMem_FltCode format addr src
84+
| is32Bit && isWord64 ty -> assignMem_I64Code addr src
85+
@@ -3409,7 +3423,12 @@ outOfLineCmmOp bid mop res args
86+
genSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> NatM InstrBlock
87+
88+
genSwitch dflags expr targets
89+
- | positionIndependent dflags
90+
+ -- Windows is a bit odd. It's virtually PIC on x86_64, by preference of
91+
+ -- %rip relative addressing to produce the appropriate IMAGE relative
92+
+ -- relocations. Absolute relocations start to fail with binutils switching
93+
+ -- to default to high entropy ASLR and dynamic base. For most things, we can
94+
+ -- simply consider Windows to be PIC on x86_64.
95+
+ | positionIndependent dflags || (platformOS $ targetPlatform dflags) == OSMinGW32
96+
= do
97+
(reg,e_code) <- getNonClobberedReg (cmmOffset dflags expr offset)
98+
-- getNonClobberedReg because it needs to survive across t_code
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
diff --git a/compiler/GHC/CmmToAsm.hs b/compiler/GHC/CmmToAsm.hs
2+
index 23175a1..d812289 100644
3+
--- a/compiler/GHC/CmmToAsm.hs
4+
+++ b/compiler/GHC/CmmToAsm.hs
5+
@@ -333,6 +333,13 @@ nativeCodeGen' dflags this_mod modLoc ncgImpl h us cmms
6+
-- Pretty if it weren't for the fact that we do lots of little
7+
-- printDocs here (in order to do codegen in constant space).
8+
bufh <- newBufHandle h
9+
+ let Module _u nm = (ncgThisModule config)
10+
+ -- emit file prolue. Including file meta inforamtion. e.g. The
11+
+ -- current name of the compile file. This may show up during linking,
12+
+ -- and thus having the proper file name is essential.
13+
+ _ <- emitNativeCode logger dflags config bufh $
14+
+ text "\t.file \"" <> ftext (moduleNameFS nm) <> text ".hs\""
15+
+
16+
let ngs0 = NGS [] [] [] [] [] [] emptyUFM mapEmpty
17+
(ngs, us', a) <- cmmNativeGenStream dflags this_mod modLoc ncgImpl bufh us
18+
cmms ngs0
19+
diff --git a/compiler/GHC/CmmToAsm/PIC.hs b/compiler/GHC/CmmToAsm/PIC.hs
20+
index 1eb5f14..e74848f 100644
21+
--- a/compiler/GHC/CmmToAsm/PIC.hs
22+
+++ b/compiler/GHC/CmmToAsm/PIC.hs
23+
@@ -156,10 +156,17 @@ cmmMakeDynamicReference config referenceKind lbl
24+
25+
cmmMakePicReference :: NCGConfig -> CLabel -> CmmExpr
26+
cmmMakePicReference config lbl
27+
- -- Windows doesn't need PIC,
28+
- -- everything gets relocated at runtime
29+
+ -- Windows used to be absolute 32bit only (small code model)
30+
+ -- however with ASLR, and high entropy base images, we assume
31+
+ -- everything to be RIP relative. This basically for windows
32+
+ -- we want always PIC relative addressing.
33+
| OSMinGW32 <- platformOS platform
34+
- = CmmLit $ CmmLabel lbl
35+
+ = CmmMachOp (MO_Add (wordWidth platform))
36+
+ [ CmmReg (CmmGlobal PicBaseReg)
37+
+ , CmmLit $ picRelative (wordWidth platform)
38+
+ (platformArch platform)
39+
+ (platformOS platform)
40+
+ lbl ]
41+
42+
| OSAIX <- platformOS platform
43+
= CmmMachOp (MO_Add W32)
44+
@@ -454,6 +461,8 @@ picRelative _ arch os lbl
45+
46+
in result
47+
48+
+picRelative _ ArchX86_64 OSMinGW32 lbl = CmmLabel lbl
49+
+
50+
picRelative _ _ _ _
51+
= panic "GHC.CmmToAsm.PIC.picRelative undefined for this platform"
52+
53+
diff --git a/compiler/GHC/CmmToAsm/X86/CodeGen.hs b/compiler/GHC/CmmToAsm/X86/CodeGen.hs
54+
index 2cce508..376ebf0 100644
55+
--- a/compiler/GHC/CmmToAsm/X86/CodeGen.hs
56+
+++ b/compiler/GHC/CmmToAsm/X86/CodeGen.hs
57+
@@ -338,6 +338,13 @@ stmtToInstrs bid stmt = do
58+
lbl <- mkAsmTempLabel <$> getUniqueM
59+
return $ unitOL $ UNWIND lbl tbl
60+
61+
+ CmmAssign reg src@(CmmLit lit)
62+
+ | isFloatType ty -> assignReg_FltCode format reg src
63+
+ | is32Bit && isWord64 ty -> assignReg_I64Code reg src
64+
+ | otherwise -> assignReg_IntCode format reg src
65+
+ where ty = cmmRegType platform reg
66+
+ format = cmmTypeFormat ty
67+
+
68+
CmmAssign reg src
69+
| isFloatType ty -> assignReg_FltCode format reg src
70+
| is32Bit && isWord64 ty -> assignReg_I64Code reg src
71+
@@ -345,6 +352,13 @@ stmtToInstrs bid stmt = do
72+
where ty = cmmRegType platform reg
73+
format = cmmTypeFormat ty
74+
75+
+ CmmStore addr src@(CmmLit lit) _alignment
76+
+ | isFloatType ty -> assignMem_FltCode format addr src
77+
+ | is32Bit && isWord64 ty -> assignMem_I64Code addr src
78+
+ | otherwise -> assignMem_IntCode format addr src
79+
+ where ty = cmmExprType platform src
80+
+ format = cmmTypeFormat ty
81+
+
82+
CmmStore addr src _alignment
83+
| isFloatType ty -> assignMem_FltCode format addr src
84+
| is32Bit && isWord64 ty -> assignMem_I64Code addr src
85+
@@ -3443,7 +3457,12 @@ genSwitch :: CmmExpr -> SwitchTargets -> NatM InstrBlock
86+
genSwitch expr targets = do
87+
config <- getConfig
88+
let platform = ncgPlatform config
89+
- if ncgPIC config
90+
+ -- Windows is a bit odd. It's virtually PIC on x86_64, by preference of
91+
+ -- %rip relative addressing to produce the appropriate IMAGE relative
92+
+ -- relocations. Absolute relocations start to fail with binutils switching
93+
+ -- to default to high entropy ASLR and dynamic base. For most things, we can
94+
+ -- simply consider Windows to be PIC on x86_64.
95+
+ if ncgPIC config || (platformOS platform) == OSMinGW32
96+
then do
97+
(reg,e_code) <- getNonClobberedReg (cmmOffset platform expr offset)
98+
-- getNonClobberedReg because it needs to survive across t_code
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
diff --git a/compiler/GHC/CmmToAsm.hs b/compiler/GHC/CmmToAsm.hs
2+
index 23175a1..d812289 100644
3+
--- a/compiler/GHC/CmmToAsm.hs
4+
+++ b/compiler/GHC/CmmToAsm.hs
5+
@@ -333,6 +333,13 @@ nativeCodeGen' dflags this_mod modLoc ncgImpl h us cmms
6+
-- Pretty if it weren't for the fact that we do lots of little
7+
-- printDocs here (in order to do codegen in constant space).
8+
bufh <- newBufHandle h
9+
+ let Module _u nm = this_mod
10+
+ -- emit file prolue. Including file meta inforamtion. e.g. The
11+
+ -- current name of the compile file. This may show up during linking,
12+
+ -- and thus having the proper file name is essential.
13+
+ _ <- emitNativeCode dflags bufh $
14+
+ text "\t.file \"" <> ftext (moduleNameFS nm) <> text ".hs\""
15+
+
16+
let ngs0 = NGS [] [] [] [] [] [] emptyUFM mapEmpty
17+
(ngs, us', a) <- cmmNativeGenStream dflags this_mod modLoc ncgImpl bufh us
18+
cmms ngs0
19+
diff --git a/compiler/GHC/CmmToAsm/PIC.hs b/compiler/GHC/CmmToAsm/PIC.hs
20+
index 1eb5f14..e74848f 100644
21+
--- a/compiler/GHC/CmmToAsm/PIC.hs
22+
+++ b/compiler/GHC/CmmToAsm/PIC.hs
23+
@@ -156,10 +156,17 @@ cmmMakeDynamicReference config referenceKind lbl
24+
25+
cmmMakePicReference :: NCGConfig -> CLabel -> CmmExpr
26+
cmmMakePicReference config lbl
27+
- -- Windows doesn't need PIC,
28+
- -- everything gets relocated at runtime
29+
+ -- Windows used to be absolute 32bit only (small code model)
30+
+ -- however with ASLR, and high entropy base images, we assume
31+
+ -- everything to be RIP relative. This basically for windows
32+
+ -- we want always PIC relative addressing.
33+
| OSMinGW32 <- platformOS platform
34+
- = CmmLit $ CmmLabel lbl
35+
+ = CmmMachOp (MO_Add (wordWidth platform))
36+
+ [ CmmReg (CmmGlobal PicBaseReg)
37+
+ , CmmLit $ picRelative (wordWidth platform)
38+
+ (platformArch platform)
39+
+ (platformOS platform)
40+
+ lbl ]
41+
42+
| OSAIX <- platformOS platform
43+
= CmmMachOp (MO_Add W32)
44+
@@ -454,6 +461,8 @@ picRelative _ arch os lbl
45+
46+
in result
47+
48+
+picRelative _ ArchX86_64 OSMinGW32 lbl = CmmLabel lbl
49+
+
50+
picRelative _ _ _ _
51+
= panic "GHC.CmmToAsm.PIC.picRelative undefined for this platform"
52+
53+
diff --git a/compiler/GHC/CmmToAsm/X86/CodeGen.hs b/compiler/GHC/CmmToAsm/X86/CodeGen.hs
54+
index 2cce508..376ebf0 100644
55+
--- a/compiler/GHC/CmmToAsm/X86/CodeGen.hs
56+
+++ b/compiler/GHC/CmmToAsm/X86/CodeGen.hs
57+
@@ -338,6 +338,13 @@ stmtToInstrs bid stmt = do
58+
lbl <- mkAsmTempLabel <$> getUniqueM
59+
return $ unitOL $ UNWIND lbl tbl
60+
61+
+ CmmAssign reg src@(CmmLit lit)
62+
+ | isFloatType ty -> assignReg_FltCode format reg src
63+
+ | is32Bit && isWord64 ty -> assignReg_I64Code reg src
64+
+ | otherwise -> assignReg_IntCode format reg src
65+
+ where ty = cmmRegType platform reg
66+
+ format = cmmTypeFormat ty
67+
+
68+
CmmAssign reg src
69+
| isFloatType ty -> assignReg_FltCode format reg src
70+
| is32Bit && isWord64 ty -> assignReg_I64Code reg src
71+
@@ -345,6 +352,13 @@ stmtToInstrs bid stmt = do
72+
where ty = cmmRegType platform reg
73+
format = cmmTypeFormat ty
74+
75+
+ CmmStore addr src@(CmmLit lit)
76+
+ | isFloatType ty -> assignMem_FltCode format addr src
77+
+ | is32Bit && isWord64 ty -> assignMem_I64Code addr src
78+
+ | otherwise -> assignMem_IntCode format addr src
79+
+ where ty = cmmExprType platform src
80+
+ format = cmmTypeFormat ty
81+
+
82+
CmmStore addr src
83+
| isFloatType ty -> assignMem_FltCode format addr src
84+
| is32Bit && isWord64 ty -> assignMem_I64Code addr src
85+
@@ -3443,7 +3457,12 @@ genSwitch :: CmmExpr -> SwitchTargets -> NatM InstrBlock
86+
genSwitch expr targets = do
87+
config <- getConfig
88+
let platform = ncgPlatform config
89+
- if ncgPIC config
90+
+ -- Windows is a bit odd. It's virtually PIC on x86_64, by preference of
91+
+ -- %rip relative addressing to produce the appropriate IMAGE relative
92+
+ -- relocations. Absolute relocations start to fail with binutils switching
93+
+ -- to default to high entropy ASLR and dynamic base. For most things, we can
94+
+ -- simply consider Windows to be PIC on x86_64.
95+
+ if ncgPIC config || (platformOS platform) == OSMinGW32
96+
then do
97+
(reg,e_code) <- getNonClobberedReg (cmmOffset platform expr offset)
98+
-- getNonClobberedReg because it needs to survive across t_code

0 commit comments

Comments
 (0)