Index: bfd/elfxx-sparc.c |
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c |
index fe18a62cc99a87f45acdf5f80b3eace521367396..e14afaf970fa2b1ea58b3dceb04048c824caca30 100644 |
--- a/bfd/elfxx-sparc.c |
+++ b/bfd/elfxx-sparc.c |
@@ -1,5 +1,5 @@ |
/* SPARC-specific support for ELF |
- Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
+ Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 |
Free Software Foundation, Inc. |
This file is part of BFD, the Binary File Descriptor library. |
@@ -53,7 +53,7 @@ |
static bfd_reloc_status_type |
init_insn_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, |
- PTR data, asection *input_section, bfd *output_bfd, |
+ void * data, asection *input_section, bfd *output_bfd, |
bfd_vma *prelocation, bfd_vma *pinsn) |
{ |
bfd_vma relocation; |
@@ -97,7 +97,7 @@ static bfd_reloc_status_type |
sparc_elf_notsup_reloc (bfd *abfd ATTRIBUTE_UNUSED, |
arelent *reloc_entry ATTRIBUTE_UNUSED, |
asymbol *symbol ATTRIBUTE_UNUSED, |
- PTR data ATTRIBUTE_UNUSED, |
+ void * data ATTRIBUTE_UNUSED, |
asection *input_section ATTRIBUTE_UNUSED, |
bfd *output_bfd ATTRIBUTE_UNUSED, |
char **error_message ATTRIBUTE_UNUSED) |
@@ -109,7 +109,7 @@ sparc_elf_notsup_reloc (bfd *abfd ATTRIBUTE_UNUSED, |
static bfd_reloc_status_type |
sparc_elf_wdisp16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, |
- PTR data, asection *input_section, bfd *output_bfd, |
+ void * data, asection *input_section, bfd *output_bfd, |
char **error_message ATTRIBUTE_UNUSED) |
{ |
bfd_vma relocation; |
@@ -132,11 +132,39 @@ 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, |
+ void * 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 |
sparc_elf_hix22_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, |
- PTR data, asection *input_section, bfd *output_bfd, |
+ void * data, asection *input_section, bfd *output_bfd, |
char **error_message ATTRIBUTE_UNUSED) |
{ |
bfd_vma relocation; |
@@ -162,7 +190,7 @@ sparc_elf_hix22_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, |
static bfd_reloc_status_type |
sparc_elf_lox10_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, |
- PTR data, asection *input_section, bfd *output_bfd, |
+ void * data, asection *input_section, bfd *output_bfd, |
char **error_message ATTRIBUTE_UNUSED) |
{ |
bfd_vma relocation; |
@@ -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; |
@@ -1163,9 +1207,9 @@ _bfd_sparc_elf_create_dynamic_sections (bfd *dynobj, |
if (!_bfd_elf_create_dynamic_sections (dynobj, info)) |
return FALSE; |
- htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); |
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss"); |
if (!info->shared) |
- htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss"); |
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss"); |
if (htab->is_vxworks) |
{ |
@@ -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; |
@@ -2114,13 +2162,6 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, |
return TRUE; |
} |
- if (h->size == 0) |
- { |
- (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"), |
- h->root.root.string); |
- return TRUE; |
- } |
- |
/* We must allocate the symbol in our .dynbss section, which will |
become part of the .bss section of the executable. There will be |
an entry for this symbol in the .dynsym section. The dynamic |
@@ -2135,7 +2176,7 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, |
to copy the initial value out of the dynamic object and into the |
runtime process image. We need to remember the offset into the |
.rel.bss section we are going to use. */ |
- if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) |
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) |
{ |
htab->srelbss->size += SPARC_ELF_RELA_BYTES (htab); |
h->needs_copy = 1; |
@@ -2150,7 +2191,7 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, |
dynamic relocs. */ |
static bfd_boolean |
-allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf) |
+allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) |
{ |
struct bfd_link_info *info; |
struct _bfd_sparc_elf_link_hash_table *htab; |
@@ -2430,7 +2471,7 @@ allocate_local_dynrelocs (void **slot, void *inf) |
/* Find any dynamic relocs that apply to read-only sections. */ |
static bfd_boolean |
-readonly_dynrelocs (struct elf_link_hash_entry *h, PTR inf) |
+readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) |
{ |
struct _bfd_sparc_elf_link_hash_entry *eh; |
struct _bfd_sparc_elf_dyn_relocs *p; |
@@ -2491,7 +2532,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd, |
/* Set the contents of the .interp section to the interpreter. */ |
if (info->executable) |
{ |
- s = bfd_get_section_by_name (dynobj, ".interp"); |
+ s = bfd_get_linker_section (dynobj, ".interp"); |
BFD_ASSERT (s != NULL); |
s->size = htab->dynamic_interpreter_size; |
s->contents = (unsigned char *) htab->dynamic_interpreter; |
@@ -2586,7 +2627,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd, |
/* Allocate global sym .plt and .got entries, and space for global |
sym dynamic relocs. */ |
- elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); |
+ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info); |
/* Allocate .plt and .got entries, and space for local symbols. */ |
htab_traverse (htab->loc_hash_table, allocate_local_dynrelocs, info); |
@@ -2701,8 +2742,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd, |
/* If any dynamic relocs apply to a read-only section, |
then we need a DT_TEXTREL entry. */ |
if ((info->flags & DF_TEXTREL) == 0) |
- elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, |
- (PTR) info); |
+ elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info); |
if (info->flags & DF_TEXTREL) |
{ |
@@ -2970,9 +3010,9 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, |
} |
} |
- if (sec != NULL && elf_discarded_section (sec)) |
+ if (sec != NULL && discarded_section (sec)) |
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, |
- rel, relend, howto, contents); |
+ rel, 1, relend, howto, 0, contents); |
if (info->relocatable) |
continue; |
@@ -3283,6 +3323,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: |
@@ -3307,6 +3348,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 |
@@ -3878,6 +3920,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; |
@@ -4069,7 +4130,9 @@ do_relocation: |
We don't, but this breaks stabs debugging info, whose |
relocations are only 32-bits wide. Ignore overflows in |
this case and also for discarded entries. */ |
- if ((r_type == R_SPARC_32 || r_type == R_SPARC_DISP32) |
+ if ((r_type == R_SPARC_32 |
+ || r_type == R_SPARC_UA32 |
+ || r_type == R_SPARC_DISP32) |
&& (((input_section->flags & SEC_DEBUGGING) != 0 |
&& strcmp (bfd_section_name (input_bfd, |
input_section), |
@@ -4432,8 +4495,8 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd, |
/* This symbols needs a copy reloc. Set it up. */ |
BFD_ASSERT (h->dynindx != -1); |
- s = bfd_get_section_by_name (h->root.u.def.section->owner, |
- ".rela.bss"); |
+ s = bfd_get_linker_section (h->root.u.def.section->owner, |
+ ".rela.bss"); |
BFD_ASSERT (s != NULL); |
rela.r_offset = (h->root.u.def.value |
@@ -4672,13 +4735,13 @@ _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *i |
BFD_ASSERT (htab != NULL); |
dynobj = htab->elf.dynobj; |
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); |
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic"); |
if (elf_hash_table (info)->dynamic_sections_created) |
{ |
asection *splt; |
- splt = bfd_get_section_by_name (dynobj, ".plt"); |
+ splt = htab->elf.splt; |
BFD_ASSERT (splt != NULL && sdyn != NULL); |
if (!sparc_finish_dyn (output_bfd, info, dynobj, sdyn, splt)) |