PR26978, Inconsistency for strong foo@v1 and weak foo@@v1
authorAlan Modra <amodra@gmail.com>
Wed, 2 Dec 2020 02:33:23 +0000 (13:03 +1030)
committerAlan Modra <amodra@gmail.com>
Fri, 4 Dec 2020 00:36:52 +0000 (11:06 +1030)
commit726d7d1ecfd1fc0966983e1d5e59b527b90cf7c5
tree5731f99318bf1845bb2b7db1b6ed1fa1faedfcc9
parent099ee20ac320addfdf4ce5bf0522e15f86d590f3
PR26978, Inconsistency for strong foo@v1 and weak foo@@v1

Prior to this patch
  ld -shared --version-script=pr26979.ver pr26978a.o pr26978b.o
results in
  ld: pr26978b.o: in function `foo_v1':
  (.text+0x0): multiple definition of `foo@v1'
  ld: pr26978b.o:(*IND*+0x0): multiple definition of `foo'
while
  ld -shared --version-script=pr26979.ver pr26978b.o pr26978a.o
results in no error, but some odd dynamic symbols.
  ... 0 NOTYPE  GLOBAL DEFAULT    7 foo@v1
  ... 0 NOTYPE  WEAK   DEFAULT    7 foo@@v1

When linking an undecorated reference to foo against such a shared
library, ld complains about multiple definitions of foo@v1 while gold
creates a dynamic reference to foo@v1.  That results in foo@v1 being
used at runtime.

While we could error in both cases, it is reasonable to say foo@v1 and
foo@@v1 are in fact the same symbol.  (Same name, same version.  The
only real difference is that foo@@v1 satisfies a reference to plain
foo, while foo@v1 does not.)  Just as merging a weak undecorated sym
with a strong sym results in the strong sym prevailing, so should the
strong foo@v1 prevail.  And since there is a definition that satisfies
plain foo, the foo@@v1 variety of dynamic symbol should be emitted at
the foo@v1 value.  That makes the testcase that currently links
continue to produce a shared library, and that shared library can now
be used by both ld and gold with the same runtime behaviour as when
using gold with the odd dynamic symbol library.

bfd/
PR 26978
* elflink.c (_bfd_elf_add_default_symbol): Handle the case where
a new weak sym@@ver should be overridden by an existing sym@ver.
(elf_link_add_object_symbols): Don't _bfd_elf_add_default_symbol
for a new weak sym@ver when sym@@ver already exists.
* linker.c (link_action): Choose MIND for previous indirect,
current def, rather than MDEF.
(_bfd_generic_link_add_one_symbol <MIND>): Handle redefinition of
weak indirect symbol.
ld/
* testsuite/ld-elf/pr26978a.d,
* testsuite/ld-elf/pr26978a.s,
* testsuite/ld-elf/pr26978b.d,
* testsuite/ld-elf/pr26978b.s: New tests.
bfd/ChangeLog
bfd/elflink.c
bfd/linker.c
ld/ChangeLog
ld/testsuite/ld-elf/pr26978a.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr26978a.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr26978b.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr26978b.s [new file with mode: 0644]