llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.8k stars 11.45k forks source link

--icf=safe warnings when using sanitizers on Ubuntu due to strip #98354

Open Trass3r opened 1 month ago

Trass3r commented 1 month ago
LDFLAGS="-fsanitize=leak -fuse-ld=lld -Xlinker --icf=safe"
clang++ -o ...
ld.lld: warning: /usr/lib/llvm-18/lib/clang/18/lib/linux/libclang_rt.lsan-x86_64.a(interception_linux.cpp.o):
        --icf=safe conservatively ignores SHT_LLVM_ADDRSIG [index 10] with sh_link=0 (likely created using objcopy or ld -r)

It's not objcopy/ld -r, Ubuntu strips the library: https://launchpadlibrarian.net/724504654/buildlog_ubuntu-noble-amd64.llvm-toolchain-18_1%3A18.1.3-1_BUILDING.txt.gz

strip --strip-debug --remove-section=.comment --remove-section=.note --enable-deterministic-archives -R .gnu.lto_\* -R .gnu.debuglto_\* -N __gnu_lto_slim -N __gnu_lto_v1 debian/libclang-rt-18-dev/usr/lib/llvm-18/lib/clang/18/lib/linux/libclang_rt.lsan-x86_64.a

That destroys the sh_link. Question is if this is a bug. llvm-strip seems to do the same thing.

MaskRay commented 1 month ago

The title can be changed from "LSAN" to "Sanitizers".

It's not objcopy/ld -r, Ubuntu strips the library:

In GNU binutils and LLVM objcopy, objcopy/strip share implementation, so it is not wrong not to mention strip.

The warning is by design and the only meaningful fix is for the distributions not to invoke objcopy/strip/ld -r. I believe the compiler-rt libraries cannot be built using GCC LTO anyway. There might be some way to compile the libraries with -fno-ident -g0 so that --strip-debug --remove-section=.comment is not needed.


https://maskray.me/blog/2020-11-15-explain-gnu-linker-options#icfall-and---icfsafe

ld.lld --icf=safe uses a special section .llvm_addrsig (LLVM address significance table, type SHT_LLVM_ADDRSIG) produced by Clang -faddrsig. As of 2023-01, -faddrsig is the default on most Linux targets but disabled for Android, Gentoo, and -fintegrated-as. If the section is absent, ld.lld is conservative and assumes every section defining a symbol in the table is address significant.

SHT_LLVM_ADDRSIG encodes symbol indexes as ULEB128. objcopy, ld -r, and other binary manipulation tools may alter the symbol table. An interesting property is that objcopy and ld -r sets sh_link=0 for an known section type SHT_LLVM_ADDRSIG. ld.lld uses sh_link!=0 to check the validity and reports a warning in case of sh_link==0. a

https://maskray.me/blog/2024-03-09-a-compact-relocation-format-for-elf#llvm_addrsig

If CREL is adopted, we can consider switching to the relocation representation.

This will eventually address the size downside, but a distribution using binutils needs to wait for this CREL feature request https://sourceware.org/bugzilla/show_bug.cgi?id=31475

Trass3r commented 1 month ago

--icf=safe conservatively ignores SHT_LLVM_ADDRSIG [index 10] with sh_link=0

If the section is absent, ld.lld is conservative and assumes every section defining a symbol in the table is address significant.

So it will simply do less potential ICF. That's fine.