From 4deb8f714d555a2f530e37c3e7af32bc42fdda58 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 28 Nov 2016 08:03:46 -0800 Subject: [PATCH] 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. --- bfd/ChangeLog | 7 ++++ bfd/elflink.c | 55 ++++++++++++++++---------------- ld/ChangeLog | 5 +++ ld/testsuite/ld-elf/indirect.exp | 3 ++ ld/testsuite/ld-elf/pr18720.rd | 4 +++ 5 files changed, 46 insertions(+), 28 deletions(-) create mode 100644 ld/testsuite/ld-elf/pr18720.rd diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0d797647768..99b0f8bc48b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2016-11-28 H.J. Lu + + * 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. + 2016-11-25 Jon Turney PR ld/20193 diff --git a/bfd/elflink.c b/bfd/elflink.c index ddbe80100d7..5f87f875537 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -2654,18 +2654,35 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, && (h->root.u.def.section->owner->flags & (DYNAMIC | BFD_PLUGIN)) == 0) h->def_regular = 1; + /* If a weak undefined symbol has non-default visibility, we also + hide it from the dynamic linker. */ + if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT + && h->root.type == bfd_link_hash_undefweak) + (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); + + /* A hidden versioned symbol in executable should be forced local if + it is is locally defined, not referenced by shared library and not + exported. */ + else if (bfd_link_executable (eif->info) + && h->versioned == versioned_hidden + && !eif->info->export_dynamic + && !h->dynamic + && !h->ref_dynamic + && h->def_regular) + (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); + /* If -Bsymbolic was used (which means to bind references to global symbols to the definition within the shared object), and this symbol was defined in a regular object, then it actually doesn't need a PLT entry. Likewise, if the symbol has non-default visibility. If the symbol has hidden or internal visibility, we will force it local. */ - if (h->needs_plt - && bfd_link_pic (eif->info) - && is_elf_hash_table (eif->info->hash) - && (SYMBOLIC_BIND (eif->info, h) - || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - && h->def_regular) + else if (h->needs_plt + && bfd_link_pic (eif->info) + && is_elf_hash_table (eif->info->hash) + && (SYMBOLIC_BIND (eif->info, h) + || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + && h->def_regular) { bfd_boolean force_local; @@ -2674,12 +2691,6 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, (*bed->elf_backend_hide_symbol) (eif->info, h, force_local); } - /* If a weak undefined symbol has non-default visibility, we also - hide it from the dynamic linker. */ - if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - && h->root.type == bfd_link_hash_undefweak) - (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); - /* If this is a weak defined symbol in a dynamic object, and we know the real definition in the dynamic object, copy interesting flags over to the real definition. */ @@ -9249,16 +9260,6 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) long indx; int ret; unsigned int type; - /* A symbol is bound locally if it is forced local or it is locally - defined, hidden versioned, not referenced by shared library and - not exported when linking executable. */ - bfd_boolean local_bind = (h->forced_local - || (bfd_link_executable (flinfo->info) - && !flinfo->info->export_dynamic - && !h->dynamic - && !h->ref_dynamic - && h->def_regular - && h->versioned == versioned_hidden)); if (h->root.type == bfd_link_hash_warning) { @@ -9270,12 +9271,12 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) /* Decide whether to output this symbol in this pass. */ if (eoinfo->localsyms) { - if (!local_bind) + if (!h->forced_local) return TRUE; } else { - if (local_bind) + if (h->forced_local) return TRUE; } @@ -9492,7 +9493,7 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) abort (); } - if (local_bind) + if (h->forced_local) { sym.st_info = ELF_ST_INFO (STB_LOCAL, type); /* Turn off visibility on local symbol. */ @@ -9603,10 +9604,8 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) /* Since there is no version information in the dynamic string, if there is no version info in symbol version section, we will have a run-time problem if not linking executable, referenced - by shared library, not locally defined, or not bound locally. - */ + by shared library, or not bound locally. */ if (h->verinfo.verdef == NULL - && !local_bind && (!bfd_link_executable (flinfo->info) || h->ref_dynamic || !h->def_regular)) diff --git a/ld/ChangeLog b/ld/ChangeLog index d612849656b..8040aa01912 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2016-11-28 H.J. Lu + + * testsuite/ld-elf/indirect.exp: Add a test for PR 18720. + * testsuite/ld-elf/pr18720.rd: New file. + 2016-11-27 Alan Modra PR 20815 diff --git a/ld/testsuite/ld-elf/indirect.exp b/ld/testsuite/ld-elf/indirect.exp index b4766fd8f87..317621042b7 100644 --- a/ld/testsuite/ld-elf/indirect.exp +++ b/ld/testsuite/ld-elf/indirect.exp @@ -91,6 +91,9 @@ set build_tests { {"Build pr18720b1.o" "-r -nostdlib tmpdir/pr18720b.o" "" {dummy.c} {} "pr18720b1.o"} + {"Build pr18720a" + "tmpdir/pr18720a.o tmpdir/pr18720b.o tmpdir/libpr18720c.so" "" + {check-ptr-eq.c} {{readelf {--dyn-syms} pr18720.rd}} "pr18720a"} {"Build libpr19553b.so" "-shared -Wl,--version-script=pr19553.map" "-fPIC" {pr19553b.c} {} "libpr19553b.so"} diff --git a/ld/testsuite/ld-elf/pr18720.rd b/ld/testsuite/ld-elf/pr18720.rd new file mode 100644 index 00000000000..b5e848fda72 --- /dev/null +++ b/ld/testsuite/ld-elf/pr18720.rd @@ -0,0 +1,4 @@ +#failif +#... +.* found at index >= .dynsym's sh_info value .* +#... -- 2.30.2