diff options
author | David S. Miller <davem@redhat.com> | 2012-04-12 16:26:06 +0000 |
---|---|---|
committer | David S. Miller <davem@redhat.com> | 2012-04-12 16:26:06 +0000 |
commit | 2615994e91176ae1a147439f81c452e5f5965920 (patch) | |
tree | 39fad336d6e5c3c564bd15e377256d88b737447c | |
parent | 214d508ee1d179d6c9e0e993d68628a0bc477124 (diff) | |
download | gdb-2615994e91176ae1a147439f81c452e5f5965920.zip gdb-2615994e91176ae1a147439f81c452e5f5965920.tar.gz gdb-2615994e91176ae1a147439f81c452e5f5965920.tar.bz2 |
Support R_SPARC_WDISP10 and R_SPARC_H34.
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.
-rw-r--r-- | bfd/ChangeLog | 14 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 4 | ||||
-rw-r--r-- | bfd/elfxx-sparc.c | 69 | ||||
-rw-r--r-- | bfd/libbfd.h | 4 | ||||
-rw-r--r-- | bfd/reloc.c | 8 | ||||
-rw-r--r-- | elfcpp/ChangeLog | 4 | ||||
-rw-r--r-- | elfcpp/sparc.h | 1 | ||||
-rw-r--r-- | gas/ChangeLog | 7 | ||||
-rw-r--r-- | gas/config/tc-sparc.c | 36 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/reloc64.d | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/sparc/reloc64.s | 4 | ||||
-rw-r--r-- | gold/ChangeLog | 11 | ||||
-rw-r--r-- | gold/sparc.cc | 48 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/elf/sparc.h | 1 | ||||
-rw-r--r-- | include/opcode/sparc.h | 3 | ||||
-rw-r--r-- | opcodes/ChangeLog | 5 | ||||
-rw-r--r-- | opcodes/sparc-dis.c | 6 |
19 files changed, 240 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f53dcfda..6eea52d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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): diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 07898be..859f825 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -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, diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 9155311c..9609d37 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -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 @@ -3871,6 +3921,25 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, 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), + relocation); + } else if (r_type == R_SPARC_REV32) { bfd_vma x; diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 844d3a7..cc293bc 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -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", diff --git a/bfd/reloc.c b/bfd/reloc.c index fb3aab2..aed3612 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -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 diff --git a/elfcpp/ChangeLog b/elfcpp/ChangeLog index f606faa..3a76401 100644 --- a/elfcpp/ChangeLog +++ b/elfcpp/ChangeLog @@ -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. diff --git a/elfcpp/sparc.h b/elfcpp/sparc.h index 6a9193b..77c4668 100644 --- a/elfcpp/sparc.h +++ b/elfcpp/sparc.h @@ -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 diff --git a/gas/ChangeLog b/gas/ChangeLog index 6a9191e..0149bd0 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index f453733..1956dff 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -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) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 8ad1605..79af626 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -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 diff --git a/gas/testsuite/gas/sparc/reloc64.d b/gas/testsuite/gas/sparc/reloc64.d index da40d0c..07e2a10 100644 --- a/gas/testsuite/gas/sparc/reloc64.d +++ b/gas/testsuite/gas/sparc/reloc64.d @@ -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 diff --git a/gas/testsuite/gas/sparc/reloc64.s b/gas/testsuite/gas/sparc/reloc64.s index 9ead6af..534a0ae 100644 --- a/gas/testsuite/gas/sparc/reloc64.s +++ b/gas/testsuite/gas/sparc/reloc64.s @@ -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 diff --git a/gold/ChangeLog b/gold/ChangeLog index d6b02a6..83d9105 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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 diff --git a/gold/sparc.cc b/gold/sparc.cc index 39c7e7c..ee82367 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -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; diff --git a/include/ChangeLog b/include/ChangeLog index e14f707..b1ff61c 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -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 diff --git a/include/elf/sparc.h b/include/elf/sparc.h index fc8a765..880ead6 100644 --- a/include/elf/sparc.h +++ b/include/elf/sparc.h @@ -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) diff --git a/include/opcode/sparc.h b/include/opcode/sparc.h index 7ae3641..91dc696 100644 --- a/include/opcode/sparc.h +++ b/include/opcode/sparc.h @@ -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. */ diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 0dec560..a65052d 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -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 diff --git a/opcodes/sparc-dis.c b/opcodes/sparc-dis.c index b7f0cc2..7857e4c 100644 --- a/opcodes/sparc-dis.c +++ b/opcodes/sparc-dis.c @@ -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); |