[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