Fix sparc TLS call relaxation when the delay slot sets up %o0.
authorDavid S. Miller <davem@redhat.com>
Wed, 19 Oct 2011 00:32:25 +0000 (00:32 +0000)
committerDavid S. Miller <davem@redhat.com>
Wed, 19 Oct 2011 00:32:25 +0000 (00:32 +0000)
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.

bfd/ChangeLog
bfd/elfxx-sparc.c
gold/ChangeLog
gold/sparc.cc
ld/testsuite/ChangeLog
ld/testsuite/ld-sparc/tlssunbin32.dd
ld/testsuite/ld-sparc/tlssunbin64.dd
ld/testsuite/ld-sparc/tlssunpic32.dd
ld/testsuite/ld-sparc/tlssunpic64.dd

index 8f9b9be753e635252133a5ff0d8130314d98bd41..3a0c0eb3709820e28fd1e94ddc3491506f7c5393 100644 (file)
@@ -1,3 +1,11 @@
+2011-10-18  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-17  Alan Modra  <amodra@gmail.com>
 
        PR ld/12975
index 438b7f5b8872f79bcadcd6e7d4cdc261857e1de3..9a151247d1b40e369ec519d8241dac5935d0f5c8 100644 (file)
@@ -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;
            }
 
index 61ad6cdd33f3589e87f998f28590d46b9d12d908..153eead12b044a1b8daecda86d715c6e09b8d6db 100644 (file)
@@ -1,3 +1,16 @@
+2011-10-18  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-18  Cary Coutant  <ccoutant@google.com>
 
        * output.cc (posix_fallocate): Return 0 on success, errno on failure.
index 1d2cbad319d156289d50c661aa66333d163dd6b6..12e1dee1d64014b1a85d5f3b90f669bf74c0f5b1 100644 (file)
@@ -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;
index 6bf48c5b97f313bd0e89ec042acc886bf8f36f8f..791250803dbe2b5dd8b4be8e742e133f1f0dbdf4 100644 (file)
@@ -1,3 +1,11 @@
+2011-10-18  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-18  Jie Zhang  <jie@codesourcery.com>
            Julian Brown  <julian@codesourcery.com>
 
index 37c1d042809aa4db329cac24139573c3d8b9e3b5..c31d1909a579708ed3e95e294d359ef6a2f7731f 100644 (file)
@@ -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 *
index 0585ae6e2805481d8118e58006810138ea867481..cd7db1c55fdba18f612627634c81aee988857c05 100644 (file)
@@ -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 *
index c34d514ac1ec1e24158d5e7e94315fc62862f1f8..558977114d5763d442f52b5e7c1101f7bcddf4c6 100644 (file)
@@ -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 *
index 0b41b6858f4c65a6ea0d7c9916fa3ac7bd32b423..5e94858182dc938b8ac63e964286f493c69fd928 100644 (file)
@@ -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 *