[binutils] binutils-2.24-aarch64-fix-ie-relax.patch: fix GD to IE relaxation under register pressure

Kyle McMartin kyle at fedoraproject.org
Tue Aug 26 18:55:27 UTC 2014


commit 422f7b79608d866025083cc17e0c18e844178451
Author: Kyle McMartin <kyle at mcmartin.ca>
Date:   Fri Aug 22 11:52:55 2014 -0400

    binutils-2.24-aarch64-fix-ie-relax.patch: fix GD to IE relaxation under register pressure
    
    split some fixes out, so it's easier to see what's backported

 ...tils-2.24-aarch64-fix-gotplt-offset-ifunc.patch |  103 +++++++++++++++++
 binutils-2.24-aarch64-fix-ie-relax.patch           |   40 +++++++
 binutils-2.24-aarch64-fix-static-ifunc.patch       |  118 ++++++++++++++++++++
 binutils-2.24-elfnn-aarch64.patch                  |   72 ------------
 binutils.spec                                      |   16 +++-
 5 files changed, 276 insertions(+), 73 deletions(-)
---
diff --git a/binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch b/binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
new file mode 100644
index 0000000..64a1d9c
--- /dev/null
+++ b/binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
@@ -0,0 +1,103 @@
+commit 67428c4aa56d4183d0f531e0d752040745a94423
+Author: Will Newton <will.newton at linaro.org>
+Date:   Mon Nov 25 11:07:07 2013 +0000
+
+    bfd/elfnn-aarch64.c: Fix miscalculation of GOTPLT offset for ifunc syms.
+    
+    The .got.plt header size was not being correctly taken into account
+    when calculating the offset for relocations against ifunc symbols.
+    
+    bfd/ChangeLog:
+    
+    2013-11-26  Will Newton  <will.newton at linaro.org>
+    
+    	* elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Ensure
+    	PLT_INDEX is calculated using correct header size.
+    
+    ld/testsuite/ChangeLog:
+    
+    2013-11-26  Will Newton  <will.newton at linaro.org>
+    
+    	* ld-aarch64/aarch64-elf.exp: Add ifunc-21 test.
+    	* ld-aarch64/ifunc-21.d: New file.
+    	* ld-aarch64/ifunc-21.s: Likewise.
+
+diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
+index 6bc414e..3cd3a18 100644
+--- a/bfd/elfnn-aarch64.c
++++ b/bfd/elfnn-aarch64.c
+@@ -3589,7 +3589,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
+ 
+ 	      if (globals->root.splt != NULL)
+ 		{
+-		  plt_index = h->plt.offset / globals->plt_entry_size - 1;
++		  plt_index = ((h->plt.offset - globals->plt_header_size) /
++			       globals->plt_entry_size);
+ 		  off = (plt_index + 3) * GOT_ENTRY_SIZE;
+ 		  base_got = globals->root.sgotplt;
+ 		}
+diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+index 5c150dd..a6b3ea2 100644
+--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
++++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+@@ -155,3 +155,4 @@ run_dump_test "ifunc-18b"
+ run_dump_test "ifunc-19a"
+ run_dump_test "ifunc-19b"
+ run_dump_test "ifunc-20"
++run_dump_test "ifunc-21"
+diff --git a/ld/testsuite/ld-aarch64/ifunc-21.d b/ld/testsuite/ld-aarch64/ifunc-21.d
+new file mode 100644
+index 0000000..fa139b2
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-21.d
+@@ -0,0 +1,31 @@
++#source: ifunc-21.s
++#ld: -shared -z nocombreloc
++#objdump: -d -s -j .got.plt -j .text
++#target: aarch64*-*-*
++
++# Ensure the .got.plt slot used is correct
++
++.*:     file format elf64-(little|big)aarch64
++
++Contents of section .text:
++ 02a0 .*
++Contents of section .got.plt:
++ 103a8 0+ 0+ 0+ 0+  .*
++ 103b8 0+ 0+ [0-9a-f]+ 0+  .*
++
++Disassembly of section .text:
++
++0+2a0 <ifunc>:
++ 2a0:	d65f03c0 	ret
++
++0+2a4 <bar>:
++ 2a4:	90000080 	adrp	x0, 10000 <.*>
++ 2a8:	f941e000 	ldr	x0, \[x0,#960\]
++ 2ac:	d65f03c0 	ret
++
++Disassembly of section .got.plt:
++
++.*:
++.*
++.*
++.*
+diff --git a/ld/testsuite/ld-aarch64/ifunc-21.s b/ld/testsuite/ld-aarch64/ifunc-21.s
+new file mode 100644
+index 0000000..a1563dc
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-21.s
+@@ -0,0 +1,13 @@
++	.text
++	.type ifunc, @gnu_indirect_function
++	.hidden ifunc
++ifunc:
++	ret
++	.size	ifunc, .-ifunc
++	.type bar, @function
++	.globl bar
++bar:
++        adrp    x0, :got:ifunc
++        ldr     x0, [x0, #:got_lo12:ifunc]
++	ret
++	.size	bar, .-bar
diff --git a/binutils-2.24-aarch64-fix-ie-relax.patch b/binutils-2.24-aarch64-fix-ie-relax.patch
new file mode 100644
index 0000000..d9157ea
--- /dev/null
+++ b/binutils-2.24-aarch64-fix-ie-relax.patch
@@ -0,0 +1,40 @@
+commit 44f814ce5066f10a3bed29c45d10e0d38f4fa433
+Author: Marcus Shawcroft <marcus.shawcroft at arm.com>
+Date:   Tue Apr 15 17:46:07 2014 +0100
+
+    [AArch64] Fix off by one error in instruction relaxation mask.
+    
+    The AArch64 TLSDESC to IE relaxation code uses a bit mask intended to
+    ensure that destination register in a relaxed ldr instruction is
+    always X0.  The mask has an off by one error resulting in the most
+    significant bit of the destination register being retained in the
+    relaxed instruction.  The issue generally appears when the compiler
+    emits TLS accesses code under high register pressure resulting in a
+    broken code sequence.
+
+diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
+index 42c83fb..8503419 100644
+--- a/bfd/elfnn-aarch64.c
++++ b/bfd/elfnn-aarch64.c
+@@ -3957,7 +3957,7 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
+ 	     ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
+ 	   */
+ 	  insn = bfd_getl32 (contents + rel->r_offset);
+-	  insn &= 0xfffffff0;
++	  insn &= 0xffffffe0;
+ 	  bfd_putl32 (insn, contents + rel->r_offset);
+ 	  return bfd_reloc_continue;
+ 	}
+diff --git a/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.s b/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.s
+index c20690c..38b3721 100644
+--- a/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.s
++++ b/ld/testsuite/ld-aarch64/tls-relax-gdesc-ie.s
+@@ -4,7 +4,7 @@ var:
+ 	.word	2
+ 	.text
+ 	adrp	x0, :tlsdesc:var
+-	ldr	x1, [x0, #:tlsdesc_lo12:var]
++	ldr	x17, [x0, #:tlsdesc_lo12:var]
+ 	add	x0, x0, :tlsdesc_lo12:var
+ 	.tlsdesccall	var
+ 	blr	x1
diff --git a/binutils-2.24-aarch64-fix-static-ifunc.patch b/binutils-2.24-aarch64-fix-static-ifunc.patch
new file mode 100644
index 0000000..296f162
--- /dev/null
+++ b/binutils-2.24-aarch64-fix-static-ifunc.patch
@@ -0,0 +1,118 @@
+commit 14d96265dd8fd934d868c0b8e1991e2fefbe9fc8
+Author: Will Newton <will.newton at linaro.org>
+Date:   Mon Nov 25 14:44:59 2013 +0000
+
+    bfd/elfnn-aarch64.c: Handle static links with ifunc correctly.
+    
+    The code for handling GOT references to ifunc symbols in static links
+    was missing.
+    
+    bfd/ChangeLog:
+    
+    2013-11-26  Will Newton  <will.newton at linaro.org>
+    
+    	* elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol):
+    	Handle STT_GNU_IFUNC symbols correctly in static links.
+    
+    ld/testsuite/ChangeLog:
+    
+    2013-11-26  Will Newton  <will.newton at linaro.org>
+    
+    	* ld-aarch64/aarch64-elf.exp: Add ifunc-22.
+    	* ld-aarch64/ifunc-22.d: New file.
+    	* ld-aarch64/ifunc-22.s: Likewise.
+
+diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
+index 3cd3a18..9053635 100644
+--- a/bfd/elfnn-aarch64.c
++++ b/bfd/elfnn-aarch64.c
+@@ -6824,7 +6824,34 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
+ 		       + htab->root.sgot->output_offset
+ 		       + (h->got.offset & ~(bfd_vma) 1));
+ 
+-      if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
++      if (h->def_regular
++	  && h->type == STT_GNU_IFUNC)
++	{
++	  if (info->shared)
++	    {
++	      /* Generate R_AARCH64_GLOB_DAT.  */
++	      goto do_glob_dat;
++	    }
++	  else
++	    {
++	      asection *plt;
++
++	      if (!h->pointer_equality_needed)
++		abort ();
++
++	      /* For non-shared object, we can't use .got.plt, which
++		 contains the real function address if we need pointer
++		 equality.  We load the GOT entry with the PLT entry.  */
++	      plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
++	      bfd_put_NN (output_bfd, (plt->output_section->vma
++				       + plt->output_offset
++				       + h->plt.offset),
++			  htab->root.sgot->contents
++			  + (h->got.offset & ~(bfd_vma) 1));
++	      return TRUE;
++	    }
++	}
++      else if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
+ 	{
+ 	  if (!h->def_regular)
+ 	    return FALSE;
+@@ -6837,6 +6864,7 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
+ 	}
+       else
+ 	{
++do_glob_dat:
+ 	  BFD_ASSERT ((h->got.offset & 1) == 0);
+ 	  bfd_put_NN (output_bfd, (bfd_vma) 0,
+ 		      htab->root.sgot->contents + h->got.offset);
+diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+index a6b3ea2..692bf34 100644
+--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
++++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
+@@ -156,3 +156,4 @@ run_dump_test "ifunc-19a"
+ run_dump_test "ifunc-19b"
+ run_dump_test "ifunc-20"
+ run_dump_test "ifunc-21"
++run_dump_test "ifunc-22"
+diff --git a/ld/testsuite/ld-aarch64/ifunc-22.d b/ld/testsuite/ld-aarch64/ifunc-22.d
+new file mode 100644
+index 0000000..f28b039
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-22.d
+@@ -0,0 +1,11 @@
++#source: ifunc-22.s
++#objdump: -s -j .got
++#ld: -static
++#target: aarch64*-*-*
++
++# Ensure GOT is populated correctly in static link
++
++.*:     file format elf64-(little|big)aarch64
++
++Contents of section \.got:
++ 4100f0 00000000 00000000 d0004000 00000000  .......... at .....
+diff --git a/ld/testsuite/ld-aarch64/ifunc-22.s b/ld/testsuite/ld-aarch64/ifunc-22.s
+new file mode 100644
+index 0000000..69a87bb
+--- /dev/null
++++ b/ld/testsuite/ld-aarch64/ifunc-22.s
+@@ -0,0 +1,14 @@
++	.text
++	.type ifunc, @gnu_indirect_function
++	.global ifunc
++ifunc:
++	ret
++	.size	ifunc, .-ifunc
++	.type _start, @function
++	.globl _start
++_start:
++        adrp    x0, :got:ifunc
++        ldr     x0, [x0, #:got_lo12:ifunc]
++	.size	_start, .-_start
++	.data
++	.xword	ifunc
diff --git a/binutils-2.24-elfnn-aarch64.patch b/binutils-2.24-elfnn-aarch64.patch
index 2491e0f..469387b 100644
--- a/binutils-2.24-elfnn-aarch64.patch
+++ b/binutils-2.24-elfnn-aarch64.patch
@@ -19,75 +19,3 @@
   
   struct elf_aarch64_local_symbol
   {
-*************** elfNN_aarch64_final_link_relocate (reloc
-*** 3589,3595 ****
-  
-  	      if (globals->root.splt != NULL)
-  		{
-! 		  plt_index = h->plt.offset / globals->plt_entry_size - 1;
-  		  off = (plt_index + 3) * GOT_ENTRY_SIZE;
-  		  base_got = globals->root.sgotplt;
-  		}
---- 3589,3596 ----
-  
-  	      if (globals->root.splt != NULL)
-  		{
-! 		  plt_index = ((h->plt.offset - globals->plt_header_size) /
-! 			       globals->plt_entry_size);
-  		  off = (plt_index + 3) * GOT_ENTRY_SIZE;
-  		  base_got = globals->root.sgotplt;
-  		}
-*************** elfNN_aarch64_finish_dynamic_symbol (bfd
-*** 6823,6829 ****
-  		       + htab->root.sgot->output_offset
-  		       + (h->got.offset & ~(bfd_vma) 1));
-  
-!       if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
-  	{
-  	  if (!h->def_regular)
-  	    return FALSE;
---- 6824,6857 ----
-  		       + htab->root.sgot->output_offset
-  		       + (h->got.offset & ~(bfd_vma) 1));
-  
-!       if (h->def_regular
-! 	  && h->type == STT_GNU_IFUNC)
-! 	{
-! 	  if (info->shared)
-! 	    {
-! 	      /* Generate R_AARCH64_GLOB_DAT.  */
-! 	      goto do_glob_dat;
-! 	    }
-! 	  else
-! 	    {
-! 	      asection *plt;
-! 
-! 	      if (!h->pointer_equality_needed)
-! 		abort ();
-! 
-! 	      /* For non-shared object, we can't use .got.plt, which
-! 		 contains the real function address if we need pointer
-! 		 equality.  We load the GOT entry with the PLT entry.  */
-! 	      plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
-! 	      bfd_put_NN (output_bfd, (plt->output_section->vma
-! 				       + plt->output_offset
-! 				       + h->plt.offset),
-! 			  htab->root.sgot->contents
-! 			  + (h->got.offset & ~(bfd_vma) 1));
-! 	      return TRUE;
-! 	    }
-! 	}
-!       else if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
-  	{
-  	  if (!h->def_regular)
-  	    return FALSE;
-*************** elfNN_aarch64_finish_dynamic_symbol (bfd
-*** 6836,6841 ****
---- 6864,6870 ----
-  	}
-        else
-  	{
-+ do_glob_dat:
-  	  BFD_ASSERT ((h->got.offset & 1) == 0);
-  	  bfd_put_NN (output_bfd, (bfd_vma) 0,
-  		      htab->root.sgot->contents + h->got.offset);
diff --git a/binutils.spec b/binutils.spec
index b56aaf0..8d0305c 100644
--- a/binutils.spec
+++ b/binutils.spec
@@ -19,7 +19,7 @@
 Summary: A GNU collection of binary utilities
 Name: %{?cross}binutils%{?_with_debug:-debug}
 Version: 2.24
-Release: 22%{?dist}
+Release: 23%{?dist}
 License: GPLv3+
 Group: Development/Tools
 URL: http://sources.redhat.com/binutils
@@ -68,6 +68,9 @@ Patch23: binutils-2.24-aarch64-ld-shared-non-PIC-xfail.patch
 Patch24: binutils-2.24-weak-sym-merge.patch
 Patch25: binutils-2.24-indirect-chain.patch
 Patch26: binutils-2.24-aarch64-fix-final_link_relocate.patch
+Patch27: binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
+Patch28: binutils-2.24-aarch64-fix-static-ifunc.patch
+Patch29: binutils-2.24-aarch64-fix-ie-relax.patch
 
 Provides: bundled(libiberty)
 
@@ -198,6 +201,9 @@ using libelf instead of BFD.
 %patch24 -p0 -b .weak-sym-merge~
 %patch25 -p0 -b .indirect-chain~
 %patch26 -p1 -b .aa64-final-link~
+%patch27 -p1 -b .aa64-1~
+%patch28 -p1 -b .aa64-2~
+%patch29 -p1 -b .aa64-3~
 
 # We cannot run autotools as there is an exact requirement of autoconf-2.59.
 
@@ -511,6 +517,14 @@ exit 0
 %endif # %{isnative}
 
 %changelog
+* Fri Aug 22 2014 Kyle McMartin <kmcmarti at redhat.com> - 2.24-23
+- binutils-2.24-aarch64-fix-gotplt-offset-ifunc.patch
+  binutils-2.24-aarch64-fix-static-ifunc.patch, split elfnn-aarch64 patches
+  into upstream git commits, to make it easier to figure out what's
+  backported already
+- binutils-2.24-aarch64-fix-ie-relax.patch: add fix for gd to ie relaxation
+  when target register is >16 (pretty unlikely, but...)
+
 * Thu Aug 21 2014 Kyle McMartin <kmcmarti at redhat.com> - 2.24-22
 - bfd/elfnn-aarch64.c: use correct offsets in final_link_relocate
   Resolves: BZ #1126199


More information about the scm-commits mailing list