Support R_SPARC_WDISP10 and R_SPARC_H34.
authorDavid S. Miller <davem@redhat.com>
Thu, 12 Apr 2012 16:26:06 +0000 (16:26 +0000)
committerDavid S. Miller <davem@redhat.com>
Thu, 12 Apr 2012 16:26:06 +0000 (16:26 +0000)
include/

* elf/sparc.h (R_SPARC_WDISP10): New reloc.
* opcode/sparc.h: Define '=' as generating R_SPARC_WDISP10.

opcodes/

* sparc-dis.c (X_DISP10): Define.
(print_insn_sparc): Handle '='.

bfd/

* reloc.c (BFD_RELOC_SPARC_H34, BFD_RELOC_SPARC_SIZE32,
BFD_RELOC_SPARC_SIZE64, BFD_RELOC_SPARC_WDISP10): New relocs.
* libbfd.h: Regenerate.
* bfd-in2.h: Likewise.
* elfxx-sparc.c (sparc_elf_wdisp10_reloc): New function.
(_bfd_sparc_elf_howto_table): Add entries for R_SPARC_H34,
R_SPARC_SIZE32, R_SPARC_64, and R_SPARC_WDISP10.
(_bfd_sparc_elf_reloc_type_lookup): Handle new relocs.
(_bfd_sparc_elf_check_relocs): Likewise.
(_bfd_sparc_elf_gc_sweep_hook): Likewise.
(_bfd_sparc_elf_relocate_section): Likewise.

gas/

* config/tc-sparc.c (sparc_ip): Handle '=', "%h34", "%l34", and
BFD_RELOC_SPARC_H34.
(md_apply_fix): Handle BFD_RELOC_SPARC_WDISP10 and BFD_RELOC_SPARC_H34.
(tc_gen_reloc): Likewise.

gas/testsuite/

* gas/sparc/reloc64.s: Add abs34 code model tests.
* gas/sparc/reloc64.d: Update.

elfcpp/

* sparc.h (R_SPARC_WDISP10): New relocation.

gold/

* sparc.cc (Reloc::wdisp10): New relocation method.
(Reloc::h34): Likewise.
(Target_sparc::Scan::check_non_pic): Handle R_SPARC_H34.
(Target_sparc::Scan::get_reference_flags): Handle R_SPARC_H34 and
R_SPARC_WDISP10.
(Target_sparc::Scan::local): Likewise.
(Target_sparc::Scan::global): Likewise.
(Target_sparc::Relocate::relocate): Likewise.

19 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elfxx-sparc.c
bfd/libbfd.h
bfd/reloc.c
elfcpp/ChangeLog
elfcpp/sparc.h
gas/ChangeLog
gas/config/tc-sparc.c
gas/testsuite/ChangeLog
gas/testsuite/gas/sparc/reloc64.d
gas/testsuite/gas/sparc/reloc64.s
gold/ChangeLog
gold/sparc.cc
include/ChangeLog
include/elf/sparc.h
include/opcode/sparc.h
opcodes/ChangeLog
opcodes/sparc-dis.c

index f53dcfda31172c6877531215796999c707c230e6..6eea52d56c553646cef847462bd9eaf4a25012b5 100644 (file)
@@ -1,3 +1,17 @@
+2012-04-12  David S. Miller  <davem@davemloft.net>
+
+       * reloc.c (BFD_RELOC_SPARC_H34, BFD_RELOC_SPARC_SIZE32,
+       BFD_RELOC_SPARC_SIZE64, BFD_RELOC_SPARC_WDISP10): New relocs.
+       * libbfd.h: Regenerate.
+       * bfd-in2.h: Likewise.
+       * elfxx-sparc.c (sparc_elf_wdisp10_reloc): New function.
+       (_bfd_sparc_elf_howto_table): Add entries for R_SPARC_H34,
+       R_SPARC_SIZE32, R_SPARC_64, and R_SPARC_WDISP10.
+       (_bfd_sparc_elf_reloc_type_lookup): Handle new relocs.
+       (_bfd_sparc_elf_check_relocs): Likewise.
+       (_bfd_sparc_elf_gc_sweep_hook): Likewise.
+       (_bfd_sparc_elf_relocate_section): Likewise.
+
 2012-04-12  Roland McGrath  <mcgrathr@google.com>
 
        * elf32-arm.c (elf32_arm_nacl_plt0_entry, elf32_arm_nacl_plt_entry):
