Adding a couple of lld folks.
I helped Shishir debug this, the link line looked like:
/home/sjessu/build/bin/clang -O0 -flto -o jcstest jcstest.o
and the issue was that libjpeg.a was created with the system ar instead of
llvm-ar. It worked when recreating libjpeg.a with llvm-ar.
I noticed that the lld code has some special handling for the case
when there is a missing symbol table, which often happens with system ar
created archives containing bitcode. I noticed that the lld code will
sometimes emit an error, but actually contains a special hack to handle
archives containing *only* bitcode objects, so that they are handled
correctly even when there is no symbol table because it was created with
the system ar.
⚙ D63781 [ELF] Error on archive with missing index added the "archive has no index; run
ranlib to add one" error.
A clarification: the LinkerDriver::addFile code handles mix-and-match
ELF object members and bitcode members. A LazyObjFile can be
either an ELF object file or an LLVM bitcode file.
Unfortunately, in this case it neither gave an error nor did
the special handling, because libjpeg.a also contains some native objects
and thus had a non-zero symbol table. I created a version of libjpeg.a
using the system library and containing only the bitcode objects, and
confirmed it links fine with lld (the native objects weren't needed in this
case). BTW this is the code in ELF/Driver.cpp LinkerDriver::addFile.
Would it be possible to extend the hack in lld to handle cases like this
with some bitcode objects and some non-bitcode objects, so that the bitcode
objects are not simply ignored?
I guess what happened here is that the archive has an incomplete symbol table.
nm -s (--print-armap) can print the symbol table.
% ar rc a.a a.bc a.o; nm -s a.a
_start in a.o
nm: a.bc: file format not recognized
0000000000000000 T _start
Currently lld trusts the archive symbol table. If the archive symbol table
actually misses some entries (GNU ar does not add bitcode definitions to the
symbol table), lld will not know that some lazy definitions are actually
It seems that if we have to make the GNU ar scenario work, lld has to distrust the archive symbol table when it contains bitcode files...
To not pessimize the case with all bitcode members but no ELF object members, we need to refine the hack to "distrust" the archive symbol table
if (the archive symbol table exists && an ELF object member exists && a bitcode member exists).
Does this scheme sound good?