[PATCH 2/3] gas/ELF: warn upon non-default visibility of local symbols
Michael Matz
matz@suse.de
Tue Jun 23 13:14:46 GMT 2026
Hello,
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).
> > 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.
Ciao,
Michael.
More information about the Binutils
mailing list