index 07898bef3e0772151018861a7411ac27ff98619e..859f8255115bccec41c0a6ae4425b920e5e4cad1 100644 (file)
@@ -2595,6 +2595,10 @@ relocation types already defined.  */
   BFD_RELOC_SPARC_M44,
   BFD_RELOC_SPARC_L44,
   BFD_RELOC_SPARC_REGISTER,
+  BFD_RELOC_SPARC_H34,
+  BFD_RELOC_SPARC_SIZE32,
+  BFD_RELOC_SPARC_SIZE64,
+  BFD_RELOC_SPARC_WDISP10,
 
 /* SPARC little endian relocation  */
   BFD_RELOC_SPARC_REV32,
index 9155311c3818156292257ff7733df267bef70807..9609d3715b02e9f3a73a9d2e0becdb4922f8e1b9 100644 (file)
@@ -132,6 +132,34 @@ sparc_elf_wdisp16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
     return bfd_reloc_ok;
 }
 
+/* Handle the WDISP10 reloc.  */
+
+static bfd_reloc_status_type
+sparc_elf_wdisp10_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+                        PTR data, asection *input_section, bfd *output_bfd,
+                        char **error_message ATTRIBUTE_UNUSED)
+{
+  bfd_vma relocation;
+  bfd_vma insn;
+  bfd_reloc_status_type status;
+
+  status = init_insn_reloc (abfd, reloc_entry, symbol, data,
+                           input_section, output_bfd, &relocation, &insn);
+  if (status != bfd_reloc_other)
+    return status;
+
+  insn &= ~ (bfd_vma) 0x181fe0;
+  insn |= (((relocation >> 2) & 0x300) << 11)
+         | (((relocation >> 2) & 0xff) << 5);
+  bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+  if ((bfd_signed_vma) relocation < - 0x1000
+      || (bfd_signed_vma) relocation > 0xfff)
+    return bfd_reloc_overflow;
+  else
+    return bfd_reloc_ok;
+}
+
 /* Handle the HIX22 reloc.  */
 
 static bfd_reloc_status_type
@@ -267,6 +295,10 @@ static reloc_howto_type _bfd_sparc_elf_howto_table[] =
   HOWTO(R_SPARC_GOTDATA_OP_HIX22,0,2,0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc,"R_SPARC_GOTDATA_OP_HIX22",FALSE,0,0x003fffff, FALSE),
   HOWTO(R_SPARC_GOTDATA_OP_LOX10,0,2,0,FALSE,0,complain_overflow_dont,  sparc_elf_lox10_reloc,  "R_SPARC_GOTDATA_OP_LOX10",FALSE,0,0x000003ff, FALSE),
   HOWTO(R_SPARC_GOTDATA_OP,0,0, 0,FALSE,0,complain_overflow_dont,   bfd_elf_generic_reloc,  "R_SPARC_GOTDATA_OP",FALSE,0,0x00000000,TRUE),
