summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-09-30 23:41:40 -0400
committerBen Gamari <ben@well-typed.com>2021-10-06 08:47:38 +0000
commitbbaf9457d261efb072746d595d6b990984de112f (patch)
treef45b419f35ddacfc3beb88a0d56e8353b0f1a546
parentd510ade8b5fa9ee9686a5d4e9707876cb4602b9d (diff)
downloadhaskell-bbaf9457d261efb072746d595d6b990984de112f.tar.gz
rts/linker: Define _DYNAMIC when necessary
Usually the dynamic linker would define _DYNAMIC. However, when dynamic linking is not supported (e.g. on musl) it is safe to define it to be NULL.
-rw-r--r--rts/Linker.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/rts/Linker.c b/rts/Linker.c
index 2641a677be..bff0b79b0c 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -869,7 +869,19 @@ SymbolAddr* lookupDependentSymbol (SymbolName* lbl, ObjectCode *dependent)
IF_DEBUG(linker, debugBelch("lookupSymbol: symbol '%s' not found, trying dlsym\n", lbl));
# if defined(OBJFORMAT_ELF)
- return internal_dlsym(lbl);
+ SymbolAddr *ret = internal_dlsym(lbl);
+
+ // Generally the dynamic linker would define _DYNAMIC, which is
+ // supposed to point to various bits of dynamic linker state (see
+ // [1]). However, if dynamic linking isn't supported (e.g. in the case
+ // of musl) then we can safely declare that it is NULL.
+ //
+ // [1] https://wiki.gentoo.org/wiki/Hardened/Introduction_to_Position_Independent_Code
+ if (ret == NULL && strcmp(lbl, "_DYNAMIC") == 0) {
+ static void *RTS_DYNAMIC = NULL;
+ ret = (SymbolAddr *) &RTS_DYNAMIC;
+ }
+ return ret;
# elif defined(OBJFORMAT_MACHO)
/* HACK: On OS X, all symbols are prefixed with an underscore.