Skip to content

Commit

Permalink
Fix patch
Browse files Browse the repository at this point in the history
  • Loading branch information
hamishmack committed Nov 13, 2024
1 parent e7ea82c commit 7a139cc
Show file tree
Hide file tree
Showing 2 changed files with 358 additions and 1 deletion.
3 changes: 2 additions & 1 deletion overlays/bootstrap.nix
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ in {
++ onMusl (onAarch64 (fromUntil "9.8" "9.10" ./patches/ghc/ghc-9.8-hadrian-strip-cmd.patch))
++ onMusl (onAarch64 (fromUntil "9.10" "9.12" ./patches/ghc/ghc-9.10-hadrian-strip-cmd.patch))
++ on32bit (fromUntil "9.0" "9.4" ./patches/ghc/ghc-9.6-32bit-cmm.patch)
++ onAndroid (fromUntil "9.6.3" "9.10" ./patches/ghc/ghc-9.6-iog.patch)
++ onAndroid (fromUntil "9.6.3" "9.8.3" ./patches/ghc/ghc-9.6-iog.patch)
++ onAndroid (fromUntil "9.8.3" "9.10" ./patches/ghc/ghc-9.8.3-iog.patch)
++ onAndroid (fromUntil "9.6" "9.9" ./patches/ghc/ghc-9.6-debug-secno.patch)

# Allow loading static external plugins into cross compilers
Expand Down
356 changes: 356 additions & 0 deletions overlays/patches/ghc/ghc-9.8.3-iog.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,356 @@
diff --git a/rts/Linker.c b/rts/Linker.c
index 1f229f8173..7f954702a3 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -273,7 +273,7 @@ int ghciInsertSymbolTable(
RtsSymbolInfo *pinfo = lookupStrHashTable(table, key);
if (!pinfo) /* new entry */
{
- pinfo = stgMallocBytes(sizeof (*pinfo), "ghciInsertToSymbolTable");
+ pinfo = stgCallocBytes(1, sizeof (*pinfo), "ghciInsertToSymbolTable");
pinfo->value = data;
pinfo->owner = owner;
pinfo->strength = strength;
@@ -1203,7 +1203,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize,


IF_DEBUG(linker, debugBelch("mkOc: %" PATH_FMT "\n", path));
- oc = stgMallocBytes(sizeof(ObjectCode), "mkOc(oc)");
+ oc = stgCallocBytes(1, sizeof(ObjectCode), "mkOc(oc)");

oc->info = NULL;
oc->type = type;
@@ -1223,7 +1223,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
oc->fileName = pathdup(path);

if (archiveMemberName) {
- oc->archiveMemberName = stgMallocBytes( (pathlen(archiveMemberName)+1) * pathsize,
+ oc->archiveMemberName = stgCallocBytes(1, (pathlen(archiveMemberName)+1) * pathsize,
"loadObj" );
pathcopy(oc->archiveMemberName, archiveMemberName);
} else {
@@ -1380,12 +1380,12 @@ preloadObjectFile (pathchar *path)
// reading the file, and then we misalign image on purpose so
// that the actual sections end up aligned again.
misalignment = machoGetMisalignment(f);
- image = stgMallocBytes(fileSize + misalignment, "loadObj(image)");
+ image = stgCallocBytes(1, fileSize + misalignment, "loadObj(image)");
image += misalignment;

# else /* !defined(darwin_HOST_OS) */

- image = stgMallocBytes(fileSize, "loadObj(image)");
+ image = stgCallocBytes(1, fileSize, "loadObj(image)");

#endif /* !defined(darwin_HOST_OS) */

@@ -1678,6 +1678,8 @@ static HsInt resolveObjs_ (void)
IF_DEBUG(linker, debugBelch("resolveObjs: start\n"));

for (ObjectCode *oc = objects; oc; oc = oc->next) {
+ if(oc->status == OBJECT_RESOLVED)
+ continue;
int r = ocTryLoad(oc);
if (!r) {
errorBelch("Could not load Object Code %" PATH_FMT ".\n", OC_INFORMATIVE_FILENAME(oc));
@@ -1806,7 +1808,7 @@ void
addProddableBlock ( ObjectCode* oc, void* start, int size )
{
ProddableBlock* pb
- = stgMallocBytes(sizeof(ProddableBlock), "addProddableBlock");
+ = stgCallocBytes(1,sizeof(ProddableBlock), "addProddableBlock");

IF_DEBUG(linker, debugBelch("addProddableBlock: %p %p %d\n", oc, start, size));
ASSERT(size > 0);
diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h
index e6098aa2b0..4b8992e817 100644
--- a/rts/LinkerInternals.h
+++ b/rts/LinkerInternals.h
@@ -299,6 +299,10 @@ struct _ObjectCode {
int n_segments;
Segment *segments;

+ // COMMON section
+ void * common_mem;
+ unsigned long common_size;
+
//
// Garbage collection fields
//
diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c
index 4cac10ba15..fe0d8ca40e 100644
--- a/rts/RtsUtils.c
+++ b/rts/RtsUtils.c
@@ -104,6 +104,11 @@ stgCallocBytes (size_t count, size_t size, char *msg)
rtsConfig.mallocFailHook((W_) count*size, msg);
stg_exit(EXIT_INTERNAL_ERROR);
}
+ // If we run under qemu with jemalloc, calloc is not guaranteed
+ // to zero memory.
+ // - https://giters.com/jemalloc/jemalloc/issues/1844
+ // - https://lists.nongnu.org/archive/html/qemu-devel/2020-05/msg03119.html
+ memset(space, 0, count*size);
return space;
}

diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c
index d181450190..1ad05fc286 100644
--- a/rts/linker/Elf.c
+++ b/rts/linker/Elf.c
@@ -307,6 +307,15 @@ ocInit_ELF(ObjectCode * oc)
}
}
}
+ if(NULL != oc->common_mem) {
+#if RTS_LINKER_USE_MMAP
+ munmap(oc->common_mem, oc->common_size);
+#else
+ stgFree(oc->common_mem);
+#endif
+ }
+ oc->common_mem = NULL;
+ oc->common_size = 0;
}

void
@@ -963,14 +972,17 @@ ocGetNames_ELF ( ObjectCode* oc )
for (size_t j = 0; j < symTab->n_symbols; j++) {
ElfSymbol *symbol = &symTab->symbols[j];
if (SHN_COMMON == symTab->symbols[j].elf_sym->st_shndx) {
- common_size += symbol->elf_sym->st_size;
+ // st_value holds the alignment. Adding alignment always
+ // should give us some wiggle room to get alignment right.
+ common_size += symbol->elf_sym->st_size + symbol->elf_sym->st_value;
}
}
}
- void * common_mem = NULL;
+ oc->common_mem = NULL;
+ oc->common_size = common_size;
if(common_size > 0) {
- common_mem = mmapAnonForLinker(common_size);
- if (common_mem == NULL) {
+ oc->common_mem = mmapAnonForLinker(common_size);
+ if (oc->common_mem == NULL) {
barf("ocGetNames_ELF: Failed to allocate memory for SHN_COMMONs");
}
}
@@ -1011,9 +1023,10 @@ ocGetNames_ELF ( ObjectCode* oc )
if (shndx == SHN_COMMON) {
isLocal = false;
CHECK(common_used < common_size);
- CHECK(common_mem);
- symbol->addr = (void*)((uintptr_t)common_mem + common_used);
- common_used += symbol->elf_sym->st_size;
+ CHECK(oc->common_mem);
+ int alignment = symbol->elf_sym->st_value-1;
+ symbol->addr = (void*)(((uintptr_t)oc->common_mem + common_used + alignment) & ~alignment);
+ common_used = (uintptr_t)symbol->addr - (uintptr_t)oc->common_mem + symbol->elf_sym->st_size;
CHECK(common_used <= common_size);

IF_DEBUG(linker_verbose,
@@ -1027,7 +1040,9 @@ ocGetNames_ELF ( ObjectCode* oc )
|| ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK
)
/* and not an undefined symbol */
- && shndx != SHN_UNDEF
+ && (shndx != SHN_UNDEF
+ /* unless it's weak */
+ || (shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK))
/* and not in a "special section" */
&& (shndx < SHN_LORESERVE
#if defined(SHN_XINDEX)
@@ -1054,6 +1069,14 @@ ocGetNames_ELF ( ObjectCode* oc )
(intptr_t) oc->sections[secno].start +
(intptr_t) symbol->elf_sym->st_value);
CHECK(symbol->addr != 0x0);
+ if(shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK) {
+ symbol->addr = NULL;
+ } else {
+ symbol->addr = (SymbolAddr*)(
+ (intptr_t) oc->sections[secno].start +
+ (intptr_t) symbol->elf_sym->st_value);
+ CHECK(symbol->addr != 0x0);
+ }
if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_LOCAL) {
isLocal = true;
isWeak = false;
@@ -1065,42 +1088,20 @@ ocGetNames_ELF ( ObjectCode* oc )
isWeak = ELF_ST_BIND(symbol->elf_sym->st_info)
== STB_WEAK;
}
- }
-
- SymType sym_type;
- if (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC) {
- sym_type = SYM_TYPE_CODE;
+ } else if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK
+ && shndx == SHN_UNDEF
+ && (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC
+ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_OBJECT
+ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_NOTYPE)) {
+ symbol->addr = NULL;
+ isLocal = false;
+ isWeak = true;
} else {
- sym_type = SYM_TYPE_DATA;
- }
-
- /* And the decision is ... */
-
- if (symbol->addr != NULL) {
- CHECK(nm != NULL);
- /* Acquire! */
- if (!isLocal) {
-
- if (isWeak == HS_BOOL_TRUE) {
- setWeakSymbol(oc, nm);
- }
- if (!ghciInsertSymbolTable(oc->fileName, symhash,
- nm, symbol->addr, isWeak, sym_type, oc)
- ) {
- goto fail;
- }
- oc->symbols[curSymbol].name = nm;
- oc->symbols[curSymbol].addr = symbol->addr;
- oc->symbols[curSymbol].type = sym_type;
- curSymbol++;
- }
- } else {
- /* Skip. */
+ /* Skip. */
IF_DEBUG(linker_verbose,
debugBelch("skipping `%s'\n",
nm)
);
-
/*
debugBelch(
"skipping bind = %d, type = %d, secno = %d `%s'\n",
@@ -1110,7 +1111,34 @@ ocGetNames_ELF ( ObjectCode* oc )
nm
);
*/
+ continue;
}
+
+ SymType sym_type;
+ if (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC) {
+ sym_type = SYM_TYPE_CODE;
+ } else {
+ sym_type = SYM_TYPE_DATA;
+ }
+
+ /* And the decision is ... */
+ CHECK(nm != NULL);
+ /* Acquire! */
+ if (!isLocal) {
+
+ if (isWeak == HS_BOOL_TRUE) {
+ setWeakSymbol(oc, nm);
+ }
+ if (!ghciInsertSymbolTable(oc->fileName, symhash,
+ nm, symbol->addr, isWeak, sym_type, oc)
+ ) {
+ goto fail;
+ }
+ oc->symbols[curSymbol].name = nm;
+ oc->symbols[curSymbol].addr = symbol->addr;
+ oc->symbols[curSymbol].type = sym_type;
+ curSymbol++;
+ }
}
}
}
diff --git a/rts/linker/elf_plt.c b/rts/linker/elf_plt.c
index 5c6ef8ed44..314d49cbc6 100644
--- a/rts/linker/elf_plt.c
+++ b/rts/linker/elf_plt.c
@@ -1,4 +1,5 @@
#include "Rts.h"
+#include "RtsUtils.h"
#include "elf_plt.h"

