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: Release 2.22: branch create


From: Eric Botcazou <ebotcazou@adacore.com>
Date: Mon, 17 Oct 2011 11:29:18 +0200

> Not sufficient it seems, you also need to move the potential relocation of the 
> insn in the delay slot.  The example I have is:
> 
>    0x00014188 <+232>:   add  %g7, %o0, %o0
>    0x0001418c <+236>:   sethi  %hi(0), %l0
>    0x00014190 <+240>:   ld  [ %o0 ], %g1
> 
> before the change and:
> 
>    0x00014188 <+232>:   sethi  %hi(0), %l0
>    0x0001418c <+236>:   add  %g0, %g0, %o0
>    0x00014190 <+240>:   ld  [ %o0 ], %g1
> 
> after, because of a R_SPARC_TLS_GD_HI22 relocation attached to the insn.

Sorry for taking so long, here is something that should work better.

bfd/

	PR binutils/13301
	* elfxx-sparc.c (sparc_elf_find_reloc_at_ofs): New function.
	(_bfd_sparc_elf_relocate_section): Always move the __tls_get_addr
	call delay slot instruction forward 4 bytes when performing
	relaxation.

gold/

	PR binutils/13301
	* sparc.cc (Target_sparc::Relocate::reloc_adjust_addr_): New
	member to track relocation locations that have moved during TLS
	reloc optimizations.
	(Target_sparc::Relocate::Relocate): Initialize to NULL.
	(Target_sparc::Relocate::relocate): Adjust view down by 4
	bytes if it matches reloc_adjust_addr_.
	(Target_sparc::Relocate::relocate_tls): Always move the
	__tls_get_addr call delay slot instruction forward 4 bytes when
	performing relaxation.

ld/testsuite/

	* ld-sparc/tlssunbin32.dd: Update for TLS call relaxation fix
	for PR 13301.
	* ld-sparc/tlssunbin64.dd: Likewise.
	* ld-sparc/tlssunpic32.dd: Likewise.
	* ld-sparc/tlssunpic64.dd: Likewise.

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 13242ba..3e6b908 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2011-10-16  David S. Miller  <davem@davemloft.net>
+
+	PR binutils/13301
+	* elfxx-sparc.c (sparc_elf_find_reloc_at_ofs): New function.
+	(_bfd_sparc_elf_relocate_section): Always move the __tls_get_addr
+	call delay slot instruction forward 4 bytes when performing
+	relaxation.
+
 2011-10-14  Hans-Peter Nilsson  <hp@axis.com>
 
 	* elf32-cris.c (cris_elf_gc_sweep_hook) <R_CRIS_16_GOTPLT>
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 438b7f5..9a15124 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -1830,6 +1830,20 @@ _bfd_sparc_elf_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
+static Elf_Internal_Rela *
+sparc_elf_find_reloc_at_ofs (Elf_Internal_Rela *rel,
+			     Elf_Internal_Rela *relend,
+			     bfd_vma offset)
+{
+  while (rel < relend)
+    {
+      if (rel->r_offset == offset)
+	return rel;
+      rel++;
+    }
+  return NULL;
+}
+
 /* Update the got entry reference counts for the section being removed.  */
 bfd_boolean
 _bfd_sparc_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
@@ -3676,6 +3690,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	  if (! info->shared
 	      || (r_type == R_SPARC_TLS_GD_CALL && tls_type == GOT_TLS_IE))
 	    {
+	      Elf_Internal_Rela *rel2;
 	      bfd_vma insn;
 
 	      if (!info->shared && (h == NULL || h->dynindx == -1))
@@ -3711,7 +3726,26 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 		  continue;
 		}
 
-	      bfd_put_32 (output_bfd, 0x9001c008, contents + rel->r_offset);
+	      /* We cannot just overwrite the delay slot instruction,
+		 as it might be what puts the %o0 argument to
+		 __tls_get_addr into place.  So we have to transpose
+		 the delay slot with the add we patch in.  */
+	      insn = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
+	      bfd_put_32 (output_bfd, insn,
+			  contents + rel->r_offset);
+	      bfd_put_32 (output_bfd, 0x9001c008,
+			  contents + rel->r_offset + 4);
+
+	      rel2 = rel;
+	      while ((rel2 = sparc_elf_find_reloc_at_ofs (rel2 + 1, relend,
+							  rel->r_offset + 4))
+		     != NULL)
+		{
+		  /* If the instruction we moved has a relocation attached to
+		     it, adjust the offset so that it will apply to the correct
+		     instruction.  */
+		  rel2->r_offset -= 4;
+		}
 	      continue;
 	    }
 
