git: 8fb4cfcd3ba2 - main - lang/ghc810: Add upstream patch fixing a rare linking problem.

From: Gleb Popov <arrowd_at_FreeBSD.org>
Date: Tue, 11 Oct 2022 20:32:28 UTC
The branch main has been updated by arrowd:

URL: https://cgit.FreeBSD.org/ports/commit/?id=8fb4cfcd3ba24b8ef7d702860ce02caf114c3799

commit 8fb4cfcd3ba24b8ef7d702860ce02caf114c3799
Author:     Gleb Popov <arrowd@FreeBSD.org>
AuthorDate: 2022-10-11 19:51:42 +0000
Commit:     Gleb Popov <arrowd@FreeBSD.org>
CommitDate: 2022-10-11 20:32:08 +0000

    lang/ghc810: Add upstream patch fixing a rare linking problem.
    
    lang/ghc does not require patching.
---
 lang/ghc810/Makefile                      |  1 +
 lang/ghc810/files/patch-linker-iconv.diff | 89 +++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+)

diff --git a/lang/ghc810/Makefile b/lang/ghc810/Makefile
index 0105166c8178..f6daff8f66f6 100644
--- a/lang/ghc810/Makefile
+++ b/lang/ghc810/Makefile
@@ -1,3 +1,4 @@
+PORTREVISION=		1
 PKGNAMESUFFIX=		810
 
 LIB_DEPENDS=		${GMP_LIB_DEPENDS}
diff --git a/lang/ghc810/files/patch-linker-iconv.diff b/lang/ghc810/files/patch-linker-iconv.diff
new file mode 100644
index 000000000000..a3f7a70fb528
--- /dev/null
+++ b/lang/ghc810/files/patch-linker-iconv.diff
@@ -0,0 +1,89 @@
+https://gitlab.haskell.org/ghc/ghc/-/commit/66d2e927842653fbc1cf2e6f997f443c78c2203b
+
+diff --git a/rts/Linker.c b/rts/Linker.c
+index 1faff3b3716dd6de440071c89d0dafa471657962..12d5418d02a95893b14a619be10b5cd49a054f1a 100644
+--- rts/Linker.c
++++ rts/Linker.c
+@@ -80,6 +80,33 @@
+ #if defined(dragonfly_HOST_OS)
+ #include <sys/tls.h>
+ #endif
++
++/*
++ * Note [iconv and FreeBSD]
++ * ~~~~~~~~~~~~~~~~~~~~~~~~
++ *
++ * On FreeBSD libc.so provides an implementation of the iconv_* family of
++ * functions. However, due to their implementation, these symbols cannot be
++ * resolved via dlsym(); rather, they can only be resolved using the
++ * explicitly-versioned dlvsym().
++ *
++ * This is problematic for the RTS linker since we may be asked to load
++ * an object that depends upon iconv. To handle this we include a set of
++ * fallback cases for these functions, allowing us to resolve them to the
++ * symbols provided by the libc against which the RTS is linked.
++ *
++ * See #20354.
++ */
++
++#if defined(freebsd_HOST_OS)
++extern void iconvctl();
++extern void iconv_open_into();
++extern void iconv_open();
++extern void iconv_close();
++extern void iconv_canonicalize();
++extern void iconv();
++#endif
++
+ /*
+    Note [runtime-linker-support]
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+@@ -637,6 +664,10 @@ internal_dlsym(const char *symbol) {
+     }
+     RELEASE_LOCK(&dl_mutex);
+ 
++    IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in special cases\n", symbol));
++#   define SPECIAL_SYMBOL(sym) \
++      if (strcmp(symbol, #sym) == 0) return (void*)&sym;
++
+ #   if defined(HAVE_SYS_STAT_H) && defined(linux_HOST_OS) && defined(__GLIBC__)
+     // HACK: GLIBC implements these functions with a great deal of trickery where
+     //       they are either inlined at compile time to their corresponding
+@@ -646,18 +677,28 @@ internal_dlsym(const char *symbol) {
+     //       We borrow the approach that the LLVM JIT uses to resolve these
+     //       symbols. See http://llvm.org/PR274 and #7072 for more info.
+ 
+-    IF_DEBUG(linker, debugBelch("internal_dlsym: looking for symbol '%s' in GLIBC special cases\n", symbol));
++    SPECIAL_SYMBOL(stat);
++    SPECIAL_SYMBOL(fstat);
++    SPECIAL_SYMBOL(lstat);
++    SPECIAL_SYMBOL(stat64);
++    SPECIAL_SYMBOL(fstat64);
++    SPECIAL_SYMBOL(lstat64);
++    SPECIAL_SYMBOL(atexit);
++    SPECIAL_SYMBOL(mknod);
++#   endif
+ 
+-    if (strcmp(symbol, "stat") == 0) return (void*)&stat;
+-    if (strcmp(symbol, "fstat") == 0) return (void*)&fstat;
+-    if (strcmp(symbol, "lstat") == 0) return (void*)&lstat;
+-    if (strcmp(symbol, "stat64") == 0) return (void*)&stat64;
+-    if (strcmp(symbol, "fstat64") == 0) return (void*)&fstat64;
+-    if (strcmp(symbol, "lstat64") == 0) return (void*)&lstat64;
+-    if (strcmp(symbol, "atexit") == 0) return (void*)&atexit;
+-    if (strcmp(symbol, "mknod") == 0) return (void*)&mknod;
++    // See Note [iconv and FreeBSD]
++#   if defined(freebsd_HOST_OS)
++    SPECIAL_SYMBOL(iconvctl);
++    SPECIAL_SYMBOL(iconv_open_into);
++    SPECIAL_SYMBOL(iconv_open);
++    SPECIAL_SYMBOL(iconv_close);
++    SPECIAL_SYMBOL(iconv_canonicalize);
++    SPECIAL_SYMBOL(iconv);
+ #   endif
+ 
++#undef SPECIAL_SYMBOL
++
+     // we failed to find the symbol
+     return NULL;
+ }