x86: Add _bfd_x86_elf_hide_symbol
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 12 Oct 2017 09:12:47 +0000 (02:12 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 12 Oct 2017 09:14:34 +0000 (02:14 -0700)
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
bfd/elf32-i386.c
bfd/elf64-x86-64.c
bfd/elfxx-x86.c
bfd/elfxx-x86.h

index fbcb11a..5651316 100644 (file)
@@ -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
index bcb219e..cf2e43f 100644 (file)
@@ -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
 
index 7d65dca..b970146 100644 (file)
@@ -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"
 
index 4384430..dd139ca 100644 (file)
@@ -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.  */
index a2f5fc2..542439c 100644 (file)
@@ -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 *);