ThinLTO with Linux+ELF+Gold -- incorrectly dropping weak definitions.

I am tracking a problem with ThinLTO on Linux using gold and elf files where there is a disconnect between gold’s treatment of comdat groups and ThinLTO’s decisions about which weak references to convert to available externally. The net result is a definition is lost and a relocation entry is not handled.

My status is summarized:

Anyone familiar with this space and have guidance? Either on how to avoid the problem, or a patch to correct it?




This looks similar to the problem I fixed awhile back in r292408. I’ll take a look (probably tomorrow since I am taking some vacation today).

I have now observed that some of the object files, while compiled -flto=thin and determined to be missing the ThinLTOSummary and are being lumped into the “regularLTO” pass. This might explain some of my problem. Under what conditions would this summary be missing? Is it ever legal to mix -flto and -flto=thin object files?

+pcc who may have some thoughts

But yes, it is legal to mix -flto and -flto=thin - at link time we’ll do regularLTO across all the -flto objects and thinLTO on the -flto=thin objects, and the resulting native objects all get linked in the end.

But if you do -flto=thin we should get a summary block (it will be empty if there are no global values, but we should still do ThinLTO compilation on it). There was a time in the past when we would not generate a summary block when we had inline assembly, as a workaround for some other issues, but that has been fixed. If you are seeing no summary block generated with -flto=thin, can you send me a reproducer? Especially if it reproduces at head.

Are the issues reported in the bug related to objects that are being handled by regularLTO?



Yes, I the objects handled by regularLTO are implicated. They have a comdat group.

I see now this is intentional in splitAndWriteThinLTOBitcode in ThinLTOBitcodeWriter.cpp

Still struggling to figure out how to reduce this.


As you discovered, any translation units which define vtables and do not contain external symbol definitions may be compiled without a summary and with full LTO even if -flto=thin is supplied.

I was unable to reproduce the comdat group issue you mentioned on the bug with a ToT clang.

$ cat /tmp/guard.cpp
struct S {
struct G { ~G(); int i; };
S() {
static G i;
ii = ++i.i;
int ii;

S thevar;

$ clang++ -c -o /tmp/guard.o /tmp/guard.cpp

$ readelf -a /tmp/guard.o

COMDAT group section [ 5] `.group’ [_ZN1SC2Ev] contains 2 sections:
[Index] Name
[ 6] .text._ZN1SC2Ev
[ 7] .rela.text._ZN1SC2Ev

COMDAT group section [ 9] `.group’ [_ZZN1SC1EvE1i] contains 1 sections:
[Index] Name
[ 10] .bss._ZZN1SC1EvE1i

COMDAT group section [ 11] `.group’ [_ZGVZN1SC1EvE1i] contains 1 sections:
[Index] Name
[ 12] .bss._ZGVZN1SC1EvE1i


Maybe this somehow only happens with LTO, but I’d check to see if you can reproduce it with regular objects first.