git: be5f5db25099 - main - lang/ghc: Add RTS linker patch for the external interpreter.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 07 Jul 2022 10:24:58 UTC
The branch main has been updated by arrowd: URL: https://cgit.FreeBSD.org/ports/commit/?id=be5f5db250995bdf3b4fa02b0ea958a0cf838f66 commit be5f5db250995bdf3b4fa02b0ea958a0cf838f66 Author: Gleb Popov <arrowd@FreeBSD.org> AuthorDate: 2021-12-29 09:12:27 +0000 Commit: Gleb Popov <arrowd@FreeBSD.org> CommitDate: 2022-07-07 10:24:10 +0000 lang/ghc: Add RTS linker patch for the external interpreter. --- lang/ghc/files/patch-rts-linker | 87 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/lang/ghc/files/patch-rts-linker b/lang/ghc/files/patch-rts-linker new file mode 100644 index 000000000000..feb736f72176 --- /dev/null +++ b/lang/ghc/files/patch-rts-linker @@ -0,0 +1,87 @@ +diff --git a/rts/Linker.c b/rts/Linker.c +index 72533ae52af48184fb76171fb93a73c04d025f2f..09cf5fa0593743f9b9f44603e2290cea9132ed89 100644 +--- rts/Linker.c ++++ rts/Linker.c +@@ -78,6 +78,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] + ----------------------------- +@@ -655,6 +682,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 +@@ -664,18 +695,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; + }