bfd/
authorDavid S. Miller <davem@redhat.com>
Thu, 11 Feb 2010 19:57:40 +0000 (19:57 +0000)
committerDavid S. Miller <davem@redhat.com>
Thu, 11 Feb 2010 19:57:40 +0000 (19:57 +0000)
* elfxx-sparc.c (_bfd_sparc_elf_check_relocs): For R_SPARC_GOTDATA_OP_HIX22
and R_SPARC_GOTDATA_OP_LOX10, only bump the GOT refcount for global
symbols.
(_bfd_sparc_elf_gc_sweep_hook): Likewise only decrement the GOT count for
these relocs on global symbols.
(gdopoff): New.
(_bfd_sparc_elf_relocate_section): Perform GOTDATA optimizations on
local symbol references which are not STT_GNU_IFUNC.  Handle
relocation of them like R_SPARC_HIX22 and R_SPARC_LOX10 respectively,
and deal with negative vs. non-negative values properly.

ld/testsuite

* ld-sparc/gotop32.s: Add local symbol case.
* ld-sparc/gotop64.s: Likewise.
* ld-sparc/gotop32.rd: Adjust expected results.
* ld-sparc/gotop32.td: Likewise.
* ld-sparc/gotop64.dd: Likewise.
* ld-sparc/gotop64.rd: Likewise.
* ld-sparc/gotop64.td: Likewise.

bfd/ChangeLog
bfd/elfxx-sparc.c
ld/testsuite/ChangeLog
ld/testsuite/ld-sparc/gotop32.dd
ld/testsuite/ld-sparc/gotop32.rd
ld/testsuite/ld-sparc/gotop32.s
ld/testsuite/ld-sparc/gotop32.td
ld/testsuite/ld-sparc/gotop64.dd
ld/testsuite/ld-sparc/gotop64.rd
ld/testsuite/ld-sparc/gotop64.s
ld/testsuite/ld-sparc/gotop64.td

index 0e0646ee205836ff7fdf0859a4d4c1bae7c2b0f9..fd505bcfb9b936d6e1d9c9f6725eee83f21c20bd 100644 (file)
@@ -1,3 +1,16 @@
+2010-02-11  David S. Miller  <davem@davemloft.net>
+
+       * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): For R_SPARC_GOTDATA_OP_HIX22
+       and R_SPARC_GOTDATA_OP_LOX10, only bump the GOT refcount for global
+       symbols.
+       (_bfd_sparc_elf_gc_sweep_hook): Likewise only decrement the GOT count for
+       these relocs on global symbols.
+       (gdopoff): New.
+       (_bfd_sparc_elf_relocate_section): Perform GOTDATA optimizations on
+       local symbol references which are not STT_GNU_IFUNC.  Handle
+       relocation of them like R_SPARC_HIX22 and R_SPARC_LOX10 respectively,
+       and deal with negative vs. non-negative values properly.
+
 2010-02-09  Tristan Gingold  <gingold@adacore.com>
 
        * mach-o.c (bfd_mach_o_canonicalize_one_reloc): Adjust addend for
index bc36920db947e73b5de9fbd42cca7c31fcd9f3d0..1947d1a1e87c456ccd628b0ef8e5819d57847048 100644 (file)
@@ -1345,8 +1345,6 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
              case R_SPARC_GOT10:
              case R_SPARC_GOT13:
              case R_SPARC_GOT22:
-             case R_SPARC_GOTDATA_HIX22:
-             case R_SPARC_GOTDATA_LOX10:
              case R_SPARC_GOTDATA_OP_HIX22:
              case R_SPARC_GOTDATA_OP_LOX10:
                tls_type = GOT_NORMAL;
@@ -1386,7 +1384,16 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    _bfd_sparc_elf_local_got_tls_type (abfd)
                      = (char *) (local_got_refcounts + symtab_hdr->sh_info);
                  }
-               local_got_refcounts[r_symndx] += 1;
+               switch (r_type)
+                 {
+                 case R_SPARC_GOTDATA_OP_HIX22:
+                 case R_SPARC_GOTDATA_OP_LOX10:
+                   break;
+
+                 default:
+                   local_got_refcounts[r_symndx] += 1;
+                   break;
+                 }
                old_tls_type = _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx];
              }
 
@@ -1766,8 +1773,17 @@ _bfd_sparc_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
            }
          else
            {
-             if (local_got_refcounts[r_symndx] > 0)
-               local_got_refcounts[r_symndx]--;
+             switch (r_type)
+               {
+               case R_SPARC_GOTDATA_OP_HIX22:
+               case R_SPARC_GOTDATA_OP_LOX10:
+                 break;
+
+               default:
+                 if (local_got_refcounts[r_symndx] > 0)
+                   local_got_refcounts[r_symndx]--;
+                 break;
+               }
            }
          break;
 
