https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105133
Bug ID: 105133 Summary: lto/gold: lto failed to link --start-lib/--end-lib in gold Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: luoxhu at gcc dot gnu.org CC: marxin at gcc dot gnu.org Target Milestone: --- Hi, linker gold supports --start-lib and --end-lib to "mimics the semantics of static libraries, but without needing to actually create the archive file."(https://reviews.llvm.org/D66848). Sometimes large application may introduce multiple libraries from different repositories with same source code, they would be linked into one binary finally, recently I suffered from a link error with gold as linker and reduced an example as below: cat hello.c extern int hello(int a); int main(void) { return 0; /* hello(10); */ } cat ./B/libhello.c #include <stdio.h> int hello(int a) { puts("Hello"); return 0; } cat ./C/libhello.c #include <stdio.h> int hello(int a) { puts("Hello"); return 0; } (1) NON lto link with gold is OK: gcc -O2 -o ./B/libhello.c.o -c ./B/libhello.c gcc-ar qc ./B/libhello.a ./B/libhello.c.o gcc-ranlib ./B/libhello.a gcc -O2 -o ./C/libhello.c.o -c ./C/libhello.c gcc-ar qc ./C/libhello.a ./C/libhello.c.o gcc-ranlib ./C/libhello.a gcc hello.c -o hello.o -c -O2 gcc -o hellow hello.o -Wl,--start-lib ./B/libhello.c.o -Wl,--end-lib -Wl,--start-lib ./C/libhello.c.o -Wl,--end-lib -O2 -fuse-ld=gold (2) lto link with gold fails with redefinition: gcc -O2 -flto -o ./B/libhello.c.o -c ./B/libhello.c gcc-ar qc ./B/libhello.a ./B/libhello.c.o gcc-ranlib ./B/libhello.a gcc -O2 -flto -o ./C/libhello.c.o -c ./C/libhello.c gcc-ar qc ./C/libhello.a ./C/libhello.c.o gcc-ranlib ./C/libhello.a gcc hello.c -o hello.o -c -O2 -flto gcc -o hellow hello.o -Wl,--start-lib ./B/libhello.c.o -Wl,--end-lib -Wl,--start-lib ./C/libhello.c.o -Wl,--end-lib -O2 -flto -fuse-ld=gold ./B/libhello.c:5:5: error: 'hello' has already been defined 5 | int hello(int a) | ^ ./B/libhello.c:5:5: note: previously defined here lto1: fatal error: errors during merging of translation units compilation terminated. lto-wrapper: fatal error: gcc returned 1 exit status compilation terminated. /usr/bin/ld.gold: fatal error: lto-wrapper failed collect2: error: ld returned 1 exit status This error happens at function gcc/lto/lto-symtab.c:lto_symtab_resolve_symbols, simply remove the error_at line could work, but this may be not a reasonable fix. /* Find the single non-replaceable prevailing symbol and diagnose ODR violations. */ for (e = first; e; e = e->next_sharing_asm_name) { if (!lto_symtab_resolve_can_prevail_p (e)) continue; /* If we have a non-replaceable definition it prevails. */ if (!lto_symtab_resolve_replaceable_p (e)) { if (prevailing) { error_at (DECL_SOURCE_LOCATION (e->decl), "%qD has already been defined", e->decl); inform (DECL_SOURCE_LOCATION (prevailing->decl), "previously defined here"); } prevailing = e; } } cat hellow.res 3 hello.o 2 192 ccb9165e03755470 PREVAILING_DEF main 197 ccb9165e03755470 PREVAILING_DEF_IRONLY s ./B/libhello.c.o 1 205 68e0b97e93a52d7a PREEMPTED_REG hello ./C/libhello.c.o 1 205 18fe2d3482bfb511 PREEMPTED_REG hello Secondly, If call hello(10) in hello.c , there will be NO error reported out. The difference is the resolution type is changed from PREEMPTED_REG to RESOLVED_IR/PREVAILING_DEF_IRONLY. 3 hello.o 3 192 19ef867d12f62129 PREVAILING_DEF main 197 19ef867d12f62129 PREVAILING_DEF_IRONLY s 201 19ef867d12f62129 RESOLVED_IR hello ./B/libhello.c.o 1 205 23c5c855935478ce PREVAILING_DEF_IRONLY hello ./C/libhello.c.o 1 205 abbf050f5c23b448 PREEMPTED_REG hello Is this a valid bug? Thanks.