elf: Properly place base symbols in DT_GNU_HASH and DT_HASH
The base symbol, a symbol with the empty version string, created by
asm (".symver foo_base, foo@");
is used to provide a compatibility symbol in a versioned shared library
for binaries linked against the previous unversioned shared library.
The dynamic linker will pick the first match to resolve the unversioned
symbol reference. If the newest version, VERS_1,
asm (".symver foo_v1, foo@@VERS_1");
is picked before the base symbol in DT_GNU_HASH and DT_HASH, foo@@VERS_1,
instead of foo@, will be used to resolve the unversioned reference.
Properly place base symbols in DT_GNU_HASH and DT_HASH so that they will
be picked first.
Also check defined function symbol, foo, and undefined function symbol,
bar, separately to support different dynamic symbol orders.
bfd/
PR ld/33577
PR ld/33673
* elf-bfd.h (elf_link_hash_entry): Add base_symbol.
(elf_link_hash_table): Add has_base_symbols.
* elflink.c (_bfd_elf_merge_symbol): Set base_symbol and
has_base_symbols if the version string is empty.
(collect_gnu_hash_codes): Add base_symbol.
(elf_gnu_hash_process_symidx): Skip if base symbol doesn't match.
(bfd_elf_size_dynsym_hash_dynstr): If there are base symbols,
output base symbols first in DT_GNU_HASH.
(elf_outext_info): Add base_symbol.
(elf_link_output_extsym): Skip if base symbol doesn't match.
(_bfd_elf_final_link): If there are base symbols, output base
symbols last in DT_HASH.
ld/
PR ld/33577
PR ld/33673
* testsuite/ld-elfvers/pr33577-unversioned.rd: Removed.
* testsuite/ld-elfvers/pr33577-versioned.rd: Likewise.
* testsuite/ld-elfvers/pr33577-unversioned-a.rd: New file.
* testsuite/ld-elfvers/pr33577-unversioned-b.rd: Likewise.
* testsuite/ld-elfvers/pr33577-versioned-a.rd: Likewise.
* testsuite/ld-elfvers/pr33577-versioned-b.rd: Likewise.
* ld-elfvers/vers.exp (base_symbol_test): New.
Run PR ld/33673 tests.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
7 files changed