@@ -2672,6 +2688,21 @@ tpoff (struct bfd_link_info *info, bfd_vma address)
   return address - htab->tls_size - htab->tls_sec->vma;
 }
 
+/* Return the relocation value for a %gdop relocation.  */
+
+static bfd_vma
+gdopoff (struct bfd_link_info *info, bfd_vma address)
+{
+  struct elf_link_hash_table *htab = elf_hash_table (info);
+  bfd_vma got_base;
+
+  got_base = (htab->hgot->root.u.def.value
+             + htab->hgot->root.u.def.section->output_offset
+             + htab->hgot->root.u.def.section->output_section->vma);
+
+  return address - got_base;
+}
+
 /* Relocate a SPARC ELF section.  */
 
 bfd_boolean
@@ -2821,10 +2852,17 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 
          switch (r_type)
            {
-           case R_SPARC_GOTDATA_HIX22:
-           case R_SPARC_GOTDATA_LOX10:
+           case R_SPARC_GOTDATA_OP:
+             continue;
+
            case R_SPARC_GOTDATA_OP_HIX22:
            case R_SPARC_GOTDATA_OP_LOX10:
+             r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
+                       ? R_SPARC_GOT22
+                       : R_SPARC_GOT10);
+             howto = _bfd_sparc_elf_howto_table + r_type;
+             /* Fall through.  */
+
            case R_SPARC_GOT10:
            case R_SPARC_GOT13:
            case R_SPARC_GOT22:
@@ -2911,19 +2949,37 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 
       switch (r_type)
        {
-       case R_SPARC_GOTDATA_HIX22:
-       case R_SPARC_GOTDATA_LOX10:
        case R_SPARC_GOTDATA_OP_HIX22:
        case R_SPARC_GOTDATA_OP_LOX10:
-         /* We don't support these code transformation optimizations
-            yet, so just leave the sequence alone and treat as
-            GOT22/GOT10.  */
-         if (r_type == R_SPARC_GOTDATA_HIX22
-             || r_type == R_SPARC_GOTDATA_OP_HIX22)
-           r_type = R_SPARC_GOT22;
+         if (SYMBOL_REFERENCES_LOCAL (info, h))
+           r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
+                     ? R_SPARC_GOTDATA_HIX22
+                     : R_SPARC_GOTDATA_LOX10);
          else
-           r_type = R_SPARC_GOT10;
-         /* Fall through. */
+           r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
+                     ? R_SPARC_GOT22
+                     : R_SPARC_GOT10);
+         howto = _bfd_sparc_elf_howto_table + r_type;
+         break;
+
+       case R_SPARC_GOTDATA_OP:
+         if (SYMBOL_REFERENCES_LOCAL (info, h))
+           {
+             bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+             /* {ld,ldx} [%rs1 + %rs2], %rd --> add %rs1, %rs2, %rd */
+             relocation = 0x80000000 | (insn & 0x3e07c01f);
+             bfd_put_32 (output_bfd, relocation, contents + rel->r_offset);
+           }
+         continue;
+       }
+
+      switch (r_type)
+       {
+       case R_SPARC_GOTDATA_HIX22:
+       case R_SPARC_GOTDATA_LOX10:
+         relocation = gdopoff (info, relocation);
+         break;
 
        case R_SPARC_GOT10:
        case R_SPARC_GOT13:
@@ -3576,11 +3632,6 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
            }
          continue;
 
-       case R_SPARC_GOTDATA_OP:
-         /* We don't support gotdata code transformation optimizations
-            yet, so simply leave the sequence as-is.  */
-         continue;
-
        case R_SPARC_TLS_IE_LD:
        case R_SPARC_TLS_IE_LDX:
          if (! info->shared && (h == NULL || h->dynindx == -1))
@@ -3704,12 +3755,15 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 
          r = bfd_reloc_ok;
        }
-      else if (r_type == R_SPARC_HIX22)
+      else if (r_type == R_SPARC_HIX22
+              || r_type == R_SPARC_GOTDATA_HIX22)
        {
          bfd_vma x;
 
          relocation += rel->r_addend;
-         relocation = relocation ^ MINUS_ONE;
+         if (r_type == R_SPARC_HIX22
+             || (bfd_signed_vma) relocation < 0)
+           relocation = relocation ^ MINUS_ONE;
 
          x = bfd_get_32 (input_bfd, contents + rel->r_offset);
          x = (x & ~(bfd_vma) 0x3fffff) | ((relocation >> 10) & 0x3fffff);
@@ -3720,12 +3774,17 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                                  bfd_arch_bits_per_address (input_bfd),
                                  relocation);
        }
