The NASM docs on "elf Extensions to the GLOBAL Directive" say,

Optionally, you can control the ELF visibility of the symbol. Just add one of the visibility keywords: default, internal, hidden, or protected. The default is default of course.

Where are these defined? and how does ld use them? I see access levels mentioned frequently in C++ which include protected, public, and private, but I don't know if this is what ELF is referencing?

My use-case is C and Assembly so if you can make this relevant to those two languages and the linker, extra points.

1 Answer 1


It seems from the NASM source these seem to correspond with the docs from Oracle "Linker and Libraries Guide", these seem to correspond to STV_DEFAULT, STV_INTERNAL, STV_HIDDEN, and STV_PROTECTED.

Oracle says this:

  • STV_DEFAULT The visibility of symbols with the STV_DEFAULT attribute is as specified by the symbol's binding type. That is, global and weak symbols are visible outside of their defining component, the executable file or shared object. Local symbols are hidden. Global and weak symbols can also be preempted, that is, they may by interposed by definitions of the same name in another component.

  • STV_PROTECTED 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.

  • 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. This attribute is used to control the external interface of a component. An object named by such a symbol may still be referenced from another component if its address is passed outside.

    A hidden symbol contained in a relocatable object is either removed or converted to STB_LOCAL binding by the link-editor when the relocatable object is included in an executable file or shared object.

  • STV_INTERNAL This visibility attribute is currently reserved.

As for the effect on C and Assembly, the Oracle docs go on to say

None of the visibility attributes affects the resolution of symbols within an executable or shared object during link-editing. Such resolution is controlled by the binding type. Once the link-editor has chosen its resolution, these attributes impose two requirements. Both requirements are based on the fact that references in the code being linked may have been optimized to take advantage of the attributes.

  • First, all of the non-default visibility attributes, when applied to a symbol reference, imply that a definition to satisfy that reference must be provided within the current executable or shared object. If this type of symbol reference has no definition within the component being linked, then the reference must have STB_WEAK binding and is resolved to zero.

  • Second, if any reference to or definition of a name is a symbol with a non-default visibility attribute, the visibility attribute must be propagated to the resolving symbol in the linked object. If different visibility attributes are specified for distinct references to or definitions of a symbol, the most constraining visibility attribute must be propagated to the resolving symbol in the linked object. The attributes, ordered from least to most constraining, are STV_PROTECTED, STV_HIDDEN and STV_INTERNAL.

See also

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .