This is the mail archive of the binutils-cvs@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]

[binutils-gdb] PR20989, sparc GOT sequence optimisation


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5b86074c4a84e32ca55a6c72c5fca45d97dc9374

commit 5b86074c4a84e32ca55a6c72c5fca45d97dc9374
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Jan 2 22:06:28 2017 +1030

    PR20989, sparc GOT sequence optimisation
    
    	PR ld/20989
    	* elfxx-sparc.c (gdop_relative_offset_ok): New function.
    	(_bfd_sparc_elf_relocate_section): Use it to validate GOT
    	indirect to GOT pointer relative code edit.

Diff:
---
 bfd/ChangeLog     |  7 +++++++
 bfd/elfxx-sparc.c | 31 +++++++++++++++++++++++++++++--
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 6a61d61..c129543 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
 2017-01-02  Alan Modra  <amodra@gmail.com>
 
+	PR ld/20989
+	* elfxx-sparc.c (gdop_relative_offset_ok): New function.
+	(_bfd_sparc_elf_relocate_section): Use it to validate GOT
+	indirect to GOT pointer relative code edit.
+
+2017-01-02  Alan Modra  <amodra@gmail.com>
+
 	Update year range in copyright notice of all files.
 
 For older changes see ChangeLog-2016
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 4ec013d..f66525e 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -2927,6 +2927,33 @@ gdopoff (struct bfd_link_info *info, bfd_vma address)
   return address - got_base;
 }
 
+/* Return whether H is local and its ADDRESS is within 4G of
+   _GLOBAL_OFFSET_TABLE_ and thus the offset may be calculated by a
+   sethi, xor sequence.  */
+
+static bfd_boolean
+gdop_relative_offset_ok (struct bfd_link_info *info,
+			 struct elf_link_hash_entry *h,
+			 bfd_vma address ATTRIBUTE_UNUSED)
+{
+  if (!SYMBOL_REFERENCES_LOCAL (info, h))
+    return FALSE;
+  /* If H is undefined, ADDRESS will be zero.  We can't allow a
+     relative offset to "zero" when producing PIEs or shared libs.
+     Note that to get here with an undefined symbol it must also be
+     hidden or internal visibility.  */
+  if (bfd_link_pic (info)
+      && h != NULL
+      && (h->root.type == bfd_link_hash_undefweak
+	  || h->root.type == bfd_link_hash_undefined))
+    return FALSE;
+#ifdef BFD64
+  return gdopoff (info, address) + ((bfd_vma) 1 << 32) < (bfd_vma) 2 << 32;
+#else
+  return TRUE;
+#endif
+}
+
 /* Relocate a SPARC ELF section.  */
 
 bfd_boolean
@@ -3168,7 +3195,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	{
 	case R_SPARC_GOTDATA_OP_HIX22:
 	case R_SPARC_GOTDATA_OP_LOX10:
-	  if (SYMBOL_REFERENCES_LOCAL (info, h))
+	  if (gdop_relative_offset_ok (info, h, relocation))
 	    {
 	      r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
 			? R_SPARC_GOTDATA_HIX22
@@ -3178,7 +3205,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	  break;
 
 	case R_SPARC_GOTDATA_OP:
-	  if (SYMBOL_REFERENCES_LOCAL (info, h))
+	  if (gdop_relative_offset_ok (info, h, relocation))
 	    {
 	      bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);


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