[PATCH 2/3] gas/ELF: warn upon non-default visibility of local symbols

Jan Beulich jbeulich@suse.com
Tue Jun 23 13:26:44 GMT 2026


On 23.06.2026 15:14, Michael Matz wrote:
> On Tue, 23 Jun 2026, Jan Beulich wrote:
> 
>> ... this actual reference, arguably the compiler should also emit a .global
>> directive. It generally gets away without doing so because referenced symbols
>> which aren't otherwise defined are implicitly global (which, seeing how
>> other assemblers behave, can be argued as being a bug, but apparently is
>> "traditional behavior" on UNIXes).
> 
> An assembler isn't a structured programming language environment, I think 
> the quotes are undeserved: its entirely sensible that an assembler that 
> sees a symbol reference for a symbol that at file-end is still undefined 
> assumes that such symbol then obviously must come from a different file 
> and hence be global (binding).

Well, I grew up (in the DOS / Windows / OS/2 world) with assemblers behaving
differently.

>>> ELF spec
>>> doesn't forbid the hidden visibility on a local symbol.  It is just a no-op.
>>
>> You did read
>>
>> "The spec explicitly precludes STB_LOCAL together with STV_PROTECTED (and,
>>  implicity, STV_HIDDEN or STV_INTERNAL), so we better wouldn't entirely
>>  silently write out symbols violating this."
>>
>> in the patch description, didn't you? If you think that's wrong, did you
>> then not consider going back to the ELF spec to find what exactly is said
>> there: "A symbol with STB_LOCAL binding may not have STV_PROTECTED
>> visibility." And then for STV_HIDDEN: "Such a symbol is necessarily
>> protected." I.e. what is said for STV_PROTECTED applies to STV_HIDDEN (and
>> STV_INTERNAL) as well, at least according to my interpretation of that
>> wording.
> 
> I think that's a misinterpretation.  "a symbol is protected" is different 
> from "a symbol has STV_PROTECTED visibility".  The former is defined in 
> the section for the latter: 
> 
>   A symbol defined in the current component is protected if it is visible 
>   in other components but cannot be preempted. Any reference to such a 
>   symbol from within the defining component must be resolved to the 
>   definition in that component, even if there is a definition in another 
>   component that would interpose by the default rules. A symbol with 
>   STB_LOCAL binding will not have STV_PROTECTED visibility.
> 
> and _that definition_ is invoked by STV_HIDDEN:
> 
>   A symbol defined in the current component is hidden if its name is not 
>   visible to other components. Such a symbol is necessarily protected.
> 
> IMHO it's clear that a symbol hence "can be protected" without having its 
> visibility be STV_PROTECTED.  Namely when it is STV_HIDDEN: its then 
> protected _and_ hidden (which is of course redundant, because hidden 
> implies protected, but as we are word-smithing, lets be precise).
> 
> That a STB_LOCAL symbol cannot have STV_PROTECTED visibility doesn't 
> transfer to STV_HIDDEN from this wording, and from nothing else either, 
> conceptually binding and visibility are orthogonal concepts and this 
> specific disallowance for the STB_LOCAL+STV_PROTECTED combination is ... 
> well, specific.  That is the wart, not that STB_LOCAL+STV_HIDDEN was 
> "forgotten" to be disallowed.

IOW what you're suggesting as interpretation is that while STV_PROTECTED
and STB_LOCAL may not combine, the visibility-wise more restricting
STV_HIDDEN may combine with STB_LOCAL? Make no sense to me, I'm afraid.
(And would also make the implementation harder.)

Jan


More information about the Binutils mailing list