#include <stdbool.h>
@@ -51,7 +52,7 @@ makeStub(Section * section,
void* * addr,
uint8_t flags) {

- Stub * s = calloc(1, sizeof(Stub));
+ Stub * s = stgCallocBytes(1, sizeof(Stub), "makeStub");
ASSERT(s != NULL);
s->target = *addr;
s->flags = flags;
diff --git a/rts/linker/elf_plt_aarch64.c b/rts/linker/elf_plt_aarch64.c
index 11354a63db..6b27a2c73d 100644
--- a/rts/linker/elf_plt_aarch64.c
+++ b/rts/linker/elf_plt_aarch64.c
@@ -25,6 +25,7 @@ const size_t stubSizeAarch64 = 5 * 4;
*/
bool needStubForRelAarch64(Elf_Rel * rel) {
switch(ELF64_R_TYPE(rel->r_info)) {
+ case COMPAT_R_AARCH64_CONDBR19:
case COMPAT_R_AARCH64_CALL26:
case COMPAT_R_AARCH64_JUMP26:
return true;
@@ -34,6 +35,7 @@ bool needStubForRelAarch64(Elf_Rel * rel) {
}
bool needStubForRelaAarch64(Elf_Rela * rela) {
switch(ELF64_R_TYPE(rela->r_info)) {
+ case COMPAT_R_AARCH64_CONDBR19:
case COMPAT_R_AARCH64_CALL26:
case COMPAT_R_AARCH64_JUMP26:
return true;
diff --git a/rts/linker/elf_reloc_aarch64.c b/rts/linker/elf_reloc_aarch64.c
index 51d7178094..dc0724c4f1 100644
--- a/rts/linker/elf_reloc_aarch64.c
+++ b/rts/linker/elf_reloc_aarch64.c
@@ -105,8 +105,24 @@ encodeAddendAarch64(Section * section, Elf_Rel * rel, int64_t addend) {
break;
}
/* - control flow relocations */
+ case COMPAT_R_AARCH64_CONDBR19: { /* relocate b.* ... */
+ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
+ // 0 1 0 1 0 1 0 0 [ imm19 ...
+ //
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // ... imm19 ] 0 [ cond ]
+ CHECK(isInt64(19+2, addend)); /* X in range */
+ *(inst_t *)P = (*(inst_t *)P & 0xff00001f)
+ | ((uint32_t)(addend << (5-2)) & 0x00ffffe0);
+ break;
+ }
case COMPAT_R_AARCH64_JUMP26: /* relocate b ... */
case COMPAT_R_AARCH64_CALL26: { /* relocate bl ... */
+ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
+ // 0|1 0 0 1 0 1 [ imm26 ...
+
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // ... imm26 ]
CHECK(isInt64(26+2, addend)); /* X in range */
*(inst_t *)P = (*(inst_t *)P & 0xfc000000) /* keep upper 6 (32-6)
* bits */
@@ -222,6 +238,23 @@ computeAddend(Section * section, Elf_Rel * rel,
case COMPAT_R_AARCH64_ADD_ABS_LO12_NC:
/* type: static, class: aarch64, op: S + A */
return (S + A) & 0xfff;
+ case COMPAT_R_AARCH64_CONDBR19: {
+ int64_t V = S + A - P;
+ if(!isInt64(19+2, V)) {
+ /* need a stub */
+ /* check if we already have that stub */
+ if(findStub(section, (void**)&S, 0)) {
+ /* did not find it. Crete a new stub. */
+ if(makeStub(section, (void**)&S, 0)) {
+ abort(/* could not find or make stub */);
+ }
+ }
+
+ V = S + A -P;
+ assert(isInt64(19+2, V));
+ }
+ return V;
+ }
case COMPAT_R_AARCH64_JUMP26:
case COMPAT_R_AARCH64_CALL26: {
// S+A-P

0 comments on commit 7a139cc

Please sign in to comment.