[PATCH v3] elf: Don't set its DT_VERSYM entry for unversioned symbol

H.J. Lu hjl.tools@gmail.com
Wed Nov 12 22:45:42 GMT 2025


On Wed, Nov 12, 2025 at 9:01 PM Michael Matz <matz@suse.de> wrote:
>
> Hello,
>
> On Wed, 12 Nov 2025, Andreas Schwab wrote:
>
> > > Two values are reserved:
> > >
> > >   VER_NDX_LOCAL  0 - The symbol is private, and is not available
> > > outside this object.
> >
> > Doesn't this mean that the mold behaviour is correct?
>
> I agree.  That numeric value '1' (instead of '0') is the default value (as
> the version to use when nothing particularly interesting is specified) is
> a wart, but one that we now need to follow.  If version info must be
> encoded then a global undefined symbol without a version requirement has
> to continue using value 1.
>
> > $ binutils/readelf -WDsV c.so
> >
> > Symbol table for image contains 9 entries:
> >    Num:    Value          Size Type    Bind   Vis      Ndx Name
> >      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
> >      1: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTable
> >      2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
> >      3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
> >      4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
> >      5: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@GLIBC_2.2.5 (2)
> >      6: 0000000000004010    56 OBJECT  GLOBAL DEFAULT   21 ext_var
> >      7: 000000000000112a    43 FUNC    GLOBAL DEFAULT   12 print
> >      8: 0000000000001155    46 FUNC    GLOBAL DEFAULT   12 print64
> >
> > Version symbols section '.gnu.version' contains 9 entries:
> >  Addr: 0x0000000000000390  Offset: 0x00000390  Link: 3 (.dynsym)
> >   000:   0 (*local*)       0 (*local*)       2 (GLIBC_2.2.5)   0 (*local*)
> >   004:   0 (*local*)       2 (GLIBC_2.2.5)   0 (*local*)       0 (*local*)
> >   008:   0 (*local*)
>
> I also don't see justification for the WEAK undefined symbols to be
> 'local' here.  IMO they all should be value 1.  If that means that we
> can't differentiate between a symbol definition of 'foo' vs 'foo@'
> (with empty version), then that's what we need to pay.  Alternatively an
> explicitely empty version with a different value than 1 could be
> introduced to record the difference, but that seems unhelpfully quirky.
>
>

VER_NDX_LOCAL (0) doesn't mean local visibility.  (*local*)  indicates index 0

https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-symbol-section.html

has

A symbol may be assigned the special reserved index 0. This index can
be assigned for any of the following reasons.

A non-global symbol is always assigned VER_NDX_LOCAL. However, this is
rare in practice. Versioning sections are usually created only in
conjunction with the dynamic symbol table, .dynsym, which only
contains global symbols.

A global symbol defined within an object that does not have a
SHT_SUNW_verdef version definition section.

An undefined global symbol defined within an object that does not have
a SHT_SUNW_verneed version dependency section. Or, an undefined global
symbol defined within an object in which the version dependency
section does not assign version indexes.

The first entry of a symbol table is always NULL. This entry always
receives VER_NDX_LOCAL, however the value has no particular meaning.

-- 
H.J.


More information about the Binutils mailing list