From 9f8575350f980aa6da8c488c6aa30862620eaa1f Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 12 Oct 2017 02:12:47 -0700 Subject: [PATCH] x86: Add _bfd_x86_elf_hide_symbol When there is no dynamic interpreter in PIE, make the undefined weak symbol dynamic so that PC relative branch to the undefined weak symbol will land to address 0. * elf32-i386.c (elf_backend_hide_symbol): New. * elf64-x86-64.c (elf_backend_hide_symbol): Likewise. * elfxx-x86.c (_bfd_x86_elf_hide_symbol): Likewise. * elfxx-x86.h (_bfd_x86_elf_hide_symbol): Likewise. --- bfd/ChangeLog | 7 +++++++ bfd/elf32-i386.c | 1 + bfd/elf64-x86-64.c | 4 +++- bfd/elfxx-x86.c | 21 +++++++++++++++++++++ bfd/elfxx-x86.h | 3 +++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index fbcb11af9f2..5651316d681 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2017-10-12 H.J. Lu + + * elf32-i386.c (elf_backend_hide_symbol): New. + * elf64-x86-64.c (elf_backend_hide_symbol): Likewise. + * elfxx-x86.c (_bfd_x86_elf_hide_symbol): Likewise. + * elfxx-x86.h (_bfd_x86_elf_hide_symbol): Likewise. + 2017-10-12 Alan Modra * elflink.c (_bfd_elf_adjust_dynamic_symbol): Call diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index bcb219ebe4d..cf2e43fc5e1 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -4586,6 +4586,7 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) #define elf_backend_reloc_type_class elf_i386_reloc_type_class #define elf_backend_relocate_section elf_i386_relocate_section #define elf_backend_setup_gnu_properties elf_i386_link_setup_gnu_properties +#define elf_backend_hide_symbol _bfd_x86_elf_hide_symbol #define elf_backend_linux_prpsinfo32_ugid16 TRUE diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 7d65dca298d..b970146cfb3 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -5187,7 +5187,9 @@ elf_x86_64_special_sections[]= #define elf_backend_additional_program_headers \ elf_x86_64_additional_program_headers #define elf_backend_setup_gnu_properties \ - elf_x86_64_link_setup_gnu_properties + elf_x86_64_link_setup_gnu_properties +#define elf_backend_hide_symbol \ + _bfd_x86_elf_hide_symbol #include "elf64-target.h" diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 4384430c864..dd139caf418 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -1668,6 +1668,27 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info, return _bfd_elf_adjust_dynamic_copy (info, h, s); } +void +_bfd_x86_elf_hide_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h, + bfd_boolean force_local) +{ + if (h->root.type == bfd_link_hash_undefweak + && info->nointerp + && bfd_link_pie (info)) + { + /* When there is no dynamic interpreter in PIE, make the undefined + weak symbol dynamic so that PC relative branch to the undefined + weak symbol will land to address 0. */ + struct elf_x86_link_hash_entry *eh = elf_x86_hash_entry (h); + if (h->plt.refcount > eh->func_pointer_refcount + || eh->plt_got.refcount > 0) + return; + } + + _bfd_elf_link_hash_hide_symbol (info, h, force_local); +} + /* Return TRUE if a symbol is referenced locally. It is similar to SYMBOL_REFERENCES_LOCAL, but it also checks version script. It works in check_relocs. */ diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index a2f5fc235a9..542439c5680 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -621,6 +621,9 @@ extern bfd_boolean _bfd_x86_elf_hash_symbol extern bfd_boolean _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *, struct elf_link_hash_entry *); +extern void _bfd_x86_elf_hide_symbol + (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean); + extern bfd_boolean _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *, struct elf_link_hash_entry *); -- 2.30.2