Skip to content

Commit 4589f9d

Browse files
angermanhamishmack
andauthored
Fix windows-th-dll build failures (#2091)
* Fix windows-th-dll build failures 48e391952c17ff7eab10b0b1456e3f2a2af28a9b, backported to 9.6 in 81873448d1c946d56f429da9d7e53ecaa55bdc71 introduced `SYM_TYPE_DUP_DISCARD` to the bitfield. The linker however, failed to mask the `SYM_TYPE_DUP_DISCARD` value. Thus `== SYM_TYPE_CODE` comparisons easily failed. This lead to us relocating DATA lookups (GOT) into E8 (call) and E9 (jump) instructions. --------- Co-authored-by: Hamish Mackenzie <Hamish.K.Mackenzie@gmail.com>
1 parent 928f59a commit 4589f9d

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

overlays/bootstrap.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ in {
257257
++ final.lib.optional (versionAtLeast "9.0" && final.stdenv.targetPlatform.isAarch64) ./patches/ghc/ghc-9.0-better-symbol-addr-debug.patch
258258
++ final.lib.optional (versionAtLeast "9.0" && final.stdenv.targetPlatform.isAarch64) ./patches/ghc/ghc-9.0-aarch64-handle-none-rela.patch
259259
++ final.lib.optional (versionAtLeast "9.6.3" && versionLessThan "9.9" && final.stdenv.targetPlatform.isWindows) ./patches/ghc/ghc-9.6-hadrian-splitsections.patch
260+
++ final.lib.optional (versionAtLeast "9.4" && final.stdenv.targetPlatform.isWindows) ./patches/ghc/ghc-9.6-fix-code-symbol-jumps.patch
260261
# this one is to allow linking extra symbols from iserv.
261262
# ++ fromUntil "9.6.1" "9.10" ./patches/ghc/iserv-syms.patch
262263
;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c
2+
index ed77d18..347ba73 100644
3+
--- a/rts/linker/PEi386.c
4+
+++ b/rts/linker/PEi386.c
5+
@@ -1939,29 +1939,32 @@ static size_t
6+
makeSymbolExtra_PEi386( ObjectCode* oc, uint64_t index STG_UNUSED, size_t s, char* symbol STG_UNUSED, SymType type )
7+
{
8+
SymbolExtra *extra;
9+
-
10+
- if (type == SYM_TYPE_CODE) {
11+
- // jmp *-14(%rip)
12+
- extra = m32_alloc(oc->rx_m32, sizeof(SymbolExtra), 8);
13+
- CHECK(extra);
14+
- extra->addr = (uint64_t)s;
15+
- static uint8_t jmp[] = { 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xFF };
16+
- memcpy(extra->jumpIsland, jmp, 6);
17+
- IF_DEBUG(linker_verbose, debugBelch("makeSymbolExtra(code): %s -> %p\n", symbol, &extra->jumpIsland));
18+
- return (size_t)&extra->jumpIsland;
19+
- } else if (type == SYM_TYPE_INDIRECT_DATA) {
20+
- extra = m32_alloc(oc->rw_m32, sizeof(SymbolExtra), 8);
21+
- CHECK(extra);
22+
- void *v = *(void**) s;
23+
- extra->addr = (uint64_t)v;
24+
- IF_DEBUG(linker_verbose, debugBelch("makeSymbolExtra(data): %s -> %p\n", symbol, &extra->addr));
25+
- return (size_t)&extra->addr;
26+
- } else {
27+
- extra = m32_alloc(oc->rw_m32, sizeof(SymbolExtra), 8);
28+
- CHECK(extra);
29+
- extra->addr = (uint64_t)s;
30+
- IF_DEBUG(linker_verbose, debugBelch("makeSymbolExtra(indirect-data): %s -> %p\n", symbol, &extra->addr));
31+
- return (size_t)&extra->addr;
32+
+ switch(type & ~SYM_TYPE_DUP_DISCARD) {
33+
+ case SYM_TYPE_CODE: {
34+
+ // jmp *-14(%rip)
35+
+ extra = m32_alloc(oc->rx_m32, sizeof(SymbolExtra), 8);
36+
+ CHECK(extra);
37+
+ extra->addr = (uint64_t)s;
38+
+ static uint8_t jmp[] = { 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xFF };
39+
+ memcpy(extra->jumpIsland, jmp, 6);
40+
+ IF_DEBUG(linker_verbose, debugBelch("makeSymbolExtra(code): %s -> %p\n", symbol, &extra->jumpIsland));
41+
+ return (size_t)&extra->jumpIsland;
42+
+ }
43+
+ case SYM_TYPE_INDIRECT_DATA: {
44+
+ extra = m32_alloc(oc->rw_m32, sizeof(SymbolExtra), 8);
45+
+ CHECK(extra);
46+
+ void *v = *(void**) s;
47+
+ extra->addr = (uint64_t)v;
48+
+ IF_DEBUG(linker_verbose, debugBelch("makeSymbolExtra(data): %s -> %p\n", symbol, &extra->addr));
49+
+ return (size_t)&extra->addr;
50+
+ }
51+
+ default: {
52+
+ extra = m32_alloc(oc->rw_m32, sizeof(SymbolExtra), 8);
53+
+ CHECK(extra);
54+
+ extra->addr = (uint64_t)s;
55+
+ IF_DEBUG(linker_verbose, debugBelch("makeSymbolExtra(indirect-data): %s -> %p\n", symbol, &extra->addr));
56+
+ return (size_t)&extra->addr;
57+
+ }
58+
}
59+
}

test/th-dlls/default.nix

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,9 @@ let
2020
compareGhc = builtins.compareVersions buildPackages.haskell-nix.compiler.${compiler-nix-name}.version;
2121

2222
in recurseIntoAttrs {
23-
meta.disabled = stdenv.hostPlatform.isGhcjs ||
23+
meta.disabled = stdenv.hostPlatform.isGhcjs
2424
# On aarch64 this test also breaks form musl builds (including cross compiles on x86_64-linux)
25-
(stdenv.hostPlatform.isAarch64 && stdenv.hostPlatform.isMusl) ||
26-
# broken on ucrt64 windows
27-
(stdenv.hostPlatform.libc == "ucrt")
25+
|| (stdenv.hostPlatform.isAarch64 && stdenv.hostPlatform.isMusl)
2826
;
2927

3028
ifdInputs = {

0 commit comments

Comments
 (0)