[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