According to GNU ld documentation, using the EXTERN(symbol) in a linker script has the same effect as the -u/--undefined command-line parameter.
When using such a linker script with lld, the linker doesn't add these symbols to the output file. A simple example:
$ touch a.c $ clang -c a.c -o a.o $ echo "EXTERN(test)" > a.lds $ ld.lld -T a.lds a.o -o a.out $ objdump -t a.out | grep test $
These are not added because these symbols are not added to lld's symbol table. Driver.cpp has this code:
for (StringRef Arg : Config->Undefined) if (Symbol *Sym = Symtab->find(Arg)) handleUndefined(Sym);
Here, Symtab is empty, which is why lld silently discards the symbols declared in the script.
I can see two possible fixes for this issue:
- The one I'm proposing in this review: add the symbols to Symtab as they are read by the script parser
- Add them to Symtab close to that piece of code in Driver.cpp.