diff --git a/gold/ChangeLog b/gold/ChangeLog
index e6e8a9b..fffd22c 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,16 @@
+2011-10-16  David S. Miller  <davem@davemloft.net>
+
+	PR binutils/13301
+	* sparc.cc (Target_sparc::Relocate::reloc_adjust_addr_): New
+	member to track relocation locations that have moved during TLS
+	reloc optimizations.
+	(Target_sparc::Relocate::Relocate): Initialize to NULL.
+	(Target_sparc::Relocate::relocate): Adjust view down by 4
+	bytes if it matches reloc_adjust_addr_.
+	(Target_sparc::Relocate::relocate_tls): Always move the
+	__tls_get_addr call delay slot instruction forward 4 bytes when
+	performing relaxation.
+
 2011-10-12  Cary Coutant  <ccoutant@google.com>
 
 	* gold/output.cc (Output_file::open_base_file): Handle case where
diff --git a/gold/sparc.cc b/gold/sparc.cc
index 1d2cbad..12e1dee 100644
--- a/gold/sparc.cc
+++ b/gold/sparc.cc
@@ -265,7 +265,7 @@ class Target_sparc : public Sized_target<size, big_endian>
   {
    public:
     Relocate()
-      : ignore_gd_add_(false)
+      : ignore_gd_add_(false), reloc_adjust_addr_(NULL)
     { }
 
     ~Relocate()
@@ -302,6 +302,9 @@ class Target_sparc : public Sized_target<size, big_endian>
 
     // Ignore the next relocation which should be R_SPARC_TLS_GD_ADD
     bool ignore_gd_add_;
+
+    // If we hit a reloc at this view address, adjust it back by 4 bytes.
+    unsigned char *reloc_adjust_addr_;
   };
 
   // A class which returns the size required for a relocation type,
@@ -2622,6 +2625,8 @@ Target_sparc<size, big_endian>::Relocate::relocate(
 	  return false;
 	}
     }
+  if (this->reloc_adjust_addr_ == view)
+    view -= 4;
 
   typedef Sparc_relocate_functions<size, big_endian> Reloc;
 
@@ -3101,7 +3106,15 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
 		      wv += 1;
 		      this->ignore_gd_add_ = true;
 		    }
-
+		  else
+		    {
+		      // Even if the delay slot isn't the TLS_GD_ADD
+		      // instruction, we still have to handle the case
+		      // where it sets up %o0 in some other way.
+		      elfcpp::Swap<32, true>::writeval(wv, val);
+		      wv += 1;
+		      this->reloc_adjust_addr_ = view + 4;
+		    }
 		  // call __tls_get_addr --> add %g7, %o0, %o0
 		  elfcpp::Swap<32, true>::writeval(wv, 0x9001c008);
 		  break;
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 69df1ad..a4f79ae 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2011-10-16  David S. Miller  <davem@davemloft.net>
+
+	* ld-sparc/tlssunbin32.dd: Update for TLS call relaxation fix
+	for PR 13301.
+	* ld-sparc/tlssunbin64.dd: Likewise.
+	* ld-sparc/tlssunpic32.dd: Likewise.
+	* ld-sparc/tlssunpic64.dd: Likewise.
+
 2011-10-14  Hans-Peter Nilsson  <hp@axis.com>
 
 	* ld-cris/pic-gc-72.d: Adjust for dropping unused undefined
diff --git a/ld/testsuite/ld-sparc/tlssunbin32.dd b/ld/testsuite/ld-sparc/tlssunbin32.dd
index 37c1d04..c31d190 100644
--- a/ld/testsuite/ld-sparc/tlssunbin32.dd
+++ b/ld/testsuite/ld-sparc/tlssunbin32.dd
@@ -27,8 +27,8 @@ Disassembly of section .text:
  +11034:	01 00 00 00 	nop *
  +11038:	d0 05 c0 12 	ld  \[ %l7 \+ %l2 \], %o0
  +1103c:	01 00 00 00 	nop *
- +11040:	90 01 c0 08 	add  %g7, %o0, %o0
- +11044:	01 00 00 00 	nop *
+ +11040:	01 00 00 00 	nop *
+ +11044:	90 01 c0 08 	add  %g7, %o0, %o0
  +11048:	01 00 00 00 	nop *
  +1104c:	01 00 00 00 	nop *
  +11050:	01 00 00 00 	nop *
