Skip to content

Commit 79882ce

Browse files
committed
add aggregated ghc-9.6 patch
1 parent 90094fd commit 79882ce

File tree

2 files changed

+354
-0
lines changed

2 files changed

+354
-0
lines changed

overlays/bootstrap.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ in {
298298
# this one is to allow linking extra symbols from iserv.
299299
++ final.lib.optional (versionAtLeast "9.6.1" && versionLessThan"9.10" && final.stdenv.targetPlatform.isAndroid) ./patches/ghc/iserv-syms.patch
300300
++ final.lib.optional (versionAtLeast "9.4" && final.stdenv.targetPlatform.isWindows) ./patches/ghc/ghc-9.6-fix-code-symbol-jumps.patch
301+
++ final.lib.optional (versionAtLeast "9.6.3" && versionLessThan "9.10" && final.stdenv.targetPlatform.isAndroid) ./patches/ghc/ghc-9.6-iog.patch
301302
;
302303
in ({
303304
ghc865 = final.callPackage ../compiler/ghc (traceWarnOld "8.6" {
Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
diff --git a/rts/Linker.c b/rts/Linker.c
2+
index 59e2ff9397..78e43cd471 100644
3+
--- a/rts/Linker.c
4+
+++ b/rts/Linker.c
5+
@@ -267,7 +267,7 @@ int ghciInsertSymbolTable(
6+
RtsSymbolInfo *pinfo = lookupStrHashTable(table, key);
7+
if (!pinfo) /* new entry */
8+
{
9+
- pinfo = stgMallocBytes(sizeof (*pinfo), "ghciInsertToSymbolTable");
10+
+ pinfo = stgCallocBytes(1, sizeof (*pinfo), "ghciInsertToSymbolTable");
11+
pinfo->value = data;
12+
pinfo->owner = owner;
13+
pinfo->strength = strength;
14+
@@ -605,11 +605,11 @@ internal_dlopen(const char *dll_name)
15+
/* dlopen failed; return a ptr to the error msg. */
16+
errmsg = dlerror();
17+
if (errmsg == NULL) errmsg = "addDLL: unknown error";
18+
- errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL");
19+
+ errmsg_copy = stgCallocBytes(1,strlen(errmsg)+1, "addDLL");
20+
strcpy(errmsg_copy, errmsg);
21+
errmsg = errmsg_copy;
22+
} else {
23+
- o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL");
24+
+ o_so = stgCallocBytes(1,sizeof(OpenedSO), "addDLL");
25+
o_so->handle = hdl;
26+
o_so->next = openedSOs;
27+
openedSOs = o_so;
28+
@@ -1314,7 +1314,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
29+
30+
31+
IF_DEBUG(linker, debugBelch("mkOc: %" PATH_FMT "\n", path));
32+
- oc = stgMallocBytes(sizeof(ObjectCode), "mkOc(oc)");
33+
+ oc = stgCallocBytes(1, sizeof(ObjectCode), "mkOc(oc)");
34+
35+
oc->info = NULL;
36+
oc->type = type;
37+
@@ -1334,7 +1334,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
38+
oc->fileName = pathdup(path);
39+
40+
if (archiveMemberName) {
41+
- oc->archiveMemberName = stgMallocBytes( (pathlen(archiveMemberName)+1) * pathsize,
42+
+ oc->archiveMemberName = stgCallocBytes(1, (pathlen(archiveMemberName)+1) * pathsize,
43+
"loadObj" );
44+
pathcopy(oc->archiveMemberName, archiveMemberName);
45+
} else {
46+
@@ -1489,12 +1489,12 @@ preloadObjectFile (pathchar *path)
47+
// reading the file, and then we misalign image on purpose so
48+
// that the actual sections end up aligned again.
49+
misalignment = machoGetMisalignment(f);
50+
- image = stgMallocBytes(fileSize + misalignment, "loadObj(image)");
51+
+ image = stgCallocBytes(1, fileSize + misalignment, "loadObj(image)");
52+
image += misalignment;
53+
54+
# else /* !defined(darwin_HOST_OS) */
55+
56+
- image = stgMallocBytes(fileSize, "loadObj(image)");
57+
+ image = stgCallocBytes(1, fileSize, "loadObj(image)");
58+
59+
#endif /* !defined(darwin_HOST_OS) */
60+
61+
@@ -1787,6 +1787,8 @@ static HsInt resolveObjs_ (void)
62+
IF_DEBUG(linker, debugBelch("resolveObjs: start\n"));
63+
64+
for (ObjectCode *oc = objects; oc; oc = oc->next) {
65+
+ if(oc->status == OBJECT_RESOLVED)
66+
+ continue;
67+
int r = ocTryLoad(oc);
68+
if (!r) {
69+
errorBelch("Could not load Object Code %" PATH_FMT ".\n", OC_INFORMATIVE_FILENAME(oc));
70+
@@ -1907,7 +1909,7 @@ void
71+
addProddableBlock ( ObjectCode* oc, void* start, int size )
72+
{
73+
ProddableBlock* pb
74+
- = stgMallocBytes(sizeof(ProddableBlock), "addProddableBlock");
75+
+ = stgCallocBytes(1,sizeof(ProddableBlock), "addProddableBlock");
76+
77+
IF_DEBUG(linker, debugBelch("addProddableBlock: %p %p %d\n", oc, start, size));
78+
ASSERT(size > 0);
79+
diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h
80+
index 271611a249..784bb19c10 100644
81+
--- a/rts/LinkerInternals.h
82+
+++ b/rts/LinkerInternals.h
83+
@@ -299,6 +299,10 @@ struct _ObjectCode {
84+
int n_segments;
85+
Segment *segments;
86+
87+
+ // COMMON section
88+
+ void * common_mem;
89+
+ unsigned long common_size;
90+
+
91+
//
92+
// Garbage collection fields
93+
//
94+
diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c
95+
index 4cac10ba15..fe0d8ca40e 100644
96+
--- a/rts/RtsUtils.c
97+
+++ b/rts/RtsUtils.c
98+
@@ -104,6 +104,11 @@ stgCallocBytes (size_t count, size_t size, char *msg)
99+
rtsConfig.mallocFailHook((W_) count*size, msg);
100+
stg_exit(EXIT_INTERNAL_ERROR);
101+
}
102+
+ // If we run under qemu with jemalloc, calloc is not guaranteed
103+
+ // to zero memory.
104+
+ // - https://giters.com/jemalloc/jemalloc/issues/1844
105+
+ // - https://lists.nongnu.org/archive/html/qemu-devel/2020-05/msg03119.html
106+
+ memset(space, 0, count*size);
107+
return space;
108+
}
109+
110+
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
111+
index bab2ca3041..5d91301c51 100644
112+
--- a/rts/linker/Elf.c
113+
+++ b/rts/linker/Elf.c
114+
@@ -303,6 +303,15 @@ ocInit_ELF(ObjectCode * oc)
115+
}
116+
}
117+
}
118+
+ if(NULL != oc->common_mem) {
119+
+#if RTS_LINKER_USE_MMAP
120+
+ munmap(oc->common_mem, oc->common_size);
121+
+#else
122+
+ stgFree(oc->common_mem);
123+
+#endif
124+
+ }
125+
+ oc->common_mem = NULL;
126+
+ oc->common_size = 0;
127+
}
128+
129+
void
130+
@@ -961,14 +970,17 @@ ocGetNames_ELF ( ObjectCode* oc )
131+
for (size_t j = 0; j < symTab->n_symbols; j++) {
132+
ElfSymbol *symbol = &symTab->symbols[j];
133+
if (SHN_COMMON == symTab->symbols[j].elf_sym->st_shndx) {
134+
- common_size += symbol->elf_sym->st_size;
135+
+ // st_value holds the alignment. Adding alignment always
136+
+ // should give us some wiggle room to get alignment right.
137+
+ common_size += symbol->elf_sym->st_size + symbol->elf_sym->st_value;
138+
}
139+
}
140+
}
141+
- void * common_mem = NULL;
142+
+ oc->common_mem = NULL;
143+
+ oc->common_size = common_size;
144+
if(common_size > 0) {
145+
- common_mem = mmapAnonForLinker(common_size);
146+
- if (common_mem == NULL) {
147+
+ oc->common_mem = mmapAnonForLinker(common_size);
148+
+ if (oc->common_mem == NULL) {
149+
barf("ocGetNames_ELF: Failed to allocate memory for SHN_COMMONs");
150+
}
151+
}
152+
@@ -1010,8 +1022,9 @@ ocGetNames_ELF ( ObjectCode* oc )
153+
isLocal = false;
154+
CHECK(common_used < common_size);
155+
CHECK(common_mem);
156+
- symbol->addr = (void*)((uintptr_t)common_mem + common_used);
157+
- common_used += symbol->elf_sym->st_size;
158+
+ int alignment = symbol->elf_sym->st_value-1;
159+
+ symbol->addr = (void*)(((uintptr_t)oc->common_mem + common_used + alignment) & ~alignment);
160+
+ common_used = (uintptr_t)symbol->addr - (uintptr_t)oc->common_mem + symbol->elf_sym->st_size;
161+
CHECK(common_used <= common_size);
162+
163+
IF_DEBUG(linker_verbose,
164+
@@ -1025,7 +1038,9 @@ ocGetNames_ELF ( ObjectCode* oc )
165+
|| ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK
166+
)
167+
/* and not an undefined symbol */
168+
- && shndx != SHN_UNDEF
169+
+ && (shndx != SHN_UNDEF
170+
+ /* unless it's weak */
171+
+ || (shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK))
172+
/* and not in a "special section" */
173+
&& (shndx < SHN_LORESERVE
174+
#if defined(SHN_XINDEX)
175+
@@ -1052,6 +1067,14 @@ ocGetNames_ELF ( ObjectCode* oc )
176+
(intptr_t) oc->sections[secno].start +
177+
(intptr_t) symbol->elf_sym->st_value);
178+
CHECK(symbol->addr != 0x0);
179+
+ if(shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK) {
180+
+ symbol->addr = NULL;
181+
+ } else {
182+
+ symbol->addr = (SymbolAddr*)(
183+
+ (intptr_t) oc->sections[secno].start +
184+
+ (intptr_t) symbol->elf_sym->st_value);
185+
+ CHECK(symbol->addr != 0x0);
186+
+ }
187+
if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_LOCAL) {
188+
isLocal = true;
189+
isWeak = false;
190+
@@ -1070,35 +1093,20 @@ ocGetNames_ELF ( ObjectCode* oc )
191+
sym_type = SYM_TYPE_CODE;
192+
} else {
193+
sym_type = SYM_TYPE_DATA;
194+
- }
195+
-
196+
- /* And the decision is ... */
197+
-
198+
- if (symbol->addr != NULL) {
199+
- CHECK(nm != NULL);
200+
- /* Acquire! */
201+
- if (!isLocal) {
202+
-
203+
- if (isWeak == HS_BOOL_TRUE) {
204+
- setWeakSymbol(oc, nm);
205+
- }
206+
- if (!ghciInsertSymbolTable(oc->fileName, symhash,
207+
- nm, symbol->addr, isWeak, sym_type, oc)
208+
- ) {
209+
- goto fail;
210+
- }
211+
- oc->symbols[curSymbol].name = nm;
212+
- oc->symbols[curSymbol].addr = symbol->addr;
213+
- oc->symbols[curSymbol].type = sym_type;
214+
- curSymbol++;
215+
- }
216+
- } else {
217+
- /* Skip. */
218+
+ } else if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK
219+
+ && shndx == SHN_UNDEF
220+
+ && (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC
221+
+ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_OBJECT
222+
+ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_NOTYPE)) {
223+
+ symbol->addr = NULL;
224+
+ isLocal = false;
225+
+ isWeak = true;
226+
+ } else {
227+
+ /* skip this symbol */
228+
IF_DEBUG(linker_verbose,
229+
debugBelch("skipping `%s'\n",
230+
nm)
231+
);
232+
-
233+
/*
234+
debugBelch(
235+
"skipping bind = %d, type = %d, secno = %d `%s'\n",
236+
@@ -1108,7 +1116,24 @@ ocGetNames_ELF ( ObjectCode* oc )
237+
nm
238+
);
239+
*/
240+
- }
241+
+ continue;
242+
+ }
243+
+
244+
+ /* And the decision is ... */
245+
+ ASSERT(nm != NULL);
246+
+ /* Acquire! */
247+
+ if (!isLocal) {
248+
+
249+
+ if (isWeak == HS_BOOL_TRUE) {
250+
+ setWeakSymbol(oc, nm);
251+
+ }
252+
+ if (!ghciInsertSymbolTable(oc->fileName, symhash,
253+
+ nm, symbol->addr, isWeak, oc)) {
254+
+ goto fail;
255+
+ }
256+
+ oc->symbols[curSymbol++].name = nm;
257+
+ oc->symbols[curSymbol].addr = symbol->addr;
258+
+ }
259+
}
260+
}
261+
}
262+
diff --git a/rts/linker/elf_plt.c b/rts/linker/elf_plt.c
263+
index 9cd42efff2..70817d8b0b 100644
264+
--- a/rts/linker/elf_plt.c
265+
+++ b/rts/linker/elf_plt.c
266+
@@ -1,4 +1,5 @@
267+
#include "Rts.h"
268+
+#include "RtsUtils.h"
269+
#include "elf_plt.h"
270+
271+
#include <stdbool.h>
272+
@@ -51,7 +52,7 @@ makeStub(Section * section,
273+
void* * addr,
274+
uint8_t flags) {
275+
276+
- Stub * s = calloc(1, sizeof(Stub));
277+
+ Stub * s = stgCallocBytes(1, sizeof(Stub), "makeStub");
278+
ASSERT(s != NULL);
279+
s->target = *addr;
280+
s->flags = flags;
281+
diff --git a/rts/linker/elf_plt_aarch64.c b/rts/linker/elf_plt_aarch64.c
282+
index 11354a63db..6b27a2c73d 100644
283+
--- a/rts/linker/elf_plt_aarch64.c
284+
+++ b/rts/linker/elf_plt_aarch64.c
285+
@@ -25,6 +25,7 @@ const size_t stubSizeAarch64 = 5 * 4;
286+
*/
287+
bool needStubForRelAarch64(Elf_Rel * rel) {
288+
switch(ELF64_R_TYPE(rel->r_info)) {
289+
+ case COMPAT_R_AARCH64_CONDBR19:
290+
case COMPAT_R_AARCH64_CALL26:
291+
case COMPAT_R_AARCH64_JUMP26:
292+
return true;
293+
@@ -34,6 +35,7 @@ bool needStubForRelAarch64(Elf_Rel * rel) {
294+
}
295+
bool needStubForRelaAarch64(Elf_Rela * rela) {
296+
switch(ELF64_R_TYPE(rela->r_info)) {
297+
+ case COMPAT_R_AARCH64_CONDBR19:
298+
case COMPAT_R_AARCH64_CALL26:
299+
case COMPAT_R_AARCH64_JUMP26:
300+
return true;
301+
diff --git a/rts/linker/elf_reloc_aarch64.c b/rts/linker/elf_reloc_aarch64.c
302+
index 4743e81ea2..f37e3699f1 100644
303+
--- a/rts/linker/elf_reloc_aarch64.c
304+
+++ b/rts/linker/elf_reloc_aarch64.c
305+
@@ -105,8 +105,24 @@ encodeAddendAarch64(Section * section, Elf_Rel * rel, int64_t addend) {
306+
break;
307+
}
308+
/* - control flow relocations */
309+
+ case COMPAT_R_AARCH64_CONDBR19: { /* relocate b.* ... */
310+
+ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
311+
+ // 0 1 0 1 0 1 0 0 [ imm19 ...
312+
+ //
313+
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
314+
+ // ... imm19 ] 0 [ cond ]
315+
+ CHECK(isInt64(19+2, addend)); /* X in range */
316+
+ *(inst_t *)P = (*(inst_t *)P & 0xff00001f)
317+
+ | ((uint32_t)(addend << (5-2)) & 0x00ffffe0);
318+
+ break;
319+
+ }
320+
case COMPAT_R_AARCH64_JUMP26: /* relocate b ... */
321+
case COMPAT_R_AARCH64_CALL26: { /* relocate bl ... */
322+
+ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
323+
+ // 0|1 0 0 1 0 1 [ imm26 ...
324+
+
325+
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
326+
+ // ... imm26 ]
327+
CHECK(isInt64(26+2, addend)); /* X in range */
328+
*(inst_t *)P = (*(inst_t *)P & 0xfc000000) /* keep upper 6 (32-6)
329+
* bits */
330+
@@ -222,6 +238,23 @@ computeAddend(Section * section, Elf_Rel * rel,
331+
case COMPAT_R_AARCH64_ADD_ABS_LO12_NC:
332+
/* type: static, class: aarch64, op: S + A */
333+
return (S + A) & 0xfff;
334+
+ case COMPAT_R_AARCH64_CONDBR19: {
335+
+ int64_t V = S + A - P;
336+
+ if(!isInt64(19+2, V)) {
337+
+ /* need a stub */
338+
+ /* check if we already have that stub */
339+
+ if(findStub(section, (void**)&S, 0)) {
340+
+ /* did not find it. Crete a new stub. */
341+
+ if(makeStub(section, (void**)&S, 0)) {
342+
+ abort(/* could not find or make stub */);
343+
+ }
344+
+ }
345+
+
346+
+ V = S + A -P;
347+
+ assert(isInt64(19+2, V));
348+
+ }
349+
+ return V;
350+
+ }
351+
case COMPAT_R_AARCH64_JUMP26:
352+
case COMPAT_R_AARCH64_CALL26: {
353+
// S+A-P

0 commit comments

Comments
 (0)