diff --git a/scripts/nix/darwin-info-table-project.nix b/scripts/nix/darwin-info-table-project.nix index c413ffc3ff..21ebb52857 100644 --- a/scripts/nix/darwin-info-table-project.nix +++ b/scripts/nix/darwin-info-table-project.nix @@ -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 ]); }) ]; } diff --git a/scripts/nix/ghc914-rts-macho-signed-addends.patch b/scripts/nix/ghc914-rts-macho-signed-addends.patch new file mode 100644 index 0000000000..8335614602 --- /dev/null +++ b/scripts/nix/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));