aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf32-i386.c1
-rw-r--r--bfd/elf64-x86-64.c4
-rw-r--r--bfd/elfxx-x86.c21
-rw-r--r--bfd/elfxx-x86.h3
5 files changed, 35 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index fbcb11a..5651316 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2017-10-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * 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 <amodra@gmail.com>
* elflink.c (_bfd_elf_adjust_dynamic_symbol): Call
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index bcb219e..cf2e43f 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 7d65dca..b970146 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 4384430..dd139ca 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 a2f5fc2..542439c 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 *);