Fix GHC 9.14 external Mach-O signed addends [skip ci]

Mach-O SIGNED_N embeds a -N addend for trailing instruction bytes.
Normalize that addend in the external relocation path before subtracting
the next-instruction address; keep internal section relocations unchanged.

Apply the RTS package patch only to the native Intel Darwin stage2
compiler. Source application and module scope/order/laziness checks pass;
the rebuilt compiler and the observed mobile SIGBUS still need CI.
This commit is contained in:
Moritz Angermann committed 2026-10-19 00:01:59 +09:00
1 parent e709043882
commit 7ef6c382e5
2 files changed
+29

No files matched your search

@@ -13,6 +13,14 @@ lib.mkIf (
# Stage1 must emit correct info tables for the stage2 boot libraries;
# stage2 must retain that fix for application and interpreter objects.
packages.ghc.patches = lib.mkAfter [ ./ghc914-macho-info-tables.patch ];
# Patch the native compiler's RTS without changing its configured
# source or stage1 bootstrap. External Mach-O SIGNED_N relocations
# carry a trailing-byte bias that must be normalized exactly once.
packages.rts.patches = lib.mkIf (
config.name == "ghc914-sh-stage2"
&& config.compiler-nix-name == "ghc914-sh-stage1"
) (lib.mkAfter [ ./ghc914-rts-macho-signed-addends.patch ]);
})
];
}
@@ -0,0 +1,21 @@
--- a/linker/MachO.c
+++ b/linker/MachO.c
@@ -897,10 +897,18 @@
type = X86_64_RELOC_SIGNED;
}
else if (reloc->r_extern)
{
+ /* SIGNED_N's embedded addend already contains a -N bias for
+ * trailing instruction bytes. Normalize it before subtracting
+ * baseValue, which also includes N. Local relocations instead
+ * encode a displacement in the original image and are handled
+ * separately below.
+ */
+ thing += nextInstrAdj;
+
MachOSymbol *symbol = &symbols[reloc->r_symbolnum];
SymbolName* nm = symbol->name;
SymbolAddr* addr = NULL;
IF_DEBUG(linker_verbose, debugBelch("relocateSection: looking up external symbol %s\n", nm));