mold tests failed with unversioned symbols
mold tests failed using ld with the fix for
https://sourceware.org/bugzilla/show_bug.cgi?id=33577
+ cc -B. -o out/test/x86_64/wrap-lto/exe out/test/x86_64/wrap-lto/a.so out/test/x86_64/wrap-lto/b.o -flto
mold: error: undefined symbol: foo
>>> referenced by <artificial>
>>> /tmp/ccJUq1KE.ltrans0.ltrans.o:(main)
collect2: error: ld returned 1 exit status
Before the PR ld/33577 fix:
/tmp/a.so: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000 w D *UND* 0000000000000000 Base _ITM_deregisterTMCloneTable
0000000000000000 w D *UND* 0000000000000000 Base __gmon_start__
0000000000000000 w D *UND* 0000000000000000 Base _ITM_registerTMCloneTable
0000000000000000 w DF *UND* 0000000000000000 (GLIBC_2.2.5) __cxa_finalize
0000000000000396 g DF .text 000000000000000d Base bar
0000000000000389 g DF .text 000000000000000d Base foo
After the fix:
/tmp/a.so: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable
0000000000000000 w DF *UND* 0000000000000000 (GLIBC_2.2.5) __cxa_finalize
0000000000000396 g DF .text 000000000000000d bar
0000000000000389 g DF .text 000000000000000d foo
The difference is that unversioned symbols no longer have the Base version.
Are you testing it on Solaris? I wonder how I can reproduce the failure.
Are you testing it on Solaris? I wonder how I can reproduce the failure.
You can reproduce it with binutils master branch on Linux.
This works for me: 0001-Treat-symbols-with-cleared-DT_VERSYM-entries-as-glob.patch
So, GNU ld now fills .gnu.version slots with VER_NDX_LOCAL instead of VER_NDX_GLOBAL by default? That seems like a huge churn for no real benefit. It completely breaks compatibility with all previous versions of the mold linker. We’ve been using GNU ld as the de facto golden standard for linker output, and it has been emitting .gnu.version the way it currently does probably since the very beginning. I don’t think that change should have been made just to make the objdump output a little prettier.
I can accept your patch so that we can make that change later, but I strongly believe we need a grace period for users to upgrade their linkers.
That said, I don’t think changing the contents of .gnu.version is absolutely necessary, since this is an aesthetic change with no real benefit to users.
Note that only a few mold tests failed due to the recent change in GNU ld, because only in those tests we do (accidentally) use GNU ld to link a shared object file and then use mold to link against that .so file. As long as we link everything with mold, we are of course not affected by GNU ld’s change. However, in the real world, it is common to use GNU ld to link some shared object files while using mold as the main linker for large programs. The GNU ld change completely breaks this use case unless you upgrade mold before GNU ld.
I made a comment about more context https://sourceware.org/bugzilla/show_bug.cgi?id=33577#c34
GNU ld has used index 0 for unversioned undefined symbols both before version 2.35 (see https://sourceware.org/PR26002 in 2020) and in the upcoming 2.46 release (see https://sourceware.org/PR33577). [...] Therefore, I think it makes sense for other ELF linkers to adopt index 0 for unversioned undefined symbols.
Index 0 had been the traditional behavior until changed in 2020 for https://sourceware.org/PR26002 (I forgot that I had raised this issue. I'll amend https://maskray.me/blog/2020-11-26-all-about-symbol-versioning )