diff options
Diffstat (limited to 'bfd/elfxx-sparc.c')
-rw-r--r-- | bfd/elfxx-sparc.c | 69 |
1 files changed, 69 insertions, 0 deletions
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; |