Bug 26002 - ld: Should an unversioned undefined symbol use VER_NDX_GLOBAL instead of VER_NDX_LOCAL?
Summary: ld: Should an unversioned undefined symbol use VER_NDX_GLOBAL instead of VER_...
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.35
: P2 normal
Target Milestone: 2.37
Assignee: Alan Modra
Depends on:
Reported: 2020-05-17 00:21 UTC by Fangrui Song
Modified: 2021-01-16 01:41 UTC (History)
0 users

See Also:
Last reconfirmed: 2020-06-07 00:00:00


Note You need to log in before you can comment on or make changes to this bug.
Description Fangrui Song 2020-05-17 00:21:01 UTC
echo 'v1 { f; };' > a.ver
echo '.globl f_v1; .symver f_v1,f@v1; f_v1: g:' | as - -o a.o
ld.bfd -shared --version-script a.ver a.o -o a.so

echo '.symver f,f@v1; call f; call g' | as - -o a1.o
ld.bfd -shared a1.o a.so -o a1.so

% readelf -V a1.so

Version symbols section '.gnu.version' contains 2 entries:
 Addr: 0x0000000000000204  Offset: 0x000204  Link: 3 (.dynsym)
  000:   0 (*local*)       2 (v1)

Version needs section '.gnu.version_r' contains 1 entry:
 Addr: 0x0000000000000208  Offset: 0x000208  Link: 4 (.dynstr)
  000000: Version: 1  File: a.so  Cnt: 1
  0x0010:   Name: v1  Flags: none  Version: 2

Should `g` be VER_NDX_GLOBAL instead of VER_NDX_LOCAL?

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=64707334c75cdf16a0c2d317fc381c9b158beed9 may be related

-      if (v == static_cast<unsigned int>(elfcpp::VER_NDX_LOCAL))
+      // The Sun documentation says that V can be VER_NDX_LOCAL, or
+      // VER_NDX_GLOBAL, or a version index.  The meaning of
+      // VER_NDX_LOCAL is defined as "Symbol has local scope."  The
+      // old GNU linker will happily generate VER_NDX_LOCAL for an
+      // undefined symbol.  I don't know what the Sun linker will
+      // generate.
+      if (v == static_cast<unsigned int>(elfcpp::VER_NDX_LOCAL)
+          && sym.get_st_shndx() != elfcpp::SHN_UNDEF)

# The build system has some robustness problems. 
# I tried git checkout binutils-2_28; make; git checkout binutils-2_29; make; ... to iterate over recent releases. When I checkout binutils-2_33, `make` will complain. (Deleting the build directory and regenerating it will work.) It seems that some build artifacts from previous versions are not correctly cleaned.
Comment 1 Alan Modra 2020-06-07 04:14:56 UTC
> Should `g` be VER_NDX_GLOBAL instead of VER_NDX_LOCAL?

Yes, it probably should be.  Note that there are cases where VER_NDX_LOCAL is expected, but this doesn't seem to be one of those cases.  See https://docs.oracle.com/cd/E26505_01/html/E26506/chapter6-54676.html
Comment 2 cvs-commit@gcc.gnu.org 2021-01-16 00:42:32 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:


commit eb6e6af8c17a8f4e120d79cb5f2451ebe60aaf4e
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Jan 15 21:17:43 2021 +1030

    PR26002 undefined symbol VER_NDX_GLOBAL vs. VER_NDX_LOCAL
    This patch makes undefined unversioned dynamic symbols use
    VER_NDX_GLOBAL (version 1) rather than VER_NDX_LOCAL (version 0).
    There really isn't much use for an undefined local dynamic symbol, so
    we may as well use the logically correct value in .gnu.version.
            PR 26002
            * elflink.c (elf_link_output_extsym): Use version 1 in
            .gnu.version for undefined unversioned symbols.
            PR 26002
            * testsuite/ld-elfvers/vers6.dsym: Expect "Base" for undefined
            unversioned symbols.
            * testsuite/ld-elfvers/vers16.dsym: Likewise.
Comment 3 Alan Modra 2021-01-16 01:41:41 UTC