This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Set dynamic_undefined_weak to zero for static PIEs


On 10/12/17, H.J. Lu <hjl.tools@gmail.com> wrote:
> On 10/11/17, Alan Modra <amodra@gmail.com> wrote:
>> I believe we should be warning if ld is given both --no-dynamic-linker
>> and -z dynamic-undefined-weak.  The two options are contradictory, the
>> first says an executable has no dynamic interpreter to resolve dynamic
>> symbols, while the second is asking for dynamic symbols to be emitted.
>> (And even if a static PIE's relocation code, which is needed to
>> process R_*_RELATIVE relocs, could process symbols, there are no
>> DT_NEEDED dynamic objects to define such symbols.)
>>
>> I also think that dynamic_undefined_weak is the right flag to control
>> whether undefined weaks are made dynamic, whether in static PIEs or
>> anywhere else.  So force it to 0 for static PIEs, fixing PR 22269 for
>> powerpc and any other target where the backend usually defaults to
>> undefined weaks being made dynamic.
>>
>> This patch introduces regressions.  I'd normally not do that, but
>> these are all in very recently added test cases, or expose bugs in the
>> x86 backend.  The test cases were added after I'd made it known that
>> this patch or one like it was imminent.
>>
>
> I checked this patch to update tests to expect warning of
> "-z dynamic-undefined-weak ignored".  I will check in an x86
> linker patch later to fix the maining:
>
> FAIL: ld-i386/pr19636-1d
> FAIL: ld-i386/pr19636-1l
> FAIL: ld-x86-64/pr19636-2d
> FAIL: ld-x86-64/pr19636-2l
>

This is the x86 linker patch I checked in.


-- 
H.J.
From 9f8575350f980aa6da8c488c6aa30862620eaa1f Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
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 fbcb11af9f..5651316d68 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 bcb219ebe4..cf2e43fc5e 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 7d65dca298..b970146cfb 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 4384430c86..dd139caf41 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 a2f5fc235a..542439c568 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.13.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]