GCC doesn't put builtin function symbol references, which are defined in the shared C library, in the IR symbol table. As the result, --as-needed doesn't work with references to builtin functions: [hjl@gnu-cfl-3 as-needed]$ cat x.c #include <stdlib.h> int main() { abort (); return 0; } [hjl@gnu-cfl-3 as-needed]$ cat bar.c #include <stdlib.h> #include <stdio.h> void abort (void) { printf ("PASS\n"); exit (0); } [hjl@gnu-cfl-3 as-needed]$ make gcc -B./ -g -flto -c -o x.o x.c gcc -B./ -g -fPIC -c -o bar.o bar.c gcc -B./ -shared -o libbar.so bar.o gcc -B./ -Wl,--as-needed -o x x.o libbar.so -Wl,-R,. ./x make: *** [Makefile:12: all] Aborted (core dumped) [hjl@gnu-cfl-3 as-needed]$
Dup. *** This bug has been marked as a duplicate of bug 31482 ***
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c0419c024bf922128131671e40de0aed736e38ed commit c0419c024bf922128131671e40de0aed736e38ed Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Apr 4 18:46:40 2024 -0700 elf: Always honor the first definition in shared object and archive GCC doesn't put builtin function symbol references, which are defined in the shared C library, in the IR symbol table. When linker rescans shared objects and archives for newly added symbol references generated from the IR inputs, it skips definitions of the builtin functions in shared objects and archives. Add first_hash to elf_link_hash_table to track unreferenced definitions defined first in shared objects and archives. Always use them to resolve any references. bfd/ PR ld/31482 PR ld/31489 * elf-bfd.h (elf_link_hash_table): Add first_hash. * elflink.c (elf_link_add_to_first_hash): New function. (elf_link_add_object_symbols): Initialize first_hash for an IR input. Always use the first definition in shared object. Add the first unreferenced dynamic definition to first_hash. (_bfd_elf_archive_symbol_lookup): Add the first unreferenced definition to first_hash.. (elf_link_add_archive_symbols): Use the symbol definition in archive if symbol is defined first in this archive. (_bfd_elf_link_hash_table_free): Also free first_hash. ld/ PR ld/31482 PR ld/31489 * testsuite/ld-plugin/lto.exp: Add PR ld/31482 and PR ld/31489 tests. * testsuite/ld-elf/pr31482a-no-lto.c: New file. * testsuite/ld-elf/pr31482b-no-lto.c: Likewise. * testsuite/ld-elf/pr31482c-no-lto.c: Likewise. * testsuite/ld-elf/pr31482d-no-lto.c: Likewise. * testsuite/ld-plugin/pass1.out: Likewise. * testsuite/ld-plugin/pr31482a.c: Likewise. * testsuite/ld-plugin/pr31482b.c: Likewise. * testsuite/ld-plugin/pr31482c.c: Likewise.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=816fd3dced1b2e94789b6d7d1d1fab1988e8e05d commit 816fd3dced1b2e94789b6d7d1d1fab1988e8e05d Author: H.J. Lu <hjl.tools@gmail.com> Date: Fri Apr 5 16:37:58 2024 -0700 elf: Use elf_link_first_hash_entry for first_hash Add elf_link_first_hash_entry and use it for first_hash. Free first_hash before freeing the main hash table. PR ld/31482 PR ld/31489 * elf-bfd.h (elf_link_hash_table): Change first_hash to bfd_hash_table. * elflink.c (elf_link_first_hash_entry): New. (elf_link_first_hash_newfunc): Likewise. (elf_link_add_to_first_hash): Updated. (elf_link_add_object_symbols): Initialize first_hash with elf_link_first_hash_newfunc. (elf_link_add_object_symbols): Updated. (elf_link_add_archive_symbols): Likewise. (_bfd_elf_link_hash_table_free): Free first_hash before freeing the main hash table.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e7e05a9dd0c93038fdd5ed1904ca660e52beabdc commit e7e05a9dd0c93038fdd5ed1904ca660e52beabdc Author: Alan Modra <amodra@gmail.com> Date: Sat Apr 6 15:49:44 2024 +1030 Don't have first_hash entries of strings that can be freed. Seen running "LTO 1" under valgrind. ==1443263== Invalid read of size 1 ==1443263== at 0x484CFE4: strcmp (vg_replace_strmem.c:939) ==1443263== by 0x56E16C: bfd_hash_lookup (hash.c:564) ==1443263== by 0x5A3C8F: elf_link_add_to_first_hash (elflink.c:4316) ==1443263== by 0x5AE60F: elf_link_add_object_symbols (elflink.c:5663) ==1443263== by 0x5B0672: bfd_elf_link_add_symbols (elflink.c:6333) ==1443263== by 0x41448F: load_symbols (ldlang.c:3129) ==1443263== by 0x4149D8: open_input_bfds (ldlang.c:3621) ==1443263== by 0x414968: open_input_bfds (ldlang.c:3569) ==1443263== by 0x4166A2: lang_process (ldlang.c:8162) ==1443263== by 0x4194D5: main (ldmain.c:504) ==1443263== Address 0x525e230 is 192 bytes inside a block of size 4,064 free'd ==1443263== at 0x484810F: free (vg_replace_malloc.c:974) ==1443263== by 0x8D4D87: objalloc_free_block (objalloc.c:248) ==1443263== by 0x5AEACC: elf_link_add_object_symbols (elflink.c:5790) ==1443263== by 0x5B0672: bfd_elf_link_add_symbols (elflink.c:6333) ==1443263== by 0x41448F: load_symbols (ldlang.c:3129) ==1443263== by 0x4149D8: open_input_bfds (ldlang.c:3621) ==1443263== by 0x414968: open_input_bfds (ldlang.c:3569) ==1443263== by 0x4166A2: lang_process (ldlang.c:8162) ==1443263== by 0x4194D5: main (ldmain.c:504) PR ld/31482 PR ld/31489 * elflink.c (elf_link_add_to_first_hash): Add "copy" param. (elf_link_add_object_symbols): Flag that name must be copied when appending version string to symbol name.