summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2021-09-09 18:48:11 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-10-12 19:16:40 -0400
commit005b1848eb4d1c5c5d2c175be0530a7b718bf7bf (patch)
tree4c95b94a4197637aaa00e0ba1af072998350d483
parent08aa7a1d2bb046398a2fc4c236b4267aa83244be (diff)
downloadhaskell-005b1848eb4d1c5c5d2c175be0530a7b718bf7bf.tar.gz
rts/RtsSymbols: Declare atexit as a strong symbol
-rw-r--r--rts/RtsSymbols.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c
index 0a821de64b..32f94b3cca 100644
--- a/rts/RtsSymbols.c
+++ b/rts/RtsSymbols.c
@@ -60,7 +60,7 @@
SymI_HasProto(signal_handlers) \
SymI_HasProto(stg_sig_install) \
SymI_HasProto(rtsTimerSignal) \
- SymI_HasProto(atexit) \
+ SymI_HasProto_redirect(atexit, atexit, STRENGTH_STRONG) /* See Note [Strong symbols] */ \
SymI_NeedsDataProto(environ) \
SymI_NeedsDataProto(nocldstop)
#endif
@@ -89,6 +89,15 @@
* which is loaded later. GHC generalizes this notion, allowing symbol
* definitions to be declared as *strong*. A strong symbol is one which will
* silently supercede definitions of the same name by later objects.
+ *
+ * This is currently only used in the case of atexit() to workaround an
+ * unfortunate interaction on musl systems (#20350). Specifically,
+ * we include atexit() in RtsSymbols to ensure that it can be used by foreign
+ * code loaded by the RTS linker (see #4456). However, this causes trouble on
+ * statically-linked musl systems since musl's libc.a defines atexit() as a
+ * non-weak symbol, causing it to conflict with the symbol table entry produced
+ * by the RtsSymbols entry. To avoid this we introduce a horrible special case
+ * in `ghciInsertSymbolTable`, ensure that `atexit` is never overridden.
*/
/*
* Note [Symbols for MinGW's printf]