Any attempt to load code in a statically-linked GHCi session on AArch64/Debian 11 is currently broken due to RtsSymbols.c not providing the __aarch64_ldadd1_acq_rel symbol, which was introduced for GCC's relatively-new out-of-line-atomics support:
I think I know how to fix this, there are lots of related issues with pretty much all our cross compilers. But fixing it properly likely requires us to add some logic to GHC that accepts a -linker-preload flag, and then feeding those mentioned libraries into the linker first. (instead of having it all hardcoded in the rts). Otherwise we'll eventually ending up throwing most of the libc, and libgcc (or similar) symbols into the rts.
@bgamari that seems quite similar! I would also have created (ideally dynamic), the RtsSymbols stub Lib and feed that in via -linker-preload. We can’t load all of libc, libgcc, … so we’d have to make do with some stub. Just outside of the rts itself ideally and dynamically changeable. (You can end up running into unknown symbols only when you compile some module that loads a c library, which uses some gcc/libc/… symbol the linker would provide by default).
I'm not sure we really want to make this runtime configurable. This is, afterall, only an issue of the toolchain.
I can also think of two other designs:
Always link (weakly) against all possible toolchain-provided symbols. Only insert those symbols which are defined into the symbol table. This is simpler to implement but doesn't rid us of the requirement that we maintain this list.
Simply add the out-of-line atomics builtins (of which __aarch64_ldadd1_acq_rel is one) to RtsSymbols and punt the problem down the road.
For 9.8, I think it would be best to do the latter.
@bgamari sure for 9.8 that sounds reasonable. In general I’m fairly certain we want some way to tell GHC to preload a library into the linker.
You often need these symbols only for the linker session. You don’t want them (all) in the RTS all the time. Even today the RTS_SYMBOLS is an annoying fragile hack.
if you could load libgcc, libc, libm, libatimic, rts, into the linker just fine (and this would likely only work for our static linker anyway), you could preload them always and have none of these symbol issues.
The problem is, we can’t. We can’t reinitialize values the libc expects to initialize only once (they are initiliazex when iserv starts up), same for other singleton state; it’s the same reason we can’t load the rts twice. For libgcc ther are even synthesized builtins, symbols that don’t exist anywhere but the compiler knows how to synthesize on demand.
I also do not think we can know or compute this completely at compile time.
So I do strongly believe we want to have a -linker-preload flag. And I also believe we want to separate out the rts symbols from the RTS and link them into some linker support library.
We’d likely also want to link the RTS_SYMBOLS only into the iserv/GHC executable, not into all rts libraries.