+  HOWTO(R_SPARC_H34,12,2,22,FALSE,0,complain_overflow_unsigned,bfd_elf_generic_reloc,"R_SPARC_H34",FALSE,0,0x003fffff,FALSE),
+  HOWTO(R_SPARC_SIZE32,0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_SIZE32",FALSE,0,0xffffffff,TRUE),
+  HOWTO(R_SPARC_SIZE64,0,4,64,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_SIZE64",FALSE,0,MINUS_ONE, TRUE),
+  HOWTO(R_SPARC_WDISP10,2,2,10,TRUE, 0,complain_overflow_signed,sparc_elf_wdisp10_reloc,"R_SPARC_WDISP10",FALSE,0,0x00000000,TRUE),
 };
 static reloc_howto_type sparc_jmp_irel_howto =
   HOWTO(R_SPARC_JMP_IREL,  0,0,00,FALSE,0,complain_overflow_dont,    bfd_elf_generic_reloc,  "R_SPARC_JMP_IREL",FALSE,0,0x00000000,TRUE);
@@ -524,6 +556,18 @@ _bfd_sparc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
     case BFD_RELOC_SPARC_GOTDATA_OP:
       return &_bfd_sparc_elf_howto_table[R_SPARC_GOTDATA_OP];
 
+    case BFD_RELOC_SPARC_H34:
+      return &_bfd_sparc_elf_howto_table[R_SPARC_H34];
+
+    case BFD_RELOC_SPARC_SIZE32:
+      return &_bfd_sparc_elf_howto_table[R_SPARC_SIZE32];
+
+    case BFD_RELOC_SPARC_SIZE64:
+      return &_bfd_sparc_elf_howto_table[R_SPARC_SIZE64];
+
+    case BFD_RELOC_SPARC_WDISP10:
+      return &_bfd_sparc_elf_howto_table[R_SPARC_WDISP10];
+
     case BFD_RELOC_SPARC_JMP_IREL:
       return &sparc_jmp_irel_howto;
 
@@ -1656,6 +1700,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_SPARC_WDISP22:
        case R_SPARC_WDISP19:
        case R_SPARC_WDISP16:
+       case R_SPARC_WDISP10:
        case R_SPARC_8:
        case R_SPARC_16:
        case R_SPARC_32:
@@ -1680,6 +1725,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_SPARC_H44:
        case R_SPARC_M44:
        case R_SPARC_L44:
+       case R_SPARC_H34:
        case R_SPARC_UA64:
          if (h != NULL)
            h->non_got_ref = 1;
@@ -1956,6 +2002,7 @@ _bfd_sparc_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
        case R_SPARC_WDISP22:
        case R_SPARC_WDISP19:
        case R_SPARC_WDISP16:
+       case R_SPARC_WDISP10:
        case R_SPARC_8:
        case R_SPARC_16:
        case R_SPARC_32:
@@ -1981,6 +2028,7 @@ _bfd_sparc_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
        case R_SPARC_H44:
        case R_SPARC_M44:
        case R_SPARC_L44:
+       case R_SPARC_H34:
        case R_SPARC_UA64:
          if (info->shared)
            break;
@@ -3276,6 +3324,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
        case R_SPARC_WDISP22:
        case R_SPARC_WDISP19:
        case R_SPARC_WDISP16:
+       case R_SPARC_WDISP10:
        case R_SPARC_8:
        case R_SPARC_16:
        case R_SPARC_32:
@@ -3300,6 +3349,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
        case R_SPARC_H44:
        case R_SPARC_M44:
        case R_SPARC_L44:
+       case R_SPARC_H34:
        case R_SPARC_UA64:
        r_sparc_plt32:
          if ((input_section->flags & SEC_ALLOC) == 0
@@ -3866,6 +3916,25 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                | ((relocation >> 2) & 0x3fff));
          bfd_put_32 (input_bfd, x, contents + rel->r_offset);
 
+         r = bfd_check_overflow (howto->complain_on_overflow,
+                                 howto->bitsize, howto->rightshift,
+                                 bfd_arch_bits_per_address (input_bfd),
+                                 relocation);
+       }
+      else if (r_type == R_SPARC_WDISP10)
+       {
+         bfd_vma x;
+
+         relocation += rel->r_addend;
+         relocation -= (input_section->output_section->vma
+                        + input_section->output_offset);
+         relocation -= rel->r_offset;
+
+         x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+         x |= ((((relocation >> 2) & 0x300) << 11)
+               | (((relocation >> 2) & 0xff) << 5));
+         bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+
          r = bfd_check_overflow (howto->complain_on_overflow,
                                  howto->bitsize, howto->rightshift,
                                  bfd_arch_bits_per_address (input_bfd),
index 844d3a73d9c46038f949c3a883722eef8d9e69d0..cc293bca19dacdbcc62f22ed827e8407254a4891 100644 (file)
@@ -1014,6 +1014,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_SPARC_M44",
   "BFD_RELOC_SPARC_L44",
   "BFD_RELOC_SPARC_REGISTER",
+  "BFD_RELOC_SPARC_H34",
+  "BFD_RELOC_SPARC_SIZE32",
+  "BFD_RELOC_SPARC_SIZE64",
+  "BFD_RELOC_SPARC_WDISP10",
   "BFD_RELOC_SPARC_REV32",
   "BFD_RELOC_SPARC_TLS_GD_HI22",
   "BFD_RELOC_SPARC_TLS_GD_LO10",
index fb3aab26564b7876ae85414471caafb310774b1d..aed361247dedb19133275cdfc0b1f08d26c6c9dd 100644 (file)
@@ -1942,6 +1942,14 @@ ENUMX
   BFD_RELOC_SPARC_L44
 ENUMX
   BFD_RELOC_SPARC_REGISTER
+ENUMX
+  BFD_RELOC_SPARC_H34
+ENUMX
+  BFD_RELOC_SPARC_SIZE32
+ENUMX
+  BFD_RELOC_SPARC_SIZE64
+ENUMX
+  BFD_RELOC_SPARC_WDISP10
 ENUMDOC
   SPARC64 relocations
 
index f606faad4da7c69841a22afd7d7a9134773037f2..3a764014d1f02e8c5e99a300012a1c45c64dec13 100644 (file)
@@ -1,3 +1,7 @@
+2012-04-12  David S. Miller  <davem@davemloft.net>
+
+       * sparc.h (R_SPARC_WDISP10): New relocation.
+
 2012-03-12  Cary Coutant  <ccoutant@google.com>
 
        Update DWARF enums from ../include/dwarf2.h.
index 6a9193b355cbff8fa4c54041f9886abe4dd2eed7..77c4668773b904547b8c01ebd1da5ea7ed8aaa7c 100644 (file)
@@ -140,6 +140,7 @@ enum
   R_SPARC_H34 = 85,           // Direct high 12 of 34 bit
   R_SPARC_SIZE32 = 86,        // size of symbol, 32-bit
   R_SPARC_SIZE64 = 87,        // size of symbol, 64-bit
+  R_SPARC_WDISP10 = 88,       // PC relative 10 bit shifted
 
   R_SPARC_IRELATIVE = 249,    // Adjust indirectly by program base
 
index 6a9191eb7a10498013d855fa1d4ca08ec8f03000..0149bd0050c924176d27300cd8f81074a7c86375 100644 (file)
@@ -1,3 +1,10 @@
+2012-04-12  David S. Miller  <davem@davemloft.net>
+
+       * config/tc-sparc.c (sparc_ip): Handle '=', "%h34", "%l34", and
+       BFD_RELOC_SPARC_H34.
+       (md_apply_fix): Handle BFD_RELOC_SPARC_WDISP10 and BFD_RELOC_SPARC_H34.
+       (tc_gen_reloc): Likewise.
+
 2012-04-12  Roland McGrath  <mcgrathr@google.com>
 
        * configure.tgt (arm-*-nacl*): Match it.
index f4537330671077b023c78a88bd821fe7d2fff863..1956dff678157fb3e2fc7d8c0a27a086b1b63009 100644 (file)
@@ -1835,6 +1835,11 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
              the_insn.pcrel = 1;
              goto immediate;
 
+           case '=':
+             the_insn.reloc = /* RELOC_WDISP2_8 */ BFD_RELOC_SPARC_WDISP10;
+             the_insn.pcrel = 1;
+             goto immediate;
+
            case 'G':
              the_insn.reloc = BFD_RELOC_SPARC_WDISP19;
              the_insn.pcrel = 1;
@@ -2418,6 +2423,8 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
                      { "hh", 2, BFD_RELOC_SPARC_HH22, 1, 1 },
                      { "hm", 2, BFD_RELOC_SPARC_HM10, 1, 1 },
                      { "lm", 2, BFD_RELOC_SPARC_LM22, 1, 1 },
+                     { "h34", 3, BFD_RELOC_SPARC_H34, 1, 0 },
+                     { "l34", 3, BFD_RELOC_SPARC_L44, 1, 0 },
                      { "h44", 3, BFD_RELOC_SPARC_H44, 1, 0 },
                      { "m44", 3, BFD_RELOC_SPARC_M44, 1, 0 },
                      { "l44", 3, BFD_RELOC_SPARC_L44, 1, 0 },
@@ -2581,6 +2588,11 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
                            val &= 0x3ff;
                            break;
 
+                         case BFD_RELOC_SPARC_H34:
+                           val >>= 12;
+                           val &= 0x3fffff;
+                           break;
+
                          case BFD_RELOC_SPARC_H44:
                            val >>= 22;
                            val &= 0x3fffff;
@@ -3360,6 +3372,18 @@ md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
          insn |= val & 0x1f;
          break;
 
+       case BFD_RELOC_SPARC_WDISP10:
+         if ((val & 3)
+             || val >= 0x007fc
+             || val <= -(offsetT) 0x808)
+           as_bad_where (fixP->fx_file, fixP->fx_line,
+                         _("relocation overflow"));
+         /* FIXME: The +1 deserves a comment.  */
+         val = (val >> 2) + 1;
+         insn |= ((val & 0x300) << 11)
+           | ((val & 0xff) << 5);
+         break;
+
        case BFD_RELOC_SPARC_WDISP16:
          if ((val & 3)
              || val >= 0x1fffc
@@ -3433,6 +3457,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
          insn |= val & 0x3fffff;
          break;
 
+       case BFD_RELOC_SPARC_H34:
+         if (!fixP->fx_addsy)
+           {
+             bfd_vma tval = val;
+             tval >>= 12;
+             insn |= tval & 0x3fffff;
+           }
+         break;
+
        case BFD_RELOC_SPARC_H44:
          if (!fixP->fx_addsy)
            {
@@ -3513,6 +3546,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
     case BFD_RELOC_SPARC_PC22:
     case BFD_RELOC_SPARC_PC10:
     case BFD_RELOC_SPARC_BASE13:
+    case BFD_RELOC_SPARC_WDISP10:
     case BFD_RELOC_SPARC_WDISP16:
     case BFD_RELOC_SPARC_WDISP19:
     case BFD_RELOC_SPARC_WDISP22:
@@ -3528,6 +3562,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
     case BFD_RELOC_SPARC_PC_HH22:
     case BFD_RELOC_SPARC_PC_HM10:
     case BFD_RELOC_SPARC_PC_LM22:
+    case BFD_RELOC_SPARC_H34:
     case BFD_RELOC_SPARC_H44:
     case BFD_RELOC_SPARC_M44:
     case BFD_RELOC_SPARC_L44:
@@ -3683,6 +3718,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
       && code != BFD_RELOC_SPARC_WDISP22
       && code != BFD_RELOC_SPARC_WDISP16
       && code != BFD_RELOC_SPARC_WDISP19
+      && code != BFD_RELOC_SPARC_WDISP10
       && code != BFD_RELOC_SPARC_WPLT30
       && code != BFD_RELOC_SPARC_TLS_GD_CALL
       && code != BFD_RELOC_SPARC_TLS_LDM_CALL)
index 8ad16059ad399e8a3631d694e103efaf9d6d060e..79af6269e59214b1849a403df0c65b1791f612cb 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-12  David S. Miller  <davem@davemloft.net>
+
+       * gas/sparc/reloc64.s: Add abs34 code model tests.
+       * gas/sparc/reloc64.d: Update.
+
 2012-04-12  Roland McGrath  <mcgrathr@google.com>
 
        * gas/elf/elf.exp (run_elf_list_test): Treat arm-*-nacl* targets
index da40d0ccc586ebbf3b0ca33204c58bfc0e227e5d..07e2a103c24b26564756f93a2221b27341527045 100644 (file)
@@ -74,3 +74,9 @@ Disassembly of section .text:
   ac:  82 18 60 00     xor  %g1, 0, %g1
                        ac: R_SPARC_LOX10       .text\+0xffffffff76543210
   b0:  01 00 00 00     nop 
+  b4:  03 00 00 00     sethi  %hi\((0x|)0\), %g1
+                       b4: R_SPARC_H34 .text\+0xa9876543210
+  b8:  83 28 70 02     sllx  %g1, 2, %g1
+  bc:  82 10 60 00     mov  %g1, %g1
+                       bc: R_SPARC_L44 .text\+0xa9876543210
+  c0:  01 00 00 00     nop 
index 9ead6afbf29db31b64afa1dca8121eb592b6e310..534a0ae0ab5b3711d6b3243dfcdb5444865844e9 100644 (file)
@@ -46,3 +46,7 @@ foo:
        sethi %hix(foo+0xffffffff76543210),%g1
        xor %g1,%lox(foo+0xffffffff76543210),%g1
        nop
+       sethi %h34(foo+0xa9876543210),%g1
+       sllx %g1, 2, %g1
+       or %g1,%l34(foo+0xa9876543210),%g1
+       nop
index d6b02a693271e9a02886d99810e0dd35464e221a..83d910559380eb34d90c9859c3f15577bd3e6af7 100644 (file)
@@ -1,3 +1,14 @@
+2012-04-12  David S. Miller  <davem@davemloft.net>
+
+       * sparc.cc (Reloc::wdisp10): New relocation method.
+       (Reloc::h34): Likewise.
+       (Target_sparc::Scan::check_non_pic): Handle R_SPARC_H34.
+       (Target_sparc::Scan::get_reference_flags): Handle R_SPARC_H34 and
+       R_SPARC_WDISP10.
+       (Target_sparc::Scan::local): Likewise.
+       (Target_sparc::Scan::global): Likewise.
+       (Target_sparc::Relocate::relocate): Likewise.
+
 2012-04-09  Cary Coutant  <ccoutant@google.com>
 
        * gdb-index.cc (Gdb_index_info_reader::record_cu_ranges): Allow
index 39c7e7ccf6fe73bdfff5519aaca5f01dc8521345..ee82367f9eb79d2327cbe4139fedfa620c966c8b 100644 (file)
@@ -617,6 +617,29 @@ public:
     elfcpp::Swap<32, true>::writeval(wv, val | reloc);
   }
 
+  // R_SPARC_WDISP10: (Symbol + Addend - Address) >> 2
+  static inline void
+  wdisp10(unsigned char* view,
+         const Sized_relobj_file<size, big_endian>* object,
+         const Symbol_value<size>* psymval,
+         typename elfcpp::Elf_types<size>::Elf_Addr addend,
+         typename elfcpp::Elf_types<size>::Elf_Addr address)
+  {
+    typedef typename elfcpp::Swap<32, true>::Valtype Valtype;
+    Valtype* wv = reinterpret_cast<Valtype*>(view);
+    Valtype val = elfcpp::Swap<32, true>::readval(wv);
+    Valtype reloc = ((psymval->value(object, addend) - address)
+                    >> 2);
+
+    // The relocation value is split between the low bits 5-12,
+    // and high bits 19-20.
+    val &= ~((0x3 << 19) | (0xff << 5));
+    reloc = (((reloc & 0x300) << (19 - 8))
+            | ((reloc & 0xff) << (5 - 0)));
+
+    elfcpp::Swap<32, true>::writeval(wv, val | reloc);
+  }
+
   // R_SPARC_PC22: (Symbol + Addend - Address) >> 10
   static inline void
   pc22(unsigned char* view,
@@ -832,6 +855,16 @@ public:
                                        addend, address);
   }
 
+  // R_SPARC_H34: (Symbol + Addend) >> 12
+  static inline void
+  h34(unsigned char* view,
+      const Sized_relobj_file<size, big_endian>* object,
+      const Symbol_value<size>* psymval,
+      typename elfcpp::Elf_types<size>::Elf_Addr  addend)
+  {
+    This_insn::template rela<32>(view, 12, 0x003fffff, object, psymval, addend);
+  }
+
   // R_SPARC_H44: (Symbol + Addend) >> 22
   static inline void
   h44(unsigned char* view,
@@ -1605,6 +1638,7 @@ Target_sparc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
     case elfcpp::R_SPARC_64:
     case elfcpp::R_SPARC_HIX22:
     case elfcpp::R_SPARC_LOX10:
+    case elfcpp::R_SPARC_H34:
     case elfcpp::R_SPARC_H44:
     case elfcpp::R_SPARC_M44:
     case elfcpp::R_SPARC_L44:
@@ -1639,6 +1673,7 @@ Target_sparc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
     case elfcpp::R_SPARC_WDISP22:
     case elfcpp::R_SPARC_WDISP19:
     case elfcpp::R_SPARC_WDISP16:
+    case elfcpp::R_SPARC_WDISP10:
       return Symbol::RELATIVE_REF;
 
     case elfcpp::R_SPARC_PLT64:
@@ -1755,6 +1790,7 @@ Target_sparc<size, big_endian>::Scan::check_non_pic(Relobj* object, unsigned int
        case elfcpp::R_SPARC_LO10:
        case elfcpp::R_SPARC_HI22:
        case elfcpp::R_SPARC_OLO10:
+       case elfcpp::R_SPARC_H34:
        case elfcpp::R_SPARC_H44:
        case elfcpp::R_SPARC_M44:
        case elfcpp::R_SPARC_L44:
@@ -1861,6 +1897,7 @@ Target_sparc<size, big_endian>::Scan::local(
 
     case elfcpp::R_SPARC_HIX22:
     case elfcpp::R_SPARC_LOX10:
+    case elfcpp::R_SPARC_H34:
     case elfcpp::R_SPARC_H44:
     case elfcpp::R_SPARC_M44:
     case elfcpp::R_SPARC_L44:
@@ -1911,6 +1948,7 @@ Target_sparc<size, big_endian>::Scan::local(
     case elfcpp::R_SPARC_WDISP22:
     case elfcpp::R_SPARC_WDISP19:
     case elfcpp::R_SPARC_WDISP16:
+    case elfcpp::R_SPARC_WDISP10:
     case elfcpp::R_SPARC_DISP8:
     case elfcpp::R_SPARC_DISP16:
     case elfcpp::R_SPARC_DISP32:
@@ -2186,6 +2224,7 @@ Target_sparc<size, big_endian>::Scan::global(
     case elfcpp::R_SPARC_WDISP22:
     case elfcpp::R_SPARC_WDISP19:
     case elfcpp::R_SPARC_WDISP16:
+    case elfcpp::R_SPARC_WDISP10:
       {
        if (gsym->needs_plt_entry())
          target->make_plt_entry(symtab, layout, gsym);
@@ -2214,6 +2253,7 @@ Target_sparc<size, big_endian>::Scan::global(
     case elfcpp::R_SPARC_64:
     case elfcpp::R_SPARC_HIX22:
     case elfcpp::R_SPARC_LOX10:
+    case elfcpp::R_SPARC_H34:
     case elfcpp::R_SPARC_H44:
     case elfcpp::R_SPARC_M44:
     case elfcpp::R_SPARC_L44:
@@ -2749,6 +2789,10 @@ Target_sparc<size, big_endian>::Relocate::relocate(
       Reloc::wdisp16(view, object, psymval, addend, address);
       break;
 
+    case elfcpp::R_SPARC_WDISP10:
+      Reloc::wdisp10(view, object, psymval, addend, address);
+      break;
+
     case elfcpp::R_SPARC_HI22:
       Reloc::hi22(view, object, psymval, addend);
       break;
@@ -2900,6 +2944,10 @@ Target_sparc<size, big_endian>::Relocate::relocate(
       Reloc::lox10(view, object, psymval, addend);
       break;
 
+    case elfcpp::R_SPARC_H34:
+      Reloc::h34(view, object, psymval, addend);
+      break;
+
     case elfcpp::R_SPARC_H44:
       Reloc::h44(view, object, psymval, addend);
       break;
index e14f707b5e6f972b4e8d6dc221734cdf08389c59..b1ff61c35620fe80453b723f68ac7fdd9d8a0eef 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-12  David S. Miller  <davem@davemloft.net>
+
+       * elf/sparc.h (R_SPARC_WDISP10): New reloc.
+       * opcode/sparc.h: Define '=' as generating R_SPARC_WDISP10.
+
 2012-04-10  Tristan Gingold  <gingold@adacore.com>
 
        * splay-tree.h: Conditionnaly includes stdint.h and inttypes.h
index fc8a765a60825d0e0e765ae1fcb885e83cececfc..880ead652538a1cefcc98bde74602b9ebab74605 100644 (file)
@@ -162,6 +162,7 @@ START_RELOC_NUMBERS (elf_sparc_reloc_type)
   RELOC_NUMBER (R_SPARC_H34, 85)
   RELOC_NUMBER (R_SPARC_SIZE32, 86)
   RELOC_NUMBER (R_SPARC_SIZE64, 87)
+  RELOC_NUMBER (R_SPARC_WDISP10, 88)
   
   EMPTY_RELOC  (R_SPARC_max_std)
 
index 7ae3641cfc48407ead17a0ba89a4c3dc56880d6d..91dc696641ba4245838e073b517e4dfcd11b917c 100644 (file)
@@ -208,7 +208,8 @@ typedef struct sparc_opcode
        0       32/64 bit immediate for set or setx (v9) insns
        _       Ancillary state register in rd (v9a)
        /       Ancillary state register in rs1 (v9a)
-       (       entire floating point state register (%efsr).  */
+       (       entire floating point state register (%efsr)
+       =       2+8 bit PC relative immediate. (v9)  */
 
 #define OP2(x)         (((x) & 0x7) << 22)  /* Op2 field of format2 insns.  */
 #define OP3(x)         (((x) & 0x3f) << 19) /* Op3 field of format3 insns.  */
index 0dec560ca4ea19c23e5d5f57b0e4639b381cdc8c..a65052d60d9ffb0b2ecf524d7d2b54171bd6baea 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-12  David S. Miller  <davem@davemloft.net>
+
+       * sparc-dis.c (X_DISP10): Define.
+       (print_insn_sparc): Handle '='.
+
 2012-04-01  Mike Frysinger  <vapier@gentoo.org>
 
        * bfin-dis.c (fmtconst): Replace decimal handling with a single
index b7f0cc2ace2270698914de616ffba3cb232ef6b3..7857e4ca2b27218706d4bfe49844f470eb51c891 100644 (file)
@@ -129,6 +129,7 @@ static char *v9a_asr_reg_names[] =
 
 /* These are for v9.  */
 #define X_DISP16(i)  (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
+#define X_DISP10(i)  (((((i) >> 19) & 3) << 8) | (((i) >> 5) & 0xff))
 #define X_DISP19(i)  (((i) >> 0) & 0x7ffff)
 #define X_MEMBAR(i)  ((i) & 0x7f)
 
@@ -743,6 +744,11 @@ print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
                      break;
                    }
 
+                 case '=':
+                   info->target = memaddr + SEX (X_DISP10 (insn), 10) * 4;
+                   (*info->print_address_func) (info->target, info);
+                   break;
+
                  case 'k':
                    info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
                    (*info->print_address_func) (info->target, info);