on iko/ghcjs-patch-master help sign in
Unbreak Aarch32 cross-compilation (#411)

* Use quick-cross for cross-compilation to avoid qemu crashes * Bring over patches from my old fork of iohk-nix * Expand Aarch32 patches to ghc-8.6.5 * Turn off shared builds when cross-compilging for linux ARM * Update compiler/ghc/default.nix

commit563e18c3d5eaa348cc4500e8f73b70531d9673bf authorEdward Amsden <edward@blackriversoft.com> dateFri 31 Jan 2020, 07:58 (7 years ago) parent1f744d1
7 files changed+152−5
compiler/ghc/default.nix+2−2 overlays/bootstrap.nix+3 overlays/ghc.nix+4−2 overlays/linux-cross.nix+3−1 overlays/patches/ghc/ghc-8.6.4-prim-no-arm-atomics.patch+14 overlays/patches/ghc/global-offset-table-2.patch+26 overlays/patches/ghc/global-offset-table.patch+100
compiler/ghc/default.nix+2−2
@@ -41,7 +41,7 @@
4141, # What flavour to build. An empty string indicates no
4242 # specific flavour and falls back to ghc default values.
4343 ghcFlavour ? stdenv.lib.optionalString (stdenv.targetPlatform != stdenv.hostPlatform)
44− (if useLLVM then "perf-cross" else "perf-cross-ncg")
44+ (if useLLVM then "quick-cross" else "perf-cross-ncg")
4545
4646, # Whether to disable the large address space allocator
4747 # necessary fix for iOS: https://www.reddit.com/r/haskell/comments/4ttdz1/building_an_osxi386_to_iosarm64_cross_compiler/d5qvd67/
@@ -330,4 +330,4 @@ in let configured-src = stdenv.mkDerivation (rec {
330330 noAuditTmpdir = true;
331331});
332332
333−in drv
333+in drv
overlays/bootstrap.nix+3
@@ -99,6 +99,9 @@ in {
9999 ++ self.lib.optional (version == "8.6.4") ./patches/ghc/ghc-8.6.4-better-plusSimplCountErrors.patch
100100 ++ self.lib.optional (versionAtLeast "8.6.4" && self.stdenv.isDarwin) ./patches/ghc/ghc-macOS-loadArchive-fix.patch
101101 ++ self.lib.optional (versionAtLeast "8.4.4" && self.stdenv.isDarwin) ./patches/ghc/ghc-darwin-gcc-version-fix.patch
102+ ++ self.lib.optional (versionAtLeast "8.6.4" && versionOlder "8.8") ./patches/ghc/ghc-8.6.4-prim-no-arm-atomics.patch
103+ ++ self.lib.optional (versionAtLeast "8.6.4" && versionOlder "8.8") ./patches/ghc/global-offset-table.patch
104+ ++ self.lib.optional (versionAtLeast "8.6.4" && versionOlder "8.8") ./patches/ghc/global-offset-table-2.patch
102105 ;
103106 in ({
104107 ghc844 = self.callPackage ../compiler/ghc {
overlays/ghc.nix+4−2
@@ -4,9 +4,11 @@ self: super: with super;
44 ghcPkgOverrides = {
55 enableShared = super.stdenv.targetPlatform == super.stdenv.hostPlatform;
66 enableIntegerSimple = false;
7+ } // lib.optionalAttrs self.stdenv.hostPlatform.isAarch32 {
8+ enableRelocatableStaticLibs = false;
79 };
810 ghcDrvOverrides = drv: {
9− hardeningDisable = (drv.hardeningDisable or []) ++ [ "stackprotector" "format" ];
11+ hardeningDisable = (drv.hardeningDisable or []) ++ [ "stackprotector" "format" ] ++ lib.optionals super.stdenv.hostPlatform.isAarch32 [ "pic" "pie" ];
1012 };
1113 in {
1214 haskell-nix = let
@@ -28,4 +30,4 @@ self: super: with super;
2830 compiler = lib.mapAttrs (_name: overrideCompiler)
2931 (lib.filterAttrs (name: _value: needsPatches name) super.haskell-nix.compiler);
3032 };
31− }
33+ }
overlays/linux-cross.nix+3−1
@@ -69,4 +69,6 @@ let
6969 echo "================================================================="
7070 '';
7171
72−in { inherit preCheck postCheck configureFlags setupBuildFlags testFlags; }
72+ enableShared = lib.mkDefault (!isLinuxCross);
73+
74+in { inherit preCheck postCheck configureFlags setupBuildFlags testFlags enableShared; }
overlays/patches/ghc/ghc-8.6.4-prim-no-arm-atomics.patchnew file+14
@@ -0,0 +1,14 @@
1+diff --git a/libraries/ghc-prim/cbits/atomic.c b/libraries/ghc-prim/cbits/atomic.c
2+index 0a471b31ad..ea9612060c 100644
3+--- a/libraries/ghc-prim/cbits/atomic.c
4++++ b/libraries/ghc-prim/cbits/atomic.c
5+@@ -1,3 +1,4 @@
6++#if !defined(arm_HOST_ARCH)
7+ #include "Rts.h"
8+
9+ // Fallbacks for atomic primops on byte arrays. The builtins used
10+@@ -418,3 +419,4 @@ hs_atomicwrite64(StgWord x, StgWord64 val)
11+ while (!__sync_bool_compare_and_swap((StgWord64 *) x, *(StgWord64 *) x, (StgWord64) val));
12+ #endif
13+ }
14++#endif
overlays/patches/ghc/global-offset-table-2.patchnew file+26
@@ -0,0 +1,26 @@
1+From 358b0f69c752464c7a6d75ce44c95ff3d0ddcdea Mon Sep 17 00:00:00 2001
2+From: Edward Amsden <edward.amsden@plowtech.net>
3+Date: Thu, 16 May 2019 19:41:30 -0400
4+Subject: [PATCH] Lookup _GLOBAL_OFFSET_TABLE by symbol->addr when doing
5+ relocations
6+
7+---
8+ rts/linker/Elf.c | 2 +-
9+ 1 file changed, 1 insertion(+), 1 deletion(-)
10+
11+diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
12+index c6f82af72a..349de86227 100644
13+--- a/rts/linker/Elf.c
14++++ b/rts/linker/Elf.c
15+@@ -1064,7 +1064,7 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
16+ } else {
17+ symbol = &stab->symbols[ELF_R_SYM(info)];
18+ /* First see if it is a local symbol. */
19+- if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_LOCAL) {
20++ if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_LOCAL || strncmp(symbol->name, "_GLOBAL_OFFSET_TABLE_", 21) == 0) {
21+ S = (Elf_Addr)symbol->addr;
22+ } else {
23+ S_tmp = lookupSymbol_( symbol->name );
24+--
25+2.17.1
26+
overlays/patches/ghc/global-offset-table.patchnew file+100
@@ -0,0 +1,100 @@
1+From 8e2c350f870f8cd99122c62efd023820e563e935 Mon Sep 17 00:00:00 2001
2+From: Moritz Angermann <moritz.angermann@gmail.com>
3+Date: Thu, 16 May 2019 13:35:31 +0800
4+Subject: [PATCH] Add _GLOBAL_OFFSET_TABLE_ support
5+
6+This adds lookup logic for _GLOBAL_OFFSET_TABLE_ as well as
7+relocation logic for R_ARM_BASE_PREL and R_ARM_GOT_BREL which
8+the gnu toolchain (gas, gcc, ...) prefers to produce. Apparently
9+recent llvm toolchains will produce those as well.
10+---
11+ rts/linker/Elf.c | 33 +++++++++++++++++++++++++++++++--
12+ rts/linker/elf_got.c | 10 +++++++---
13+ 2 files changed, 38 insertions(+), 5 deletions(-)
14+
15+diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
16+index b647d207cb..c6f82af72a 100644
17+--- a/rts/linker/Elf.c
18++++ b/rts/linker/Elf.c
19+@@ -1023,6 +1023,19 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
20+ return 1;
21+ }
22+
23++ /* The following nomenclature is used for the operation:
24++ * - S -- (when used on its own) is the address of the symbol.
25++ * - A -- is the addend for the relocation.
26++ * - P -- is the address of the place being relocated (derived from r_offset).
27++ * - Pa - is the adjusted address of the place being relocated, defined as (P & 0xFFFFFFFC).
28++ * - T -- is 1 if the target symbol S has type STT_FUNC and the symbol addresses a Thumb instruction; it is 0 otherwise.
29++ * - B(S) is the addressing origin of the output segment defining the symbol S. The origin is not required to be the
30++ * base address of the segment. This value must always be word-aligned.
31++ * - GOT_ORG is the addressing origin of the Global Offset Table (the indirection table for imported data addresses).
32++ * This value must always be word-aligned. See §4.6.1.8, Proxy generating relocations.
33++ * - GOT(S) is the address of the GOT entry for the symbol S.
34++ */
35++
36+ for (j = 0; j < nent; j++) {
37+ Elf_Addr offset = rtab[j].r_offset;
38+ Elf_Addr info = rtab[j].r_info;
39+@@ -1117,19 +1130,35 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
40+ # endif
41+
42+ # ifdef arm_HOST_ARCH
43+- case COMPAT_R_ARM_ABS32:
44++ case COMPAT_R_ARM_ABS32: /* (S + A) | T */
45+ // Specified by Linux ARM ABI to be equivalent to ABS32
46+ case COMPAT_R_ARM_TARGET1:
47+ *(Elf32_Word *)P += S;
48+ *(Elf32_Word *)P |= T;
49+ break;
50+
51+- case COMPAT_R_ARM_REL32:
52++ case COMPAT_R_ARM_REL32: /* ((S + A) | T) – P */
53+ *(Elf32_Word *)P += S;
54+ *(Elf32_Word *)P |= T;
55+ *(Elf32_Word *)P -= P;
56+ break;
57+
58++ case COMPAT_R_ARM_BASE_PREL: /* B(S) + A – P */
59++ {
60++ int32_t A = *pP;
61++ // bfd used to encode sb (B(S)) as 0.
62++ *(uint32_t *)P += 0 + A - P;
63++ break;
64++ }
65++
66++ case COMPAT_R_ARM_GOT_BREL: /* GOT(S) + A – GOT_ORG */
67++ {
68++ int32_t A = *pP;
69++ void* GOT_S = symbol->got_addr;
70++ *(uint32_t *)P = (uint32_t) GOT_S + A - (uint32_t) oc->info->got_start;
71++ break;
72++ }
73++
74+ case COMPAT_R_ARM_CALL:
75+ case COMPAT_R_ARM_JUMP24:
76+ {
77+diff --git a/rts/linker/elf_got.c b/rts/linker/elf_got.c
78+index 10ea25b98b..162fff3161 100644
79+--- a/rts/linker/elf_got.c
80++++ b/rts/linker/elf_got.c
81+@@ -83,9 +83,13 @@ fillGot(ObjectCode * oc) {
82+ if(0x0 == symbol->addr) {
83+ symbol->addr = lookupSymbol_(symbol->name);
84+ if(0x0 == symbol->addr) {
85+- errorBelch("Failed to lookup symbol: %s\n",
86+- symbol->name);
87+- return EXIT_FAILURE;
88++ if(0 == strncmp(symbol->name,"_GLOBAL_OFFSET_TABLE_",21)) {
89++ symbol->addr = oc->info->got_start;
90++ } else {
91++ errorBelch("Failed to lookup symbol: %s\n",
92++ symbol->name);
93++ return EXIT_FAILURE;
94++ }
95+ }
96+ } else {
97+ // we already have the address.
98+--
99+2.21.0
100+