Summary: | No symbol version section for versioned symbol `foo@FOO' | ||
---|---|---|---|
Product: | binutils | Reporter: | H.J. Lu <hjl.tools> |
Component: | ld | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | ccoutant |
Priority: | P2 | ||
Version: | 2.26 | ||
Target Milestone: | 2.26 | ||
Host: | Target: | ||
Build: | Last reconfirmed: | ||
Bug Depends on: | |||
Bug Blocks: | 19553 |
Description
H.J. Lu
2015-07-25 15:48:16 UTC
With my proposed fix for gas (see PR 18703 comment #12), indirect3b.o would not have the stray unversioned definition for foo, and ld would work just fine as is. https://sourceware.org/bugzilla/show_bug.cgi?id=18703#c12 With your testcase, gold binds to the unversioned foo in indirect3b.o, and the resulting binary prints "MAIN" twice. With the patched assembler, both gold and ld print "DSO" twice. (In reply to Cary Coutant from comment #1) > With my proposed fix for gas (see PR 18703 comment #12), indirect3b.o would > not have the stray unversioned definition for foo, and ld would work just > fine as is. > > https://sourceware.org/bugzilla/show_bug.cgi?id=18703#c12 > > With your testcase, gold binds to the unversioned foo in indirect3b.o, and > the resulting binary prints "MAIN" twice. With the patched assembler, both > gold and ld print "DSO" twice. I tried your gas change: diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 78dc6d9..8668be0 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -2182,6 +2182,11 @@ elf_frob_symbol (symbolS *symp, int *puntp) memmove (&p[2], &p[3], l); S_SET_NAME (symp, sy_obj->versioned_name); } + else if (strncmp (S_GET_NAME (symp), sy_obj->versioned_name, + strlen (S_GET_NAME (symp))) == 0) + { + S_SET_NAME (symp, sy_obj->versioned_name); + } else { symbolS *symp2; on master branch on Linux/x86-64 and got: FAIL: ELF symbol versioning FAIL: Indirect symbol 1a: : local symbol `foo' in tmpdir/indirect1b.o is referenced by DSO FAIL: Indirect symbol 1a: : final link failed: Bad value FAIL: Indirect symbol 1b: : local symbol `foo' in tmpdir/indirect1b.o is referenced by DSO FAIL: Indirect symbol 1b: : final link failed: Bad value FAIL: Run with libindirect3c.so 1 FAIL: Run with libindirect3c.so 2 FAIL: Run with libindirect3c.so 3 FAIL: Run with libindirect3c.so 4 FAIL: vers24a FAIL: vers24b FAIL: ELF symbol versioning FAIL: symver symver1 Do you those failures? The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6e33951edcbed1fd803beabcde2af3b252b92164 commit 6e33951edcbed1fd803beabcde2af3b252b92164 Author: H.J. Lu <hjl.tools@gmail.com> Date: Fri Aug 7 05:04:21 2015 -0700 Properly merge hidden versioned symbol The hidden versioned symbol can only be merged with the versioned symbol with the same symbol version. _bfd_elf_merge_symbol should check the symbol version before merging the new hidden versioned symbol with the existing symbol. _bfd_elf_link_hash_copy_indirect can't copy any references to the hidden versioned symbol. We need to bind a symbol locally when linking executable if it is locally defined, hidden versioned, not referenced by shared library and not exported. bfd/ PR ld/18720 * elflink.c (_bfd_elf_merge_symbol): Add a parameter to indicate if the new symbol matches the existing one. The new hidden versioned symbol matches the existing symbol if they have the same symbol version. Update the existing symbol only if they match. (_bfd_elf_add_default_symbol): Update call to _bfd_elf_merge_symbol. (_bfd_elf_link_assign_sym_version): Don't set the hidden field here. (elf_link_add_object_symbols): Override a definition only if the new symbol matches the existing one. (_bfd_elf_link_hash_copy_indirect): Don't copy any references to the hidden versioned symbol. (elf_link_output_extsym): Bind a symbol locally when linking executable if it is locally defined, hidden versioned, not referenced by shared library and not exported. Turn on VERSYM_HIDDEN only if the hidden vesioned symbol is defined locally. ld/testsuite/ PR ld/18720 * ld-elf/indirect.exp: Run tests for PR ld/18720. * ld-elf/pr18720.out: New file. * ld-elf/pr18720a.c: Likewise. * ld-elf/pr18720b.c: Likewise. * ld-elf/pr18720c.c: Likewise. Fixed. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4deb8f714d555a2f530e37c3e7af32bc42fdda58 commit 4deb8f714d555a2f530e37c3e7af32bc42fdda58 Author: H.J. Lu <hjl.tools@gmail.com> Date: Mon Nov 28 08:03:46 2016 -0800 Properly hide hidden versioned symbol in executable A hidden versioned symbol in executable should be forced local if it is locally defined, not referenced by shared library and not exported. We must do it before _bfd_elf_link_renumber_dynsyms. bfd/ * elflink.c (_bfd_elf_fix_symbol_flags): Hide hidden versioned symbol in executable. (elf_link_output_extsym): Don't change bind from global to local when linking executable. ld/ * testsuite/ld-elf/indirect.exp: Add a test for PR 18720. * testsuite/ld-elf/pr18720.rd: New file. The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e81830c5c61a8665c098189d069cc68b0df113d3 commit e81830c5c61a8665c098189d069cc68b0df113d3 Author: Alan Modra <amodra@gmail.com> Date: Thu Dec 29 22:49:41 2016 +1030 link_hash_copy_indirect and symbol flags A while ago HJ fixed PR ld/18720 with commit 6e33951ed, which, among other things, modified _bfd_elf_link_hash_copy_indirect to not copy ref_dynamic, ref_regular, ref_regular_nonweak, non_got_ref, needs_plt and pointer_equality_needed when setting up an indirect non-versioned symbol pointing to a non-default versioned symbol. I didn't notice at the time, but the pr18720 testcase fails on hppa-linux with "internal error, aborting at binutils-gdb-2.28/bfd/elf32-hppa.c:3933 in elf32_hppa_relocate_section". Now hppa-linux creates entries in the plt even for local functions, if they are referenced using plabel (function pointer) relocations. So needs_plt is set for foo when processing pr18720a.o. When the aliases in pr28720b.o are processed, we get an indirection from foo to foo@FOO, but don't copy needs_plt. Since foo@FOO is the "real" symbol that is used after that point, no plt entry is made for foo and we bomb when relocating the plabel. As shown by the hppa-linux scenario, needs_plt should be copied even for non-default versioned symbols. I believe all of the others ought to be copied too, with the exception of ref_dynamic. Not copying ref_dynamic is right because if a shared lib references "foo" it should not be satisfied by any non-default version "foo@FOO". * elflink.c (_bfd_elf_link_hash_copy_indirect): Only omit copying one flag, ref_dynamic, when versioned_hidden. * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise. * elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Use same logic for copying weakdef flags. Copy plabel flag and merge tls_type. * elf32-i386.c (elf_i386_copy_indirect_symbol): Use same logic for copying weakdef flags. * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Likewise. * elf32-s390.c (elf_s390_copy_indirect_symbol): Likewise. * elf32-sh.c (sh_elf_copy_indirect_symbol): Likewise. * elf64-s390.c (elf_s390_copy_indirect_symbol): Likewise. * elfnn-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise. * elf64-x86-64.c (elf_x86_64_copy_indirect_symbol): Likewise. Simplify. The binutils-2_28-branch branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=de1f27ad53e4bcc3aa47209cdb5f32eb1fc41a76 commit de1f27ad53e4bcc3aa47209cdb5f32eb1fc41a76 Author: Alan Modra <amodra@gmail.com> Date: Thu Dec 29 22:49:41 2016 +1030 link_hash_copy_indirect and symbol flags A while ago HJ fixed PR ld/18720 with commit 6e33951ed, which, among other things, modified _bfd_elf_link_hash_copy_indirect to not copy ref_dynamic, ref_regular, ref_regular_nonweak, non_got_ref, needs_plt and pointer_equality_needed when setting up an indirect non-versioned symbol pointing to a non-default versioned symbol. I didn't notice at the time, but the pr18720 testcase fails on hppa-linux with "internal error, aborting at binutils-gdb-2.28/bfd/elf32-hppa.c:3933 in elf32_hppa_relocate_section". Now hppa-linux creates entries in the plt even for local functions, if they are referenced using plabel (function pointer) relocations. So needs_plt is set for foo when processing pr18720a.o. When the aliases in pr28720b.o are processed, we get an indirection from foo to foo@FOO, but don't copy needs_plt. Since foo@FOO is the "real" symbol that is used after that point, no plt entry is made for foo and we bomb when relocating the plabel. As shown by the hppa-linux scenario, needs_plt should be copied even for non-default versioned symbols. I believe all of the others ought to be copied too, with the exception of ref_dynamic. Not copying ref_dynamic is right because if a shared lib references "foo" it should not be satisfied by any non-default version "foo@FOO". * elflink.c (_bfd_elf_link_hash_copy_indirect): Only omit copying one flag, ref_dynamic, when versioned_hidden. * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise. * elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Use same logic for copying weakdef flags. Copy plabel flag and merge tls_type. * elf32-i386.c (elf_i386_copy_indirect_symbol): Use same logic for copying weakdef flags. * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Likewise. * elf32-s390.c (elf_s390_copy_indirect_symbol): Likewise. * elf32-sh.c (sh_elf_copy_indirect_symbol): Likewise. * elf64-s390.c (elf_s390_copy_indirect_symbol): Likewise. * elfnn-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise. * elf64-x86-64.c (elf_x86_64_copy_indirect_symbol): Likewise. Simplify. |