summaryrefslogtreecommitdiff
path: root/bfd/elfxx-sparc.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@redhat.com>2012-04-12 16:25:54 +0000
committerDavid S. Miller <davem@redhat.com>2012-04-12 16:25:54 +0000
commit3e2f8274eeadd6bb0fcf5a8ae6e7aa186ded9f3b (patch)
tree37d707983a28515e75c4b881a54ef01ea7ece6ef /bfd/elfxx-sparc.c
parent240e638daccdcaa70f612e63a60a277188e2b37f (diff)
downloadbinutils-redhat-3e2f8274eeadd6bb0fcf5a8ae6e7aa186ded9f3b.tar.gz
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.
Diffstat (limited to 'bfd/elfxx-sparc.c')
-rw-r--r--bfd/elfxx-sparc.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 9155311c38..9609d3715b 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;