[PATCH 45/59] Check if linker sets --no-undefined-version by default
Sam James
sam@gentoo.org
Wed Oct 22 18:51:48 GMT 2025
> On 22 Oct 2025, at 19:22, Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> wrote:
>
>
>
>> On 22/10/25 15:09, Sam James wrote:
>> Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> writes:
>>
>>> On 18/10/25 03:56, Sam James wrote:
>>>> Adhemerval Zanella <adhemerval.zanella@linaro.org> writes:
>>>>
>>>>> Recent lld version default to --no-undefined-version, which triggers
>>>>> errors when building multiple libraries. For ld.so it fails with:
>>>>>
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.4' to symbol '__stack_chk_guard' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_PRIVATE' to symbol '__nptl_set_robust_list_avail' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_PRIVATE' to symbol '__pointer_chk_guard' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_PRIVATE' to symbol '_dl_starting_up' failed: symbol not defined
>>>>>
>>>>> While for libc.so:
>>>>>
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_clearerr' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_fgetc' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_fileno' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_freopen' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_fscanf' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_fseek' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_peekc_unlocked' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_stderr_' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_stdin_' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_stdout_' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_pclose' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_perror' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_rewind' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_scanf' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_setbuf' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_setlinebuf' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_wdefault_setbuf' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '_IO_wfile_setbuf' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '__ctype32_tolower' failed: symbol not defined
>>>>> ld.lld: error: version script assignment of 'GLIBC_2.17' to symbol '__ctype32_toupper' failed: symbol not defined
>>>>> ld.lld: error: too many errors emitted, stopping now (use --error-limit=0 to see all errors)
>>>>>
>>>>> The way version script is created with multiple missing symbols is
>>>>> to simplify the build for multiple ABIs with different symbol
>>>>> symbols. For instance, __stack_chk_guard is defined by default to
>>>>> avoid the need of each ABI to add this symbol on its own version
>>>>> script depending of which stack protector ABI it uses.
>>>>
>>>> Yes. The warning is helpful as a linter but there's a lot of cases like
>>>> this where it ends up being more harm than help.
>>>>
>>>>>
>>>>> The libc.so warnings does show unused symbol being defined (like
>>>>> _IO_clearerr), which might trigger potential errors depending of
>>>>> how symbol are exported. However, since we do have teh ABI checks
>>>>
>>>> s/teh/the/
>>>
>>> Ack.
>>>
>>>>
>>>>> for missing and extra symbol the linker extra checks are not really
>>>>> required. So disable them for now.
>>>>
>>>> Can we just check for -Wl,--no-undefined-version please? I don't expect
>>>> us to ever change the default in bfd.
>>>>
>>>> (Or was there a particular reason to check for the default I'm missing?)
>>>
>>> The does exactly that at configure. With gcc we will get:
>>>
>>> $ grep undefined-version config.make
>>> undefined-version =
>>>
>>> While with lld:
>>>
>>> $ grep undefined-version config.make
>>> undefined-version = -Wl,--undefined-version
>>
>> What I'm saying is: check if the linker supports -Wl,--undefined-version
>> (as we do with other linker args, like the execstack warning/error),
>> don't bother checking if it errors out by default (i.e. don't pass any
>> linker script) to simplify?
> With this approach I think we can just assume -Wl,--undefined-version
> support, binutils has added a long time ago (319416359200 back in 2002)
> and lld since 2018 (aad2e328b960d).
>
> I don't have a strong opinion, if binutils does something similar we
> will probably need some fix like this.
Let's go unconditionally. I won't be stubborn if you prefer the original though.
More information about the Libc-alpha
mailing list