-      else if (r_type == R_SPARC_LOX10)
+      else if (r_type == R_SPARC_LOX10
+              || r_type == R_SPARC_GOTDATA_LOX10)
        {
          bfd_vma x;
 
          relocation += rel->r_addend;
-         relocation = (relocation & 0x3ff) | 0x1c00;
+         if (r_type == R_SPARC_LOX10
+             || (bfd_signed_vma) relocation < 0)
+           relocation = (relocation & 0x3ff) | 0x1c00;
+         else
+           relocation = (relocation & 0x3ff);
 
          x = bfd_get_32 (input_bfd, contents + rel->r_offset);
          x = (x & ~(bfd_vma) 0x1fff) | relocation;
index faec3f4aadfca4cc74cf5f0b67732e1d39074402..b67acb02d5295729677be0af8002685bb60d54f3 100644 (file)
@@ -1,3 +1,13 @@
+2010-02-11  David S. Miller  <davem@davemloft.net>
+
+       * ld-sparc/gotop32.s: Add local symbol case.
+       * ld-sparc/gotop64.s: Likewise.
+       * ld-sparc/gotop32.rd: Adjust expected results.
+       * ld-sparc/gotop32.td: Likewise.
+       * ld-sparc/gotop64.dd: Likewise.
+       * ld-sparc/gotop64.rd: Likewise.
+       * ld-sparc/gotop64.td: Likewise.
+
 2010-02-09  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
        * ld-elfvsb/elfvsb.exp: Fix tests for arm*-*-linux*.
index 9f6b1f6579b0a6a1e40bf5323e1a9bc64b6f400d..a599930433b7da6e5e7fb4342bad965ae51e2bdb 100644 (file)
@@ -17,12 +17,18 @@ Disassembly of section .text:
  +1010:        7f ff ff fc     call  1000 <_.*>
  +1014:        ae 05 e0 60     add  %l7, 0x60, %l7     ! 11060 <.*>
  +1018:        01 00 00 00     nop *
- +101c:        23 00 00 04     sethi  %hi\(0x1000\), %l1
+ +101c:        23 00 00 00     sethi  %hi\(0\), %l1
  +1020:        01 00 00 00     nop *
  +1024:        a2 1c 60 04     xor  %l1, 4, %l1
  +1028:        01 00 00 00     nop *
  +102c:        f0 05 c0 11     ld  \[ %l7 \+ %l1 \], %i0
  +1030:        01 00 00 00     nop *
- +1034:        81 c7 e0 08     ret 
- +1038:        81 e8 00 00     restore 
+ +1034:        23 00 00 03     sethi  %hi\(0xc00\), %l1
+ +1038:        01 00 00 00     nop 
+ +103c:        a2 1c 63 94     xor  %l1, 0x394, %l1
+ +1040:        01 00 00 00     nop 
+ +1044:        b0 05 c0 11     add  %l7, %l1, %i0
+ +1048:        01 00 00 00     nop 
+ +104c:        81 c7 e0 08     ret 
+ +1050:        81 e8 00 00     restore 
 #pass
index 566066c0f1ad6d520fabe843425e5f8ed3b66674..1cecad8c46565a07ee5d39d10f2896c768aacd8f 100644 (file)
@@ -59,6 +59,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
 .* SECTION +LOCAL +DEFAULT +6 *
 .* SECTION +LOCAL +DEFAULT +7 *
 .* SECTION +LOCAL +DEFAULT +8 *
+.* NOTYPE +LOCAL +DEFAULT +8 local_sym
 .* OBJECT +LOCAL +DEFAULT +ABS _DYNAMIC
 .* OBJECT +LOCAL +DEFAULT +ABS _PROCEDURE_LINKAGE_TABLE_
 .* OBJECT +LOCAL +DEFAULT +ABS _GLOBAL_OFFSET_TABLE_
index ac01d6f27728076004ec077798014fac07db477a..604694c6669a54aeb53cd7386c51ebe42c43b48a 100644 (file)
@@ -3,6 +3,9 @@
        .globl  sym
 sym:   .word   0x12345678
 
+local_sym:
+       .word   0xdeadbeef
+
        .text
        .align  4096
 .LLGETPC0:
@@ -24,5 +27,11 @@ foo:
        nop
        ld      [%l7 + %l1], %i0, %gdop(sym)
        nop
+       sethi   %gdop_hix22(local_sym), %l1
+       nop
+       xor     %l1, %gdop_lox10(local_sym), %l1
+       nop
+       ld      [%l7 + %l1], %i0, %gdop(local_sym)
+       nop
        ret
        restore
index e73482d9f22eae0d8df6b7373f76c8b2da025021..520788b0aee8dbf3a66c6cec2454d5b101deef10 100644 (file)
@@ -7,6 +7,6 @@
 .*: +file format elf32-sparc
 
 Contents of section .data:
- 13000 12345678 00000000 00000000 00000000  .*
+ 13000 12345678 deadbeef 00000000 00000000  .*
  13010 00000000 00000000 00000000 00000000  .*
 #pass
index a78f55a69ba72fa83ba587823ec8fadf91321e0b..d73fb1832bacd383ec430868a8e86bc8ec682cd8 100644 (file)
@@ -17,12 +17,18 @@ Disassembly of section .text:
  +1010:        7f ff ff fc     call  1000 <_.*>
  +1014:        ae 05 e0 d0     add  %l7, 0xd0, %l7     ! 1010d0 <.*>
  +1018:        01 00 00 00     nop *
- +101c:        23 00 00 08     sethi  %hi\(0x2000\), %l1
+ +101c:        23 00 00 00     sethi  %hi\(0\), %l1
  +1020:        01 00 00 00     nop *
  +1024:        a2 1c 60 08     xor  %l1, 8, %l1
  +1028:        01 00 00 00     nop *
  +102c:        f0 5d c0 11     ldx  \[ %l7 \+ %l1 \], %i0
  +1030:        01 00 00 00     nop *
- +1034:        81 c7 e0 08     ret 
- +1038:        81 e8 00 00     restore 
+ +1034:        23 00 00 03     sethi  %hi\(0xc00\), %l1
+ +1038:        01 00 00 00     nop *
+ +103c:        a2 1c 63 24     xor  %l1, 0x324, %l1
+ +1040:        01 00 00 00     nop *
+ +1044:        b0 05 c0 11     add  %l7, %l1, %i0
+ +1048:        01 00 00 00     nop *
+ +104c:        81 c7 e0 08     ret 
+ +1050:        81 e8 00 00     restore 
 #pass
index 4d3e519a742102b6936bb584019401b00e055e37..509c8f898946836e131fd218065f7dc820deb4f3 100644 (file)
@@ -59,6 +59,7 @@ Symbol table '\.symtab' contains [0-9]+ entries:
 .* SECTION +LOCAL +DEFAULT +6 *
 .* SECTION +LOCAL +DEFAULT +7 *
 .* SECTION +LOCAL +DEFAULT +8 *
+.* NOTYPE +LOCAL +DEFAULT +8 local_sym
 .* OBJECT +LOCAL +DEFAULT +ABS _DYNAMIC
 .* OBJECT +LOCAL +DEFAULT +ABS _PROCEDURE_LINKAGE_TABLE_
 .* OBJECT +LOCAL +DEFAULT +ABS _GLOBAL_OFFSET_TABLE_
index 8a8ff82b89a298ae00ea609b8eb0b641eb8f9a23..9910813d2a57c6a0c977bc0074f569b137f96573 100644 (file)
@@ -3,6 +3,9 @@
        .globl  sym
 sym:   .word   0x12345678
 
+local_sym:
+       .word   0xdeadbeef
+
        .text
        .align  4096
 .LLGETPC0:
@@ -24,5 +27,11 @@ foo:
        nop
        ldx     [%l7 + %l1], %i0, %gdop(sym)
        nop
+       sethi   %gdop_hix22(local_sym), %l1
+       nop
+       xor     %l1, %gdop_lox10(local_sym), %l1
+       nop
+       ldx     [%l7 + %l1], %i0, %gdop(local_sym)
+       nop
        ret
        restore
index f16cf503447a7eeab5ae1363f23fa1de83d677e0..28d40edc28a02f0c76a99580336ad43177a6fdb0 100644 (file)
@@ -7,6 +7,6 @@
 .*: +file format elf64-sparc
 
 Contents of section .data:
- 103000 12345678 00000000 00000000 00000000  .*
+ 103000 12345678 deadbeef 00000000 00000000  .*
  103010 00000000 00000000 00000000 00000000  .*
 #pass
This page took 0.039167 seconds and 4 git commands to generate.