Support static linker semantics for archives and weak symbols
While looking at #5004 (closed), I had a go at getting the GHCi linker to load the LLVM libs, as in making this work:
ghci -package llvm.
This involves loading a whole bunch of LLVM*.a files and linking them against the C and C++ standard libs. This in turn requires a few more features in the GHCi linker:
- support for weak symbols
- search archives only on demand
- support .oS files in archives
The last is trivial.
The first is not so hard to do. When the linker finds a definition of a weak symbol, if there's already a symbol with that name in the symbol table then we just ignore the new one. When resolving symbols if we find an unresolved weak symbol we just give it the value zero. Doing this is enough to load .e.g libstdc++.a and libc.a (rather than libc.so).
The next part is a bit more work. When you give system static linker some .a files, it only uses them to provide definitions for unresolved symbols in the main target. In particular it is fine for two .a files to provide definitions of the same symbol because the linker just looks for the first. (This is in contrast to duplicate symbols in the main .o input files). On linux, both libm and libc define some of the same symbols, such as
Similarly, there is a problem that the GHCi linker predefines the
atexit symbol, but that is also defined by
So for the GHCi linker to load both libm and libc then it has to follow the standard semantics for linking archives. Currently it treats an archive as a request to link all the .o files in that archive.
Probably it is not sensible to go as far as implementing the full standard static linking semantics in the GHCi linker. It's of somewhat questionable value since we mainly need it for linking Haskell code, not C/C++ code.
Nevertheless, if we do need this, then the attached Linker.c has a partial implementation. It does the weak symbols and
.oS files in archives.