@@ -36,8 +36,8 @@ Disassembly of section .text:
  +11058:	11 00 00 00 	sethi  %hi\(0\), %o0
  +1105c:	92 02 20 08 	add  %o0, 8, %o1	! 8 <.*>
  +11060:	d0 05 c0 09 	ld  \[ %l7 \+ %o1 \], %o0
- +11064:	90 01 c0 08 	add  %g7, %o0, %o0
- +11068:	01 00 00 00 	nop *
+ +11064:	01 00 00 00 	nop *
+ +11068:	90 01 c0 08 	add  %g7, %o0, %o0
  +1106c:	01 00 00 00 	nop *
  +11070:	01 00 00 00 	nop *
  +11074:	01 00 00 00 	nop *
diff --git a/ld/testsuite/ld-sparc/tlssunbin64.dd b/ld/testsuite/ld-sparc/tlssunbin64.dd
index 0585ae6..cd7db1c 100644
--- a/ld/testsuite/ld-sparc/tlssunbin64.dd
+++ b/ld/testsuite/ld-sparc/tlssunbin64.dd
@@ -27,8 +27,8 @@ Disassembly of section .text:
  +101034:	01 00 00 00 	nop *
  +101038:	d0 5d c0 12 	ldx  \[ %l7 \+ %l2 \], %o0
  +10103c:	01 00 00 00 	nop *
- +101040:	90 01 c0 08 	add  %g7, %o0, %o0
- +101044:	01 00 00 00 	nop *
+ +101040:	01 00 00 00 	nop *
+ +101044:	90 01 c0 08 	add  %g7, %o0, %o0
  +101048:	01 00 00 00 	nop *
  +10104c:	01 00 00 00 	nop *
  +101050:	01 00 00 00 	nop *
@@ -36,8 +36,8 @@ Disassembly of section .text:
  +101058:	11 00 00 00 	sethi  %hi\(0\), %o0
  +10105c:	92 02 20 10 	add  %o0, 0x10, %o1	! 10 <.*>
  +101060:	d0 5d c0 09 	ldx  \[ %l7 \+ %o1 \], %o0
- +101064:	90 01 c0 08 	add  %g7, %o0, %o0
- +101068:	01 00 00 00 	nop *
+ +101064:	01 00 00 00 	nop *
+ +101068:	90 01 c0 08 	add  %g7, %o0, %o0
  +10106c:	01 00 00 00 	nop *
  +101070:	01 00 00 00 	nop *
  +101074:	01 00 00 00 	nop *
diff --git a/ld/testsuite/ld-sparc/tlssunpic32.dd b/ld/testsuite/ld-sparc/tlssunpic32.dd
index c34d514..5589771 100644
--- a/ld/testsuite/ld-sparc/tlssunpic32.dd
+++ b/ld/testsuite/ld-sparc/tlssunpic32.dd
@@ -37,8 +37,8 @@ Disassembly of section .text:
  +1058:	11 00 00 00 	sethi  %hi\(0\), %o0
  +105c:	92 02 20 3c 	add  %o0, 0x3c, %o1	! 3c <.*>
  +1060:	d0 05 c0 09 	ld  \[ %l7 \+ %o1 \], %o0
- +1064:	90 01 c0 08 	add  %g7, %o0, %o0
- +1068:	01 00 00 00 	nop *
+ +1064:	01 00 00 00 	nop *
+ +1068:	90 01 c0 08 	add  %g7, %o0, %o0
  +106c:	01 00 00 00 	nop *
  +1070:	01 00 00 00 	nop *
  +1074:	01 00 00 00 	nop *
@@ -55,8 +55,8 @@ Disassembly of section .text:
  +10a0:	11 00 00 00 	sethi  %hi\(0\), %o0
  +10a4:	90 02 20 0c 	add  %o0, 0xc, %o0	! c <.*>
  +10a8:	d0 05 c0 08 	ld  \[ %l7 \+ %o0 \], %o0
- +10ac:	90 01 c0 08 	add  %g7, %o0, %o0
- +10b0:	01 00 00 00 	nop *
+ +10ac:	01 00 00 00 	nop *
+ +10b0:	90 01 c0 08 	add  %g7, %o0, %o0
  +10b4:	01 00 00 00 	nop *
  +10b8:	01 00 00 00 	nop *
  +10bc:	01 00 00 00 	nop *
@@ -73,8 +73,8 @@ Disassembly of section .text:
  +10e8:	11 00 00 00 	sethi  %hi\(0\), %o0
  +10ec:	90 02 20 48 	add  %o0, 0x48, %o0	! 48 <.*>
  +10f0:	d0 05 c0 08 	ld  \[ %l7 \+ %o0 \], %o0
