rui314 / mold

Mold: A Modern Linker 🦠
MIT License
14.2k stars 468 forks source link

Spurious "not claimed by the LTO plugin" when LTO is not used #1225

Closed intelfx closed 6 months ago

intelfx commented 6 months ago

Description

When trying to build a certain project and link it against system libraries, I'm getting a spurious "not claimed" error from mold even though no LTO is used in the entire project:

$ env | grep -e 'CC|CXX|FLAGS'
CFLAGS=-march=native -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=3 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fuse-ld=mold -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -Og -g
CXXFLAGS=-march=native -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=3 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fuse-ld=mold -Wp,-D_GLIBCXX_ASSERTIONS -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -Og -g
LDFLAGS=-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now -Wl,-z,pack-relative-relocs -fuse-ld=mold

$ autoreconf -vfi && ./configure <...> && make -j$(nproc)
<...>
mold: fatal: utf8_validity.cc.o: not claimed by the LTO plugin; please make sure you are using the same compiler of the same version for all object files
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:7547: netdata] Error 1

LTO is not used:

$ make -j$(nproc) V=1 | grep flto
ar: `u' modifier ignored since `D' is the default (see `U')
<...some C++ warnings...>
ar: `u' modifier ignored since `D' is the default (see `U')
ar: `u' modifier ignored since `D' is the default (see `U')
mold: fatal: utf8_validity.cc.o: not claimed by the LTO plugin; please make sure you are using the same compiler of the same version for all object files
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:7547: netdata] Error 1
make[1]: *** [Makefile:10843: all-recursive] Error 1
make: *** [Makefile:5092: all] Error 2

Unfortunately I don't know how to narrow it down or produce a minimal reproducer. I'm ready to provide whatever information or test-compiles that you request; if you could help me to narrow this down I'd be grateful.

Full build log: mold-issue-1225.log (edit: updated, fixed linebreaks)


Version

$ mold --version
mold 2.4.1 (fb3c166f80b92ca34ebd1b3f467edbcad7cae649; compatible with GNU ld)
rui314 commented 6 months ago

Can you upload your utf8_validity.cc.o file so that I can take a look at that file?

intelfx commented 6 months ago

@rui314 Apologies, this was a PEBKAC-type error (or perhaps PEBUAD, standing for "problem exists between upstream and distribution").

My distribution shipped parts of the protobuf library used by the code in question (the libutf8_range and libutf8_validity) as static archives, which turned out to only contain GCC bitcode due to said distribution using -flto across the board and gcc defaulting to -fno-fat-lto-objects when linker plugin is available:

$ pacman -Qql protobuf | grep '\.a$' | xargs readelf -s

File: /usr/lib/libutf8_range.a(naive.c.o)

Symbol table '.symtab' contains 2 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000001     1 OBJECT  GLOBAL DEFAULT  COM __gnu_lto_slim

File: /usr/lib/libutf8_range.a(range2-neon.c.o)

Symbol table '.symtab' contains 2 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000001     1 OBJECT  GLOBAL DEFAULT  COM __gnu_lto_slim

File: /usr/lib/libutf8_range.a(range2-sse.c.o)

Symbol table '.symtab' contains 2 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000001     1 OBJECT  GLOBAL DEFAULT  COM __gnu_lto_slim

File: /usr/lib/libutf8_validity.a(utf8_validity.cc.o)

Symbol table '.symtab' contains 2 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000001     1 OBJECT  GLOBAL DEFAULT  COM __gnu_lto_slim

The build failure did not appear reproducible with ld.bfd because the program in question did not, in fact, use any of the symbols therein (so apparently ld.bfd just skipped those archives entirely, whereas mold rightfully complained).

Problem solved by building protobuf with -ffat-lto-objects until upstream learns to honor the static/shared preference for all of its libraries.

Thanks, and sorry for the noise!