From 6e33951edcbed1fd803beabcde2af3b252b92164 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 7 Aug 2015 05:04:21 -0700 Subject: 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. --- ld/testsuite/ChangeLog | 9 +++++++++ ld/testsuite/ld-elf/indirect.exp | 25 ++++++++++++++++++++++++- ld/testsuite/ld-elf/pr18720.out | 2 ++ ld/testsuite/ld-elf/pr18720a.c | 27 +++++++++++++++++++++++++++ ld/testsuite/ld-elf/pr18720b.c | 11 +++++++++++ ld/testsuite/ld-elf/pr18720c.c | 15 +++++++++++++++ 6 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-elf/pr18720.out create mode 100644 ld/testsuite/ld-elf/pr18720a.c create mode 100644 ld/testsuite/ld-elf/pr18720b.c create mode 100644 ld/testsuite/ld-elf/pr18720c.c (limited to 'ld/testsuite') diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 727bcad..ea873d9 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-08-07 H.J. Lu + + 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. + 2015-08-04 Andrew Burgess * ld/ld-lib.exp (run_dump_test): When using the map option, no diff --git a/ld/testsuite/ld-elf/indirect.exp b/ld/testsuite/ld-elf/indirect.exp index 468ef2b..e8ac1ae 100644 --- a/ld/testsuite/ld-elf/indirect.exp +++ b/ld/testsuite/ld-elf/indirect.exp @@ -64,7 +64,9 @@ if { ![ld_compile $CC $srcdir/$subdir/indirect1a.c tmpdir/indirect1a.o] || ![ld_compile $CC $srcdir/$subdir/indirect3a.c tmpdir/indirect3a.o] || ![ld_compile $CC $srcdir/$subdir/indirect3b.c tmpdir/indirect3b.o] || ![ld_compile $CC $srcdir/$subdir/indirect4a.c tmpdir/indirect4a.o] - || ![ld_compile $CC $srcdir/$subdir/indirect4b.c tmpdir/indirect4b.o] } { + || ![ld_compile $CC $srcdir/$subdir/indirect4b.c tmpdir/indirect4b.o] + || ![ld_compile "$CC -O2 -fPIC -I../bfd" $srcdir/$subdir/pr18720a.c tmpdir/pr18720a.o] + || ![ld_compile $CC $srcdir/$subdir/pr18720b.c tmpdir/pr18720b.o] } { unresolved "Indirect symbol tests" return } @@ -79,6 +81,12 @@ set build_tests { {"Build libindirect4c.so" "-shared" "-fPIC" {indirect4c.c} {} "libindirect4c.so"} + {"Build libpr18720c.so" + "-shared" "-fPIC" + {pr18720c.c} {} "libpr18720c.so"} + {"Build pr18720b1.o" + "-r -nostdlib tmpdir/pr18720b.o" "" + {dummy.c} {} "pr18720b1.o"} } run_cc_link_tests $build_tests @@ -132,6 +140,21 @@ set run_tests { {"Run with libindirect4c.so 4" "tmpdir/libindirect4c.so tmpdir/indirect4b.o tmpdir/indirect4a.o" "" {dummy.c} "indirect4d" "indirect4.out"} + {"Run with libpr18720c.so 1" + "tmpdir/pr18720a.o tmpdir/pr18720b.o tmpdir/libpr18720c.so" "" + {check-ptr-eq.c} "pr18720a" "pr18720.out"} + {"Run with libpr18720c.so 2" + "tmpdir/pr18720a.o tmpdir/libpr18720c.so tmpdir/pr18720b.o" "" + {check-ptr-eq.c} "pr18720b" "pr18720.out"} + {"Run with libpr18720c.so 3" + "tmpdir/pr18720b.o tmpdir/libpr18720c.so tmpdir/pr18720a.o" "" + {check-ptr-eq.c} "pr18720c" "pr18720.out"} + {"Run with libpr18720c.so 4" + "tmpdir/libpr18720c.so tmpdir/pr18720b.o tmpdir/pr18720a.o" "" + {check-ptr-eq.c} "pr18720d" "pr18720.out"} + {"Run with libpr18720c.so 5" + "tmpdir/libpr18720c.so tmpdir/pr18720b1.o tmpdir/pr18720a.o" "" + {check-ptr-eq.c} "pr18720d" "pr18720.out"} } run_ld_link_exec_tests [] $run_tests diff --git a/ld/testsuite/ld-elf/pr18720.out b/ld/testsuite/ld-elf/pr18720.out new file mode 100644 index 0000000..482e981 --- /dev/null +++ b/ld/testsuite/ld-elf/pr18720.out @@ -0,0 +1,2 @@ +MAIN +DSO diff --git a/ld/testsuite/ld-elf/pr18720a.c b/ld/testsuite/ld-elf/pr18720a.c new file mode 100644 index 0000000..752623b --- /dev/null +++ b/ld/testsuite/ld-elf/pr18720a.c @@ -0,0 +1,27 @@ +#include + +extern void bar (void); +extern void foo (void); +extern void foo_alias (void); +extern void check_ptr_eq (void *, void *); + +#if defined(__GNUC__) && (__GNUC__ * 1000 + __GNUC_MINOR__) >= 4005 +__attribute__ ((noinline, noclone)) +#else +__attribute__ ((noinline)) +#endif +int +foo_p (void) +{ + return (intptr_t) &foo == 0x12345678 ? 1 : 0; +} + +int +main (void) +{ + foo (); + foo_p (); + bar (); + check_ptr_eq (&foo, &foo_alias); + return 0; +} diff --git a/ld/testsuite/ld-elf/pr18720b.c b/ld/testsuite/ld-elf/pr18720b.c new file mode 100644 index 0000000..90d376b --- /dev/null +++ b/ld/testsuite/ld-elf/pr18720b.c @@ -0,0 +1,11 @@ +#include + +void +foo (void) +{ + printf ("MAIN\n"); +} + +asm (".symver foo,foo@FOO"); +asm (".set foo_alias,foo"); +asm (".global foo_alias"); diff --git a/ld/testsuite/ld-elf/pr18720c.c b/ld/testsuite/ld-elf/pr18720c.c new file mode 100644 index 0000000..b52cb95 --- /dev/null +++ b/ld/testsuite/ld-elf/pr18720c.c @@ -0,0 +1,15 @@ +#include + +extern void foo (void); + +void +foo (void) +{ + printf ("DSO\n"); +} + +void +bar (void) +{ + foo (); +} -- cgit v1.1