- +10f4:	90 01 c0 08 	add  %g7, %o0, %o0
- +10f8:	01 00 00 00 	nop *
+ +10f4:	01 00 00 00 	nop *
+ +10f8:	90 01 c0 08 	add  %g7, %o0, %o0
  +10fc:	01 00 00 00 	nop *
  +1100:	01 00 00 00 	nop *
  +1104:	01 00 00 00 	nop *
@@ -91,8 +91,8 @@ Disassembly of section .text:
  +1130:	11 00 00 00 	sethi  %hi\(0\), %o0
  +1134:	90 02 20 24 	add  %o0, 0x24, %o0	! 24 <.*>
  +1138:	d0 05 c0 08 	ld  \[ %l7 \+ %o0 \], %o0
- +113c:	90 01 c0 08 	add  %g7, %o0, %o0
- +1140:	01 00 00 00 	nop *
+ +113c:	01 00 00 00 	nop *
+ +1140:	90 01 c0 08 	add  %g7, %o0, %o0
  +1144:	01 00 00 00 	nop *
  +1148:	01 00 00 00 	nop *
  +114c:	01 00 00 00 	nop *
diff --git a/ld/testsuite/ld-sparc/tlssunpic64.dd b/ld/testsuite/ld-sparc/tlssunpic64.dd
index 0b41b68..5e94858 100644
--- a/ld/testsuite/ld-sparc/tlssunpic64.dd
+++ b/ld/testsuite/ld-sparc/tlssunpic64.dd
@@ -37,8 +37,8 @@ Disassembly of section .text:
  +1058:	11 00 00 00 	sethi  %hi\(0\), %o0
  +105c:	92 02 20 78 	add  %o0, 0x78, %o1	! 78 <.*>
  +1060:	d0 5d c0 09 	ldx  \[ %l7 \+ %o1 \], %o0
- +1064:	90 01 c0 08 	add  %g7, %o0, %o0
- +1068:	01 00 00 00 	nop *
+ +1064:	01 00 00 00 	nop *
+ +1068:	90 01 c0 08 	add  %g7, %o0, %o0
  +106c:	01 00 00 00 	nop *
  +1070:	01 00 00 00 	nop *
  +1074:	01 00 00 00 	nop *
@@ -55,8 +55,8 @@ Disassembly of section .text:
  +10a0:	11 00 00 00 	sethi  %hi\(0\), %o0
  +10a4:	90 02 20 18 	add  %o0, 0x18, %o0	! 18 <.*>
  +10a8:	d0 5d c0 08 	ldx  \[ %l7 \+ %o0 \], %o0
- +10ac:	90 01 c0 08 	add  %g7, %o0, %o0
- +10b0:	01 00 00 00 	nop *
+ +10ac:	01 00 00 00 	nop *
+ +10b0:	90 01 c0 08 	add  %g7, %o0, %o0
  +10b4:	01 00 00 00 	nop *
  +10b8:	01 00 00 00 	nop *
  +10bc:	01 00 00 00 	nop *
@@ -73,8 +73,8 @@ Disassembly of section .text:
  +10e8:	11 00 00 00 	sethi  %hi\(0\), %o0
  +10ec:	90 02 20 90 	add  %o0, 0x90, %o0	! 90 <.*>
  +10f0:	d0 5d c0 08 	ldx  \[ %l7 \+ %o0 \], %o0
- +10f4:	90 01 c0 08 	add  %g7, %o0, %o0
- +10f8:	01 00 00 00 	nop *
+ +10f4:	01 00 00 00 	nop *
+ +10f8:	90 01 c0 08 	add  %g7, %o0, %o0
  +10fc:	01 00 00 00 	nop *
  +1100:	01 00 00 00 	nop *
  +1104:	01 00 00 00 	nop *
@@ -91,8 +91,8 @@ Disassembly of section .text:
  +1130:	11 00 00 00 	sethi  %hi\(0\), %o0
  +1134:	90 02 20 48 	add  %o0, 0x48, %o0	! 48 <.*>
  +1138:	d0 5d c0 08 	ldx  \[ %l7 \+ %o0 \], %o0
- +113c:	90 01 c0 08 	add  %g7, %o0, %o0
- +1140:	01 00 00 00 	nop *
+ +113c:	01 00 00 00 	nop *
+ +1140:	90 01 c0 08 	add  %g7, %o0, %o0
  +1144:	01 00 00 00 	nop *
  +1148:	01 00 00 00 	nop *
  +114c:	01 00 00 00 	nop *


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