[PATCH v3] elf: Don't set its DT_VERSYM entry for unversioned symbol
Jan Beulich
jbeulich@suse.com
Wed Nov 12 06:43:35 GMT 2025
On 12.11.2025 07:37, Fangrui Song wrote:
> On Tue, Nov 11, 2025 at 3:47 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>> On Wed, Nov 12, 2025 at 6:38 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>>>
>>> On Tue, Nov 11, 2025 at 6:46 PM Andreas Schwab <schwab@suse.de> wrote:
>>>>
>>>> On Okt 31 2025, H.J. Lu wrote:
>>>>
>>>>> 1. Referenced symbol without '@' has no version.
>>>>> 2. Defined symbol without the .symver directive has no version if there
>>>>> is no linker version script.
>>>>>
>>>>> Symbol without version shouldn't have the base version in its DT_VERSYM
>>>>> entry. Instead, its DT_VERSYM entry should be all zero to indicate that
>>>>> the symbol doesn't have a version.
>>>>
>>>> This breaks the testsuite of mold:
>>>>
>>>
>>> Why should ld change impact mold tests?
>>>
>>>> 38/428 Test #38: x86_64-arch-x86_64-reloc ..............................***Failed 0.09 sec
>>>> ++ dirname /home/abuild/rpmbuild/BUILD/mold-2.40.4.60.gad08999-build/mold-2.40.4.60.gad08999/test/arch-x86_64-reloc.sh
>>>> + . /home/abuild/rpmbuild/BUILD/mold-2.40.4.60.gad08999-build/mold-2.40.4.60.gad08999/test/common.inc
>>>> ++ export LC_ALL=C
>>>> ++ LC_ALL=C
>>>> ++ '[' -z x86_64 ']'
>>>> ++ '[' -z '' ']'
>>>> ++ TESTDIR=out/test/x86_64
>>>> ++ CC=cc
>>>> ++ CXX=c++
>>>> ++ GCC=gcc
>>>> ++ GXX=g++
>>>> ++ OBJDUMP=objdump
>>>> ++ OBJCOPY=objcopy
>>>> ++ STRIP=strip
>>>> ++ QEMU=
>>>> +++ basename /home/abuild/rpmbuild/BUILD/mold-2.40.4.60.gad08999-build/mold-2.40.4.60.gad08999/test/arch-x86_64-reloc.sh .sh
>>>> ++ testname=arch-x86_64-reloc
>>>> ++ t=out/test/x86_64/arch-x86_64-reloc
>>>> ++ mkdir -p out/test/x86_64/arch-x86_64-reloc
>>>> ++ case $MACHINE in
>>>> ++ tlsdesc_opt=-mtls-dialect=gnu2
>>>> +++ uname
>>>> ++ '[' Linux = FreeBSD ']'
>>>> ++ trap 'on_error $LINENO' ERR
>>>> ++ trap on_exit EXIT
>>>> ++ echo -n 'Testing arch-x86_64-reloc ... '
>>>> Testing arch-x86_64-reloc ... ++ set -o pipefail
>>>> ++ set -x
>>>> + cat
>>>> + cc -fPIC -c -o out/test/x86_64/arch-x86_64-reloc/a.o -x assembler -
>>>> + cc -fPIC -c -o out/test/x86_64/arch-x86_64-reloc/b.o -xc -
>>>> + cat
>>>> + cc -shared -o out/test/x86_64/arch-x86_64-reloc/c.so out/test/x86_64/arch-x86_64-reloc/a.o out/test/x86_64/arch-x86_64-reloc/b.o -Wl,-z,noexecstack
>>>> + cat
>>>> + cc -B. -o out/test/x86_64/arch-x86_64-reloc/exe out/test/x86_64/arch-x86_64-reloc/c.so out/test/x86_64/arch-x86_64-reloc/d.s -no-pie
>>>> mold: error: undefined symbol: print
>>>>>>> referenced by /tmp/ccfsY4zd.o:(.text)
>>>>>>> /tmp/ccfsY4zd.o
>>>> collect2: error: ld returned 1 exit status
>>>> ++ on_error 43
>>>> ++ code=1
>>>> ++ echo 'command failed: 43: $CC -B. -o $t/exe $t/c.so $t/d.s -no-pie'
>>>> command failed: 43: $CC -B. -o $t/exe $t/c.so $t/d.s -no-pie
>>>> ++ trap - EXIT
>>>> ++ exit 1
>>>>
>>>> Is this a bug in mold?
>>>
>>> Does
>>>
>>> $ cc -o out/test/x86_64/arch-x86_64-reloc/exe
>>> out/test/x86_64/arch-x86_64-reloc/c.so
>>> out/test/x86_64/arch-x86_64-reloc/d.s -no-pie
>>>
>>> fail with ld? "print" isn't a function in libc.
>>>
>>> 1. Where is it defined?
>>> 2. What does
>>> "readelf -DsW" with
>>>
>>> commit 2be0f2da2100cc2b5047f5d055cd039ac494d563
>>> Author: H.J. Lu <hjl.tools@gmail.com>
>>> Date: Thu Nov 6 08:20:26 2025 +0800
>>>
>>> readelf: Display the base symbol version as empty string
>>>
>>> report on the object where "print" is defined.
>>> 3. Which linker is used to generate it?
>>>
>>
>> I opened:
>>
>> https://github.com/rui314/mold/issues/1534
>>
>> --
>> H.J.
>
> ISTM new code will be needed across all Linux linkers to support this change.
>
> I think the old linker behavior, which kept undefined unversioned
> symbols at version 1, was more sensible.
>
> This is because version 0 (VER_NDX_LOCAL) used to be exclusively for
> defined symbols, but now it can be applied to undefined ones.
> This change breaks the simple rule that an absent symbol versioning
> section (like .gnu.version) meant everything was version 1.
Was / is this spelled out like this in the spec? To me, no info means
no version. I.e. also ...
> Now, a symbol's default version depends on whether it's defined.
... not exactly this.
Jan
> The fact that version index 1 in the .gnu.version_d section specifies
> the library name (SONAME) shouldn't be a reason to default undefined
> symbols to version 0.
>
> Is it worth changing the reasonable behavior for 26+ years?
> Could the objdump output be updated to stop printing "BASE" for
> undefined symbols?
>
> The comment is also posted at
> https://sourceware.org/bugzilla/show_bug.cgi?id=33577#c16
More information about the Binutils
mailing list