This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] Fix objdump output of R_SPARC_OLO10
From: David Miller <davem@davemloft.net>
Date: Fri, 21 Jan 2011 16:08:31 -0800 (PST)
> From: Hans-Peter Nilsson <hp@bitrange.com>
> Date: Fri, 21 Jan 2011 04:19:01 -0500 (EST)
>
>> On Fri, 21 Jan 2011, Alan Modra wrote:
>>> On Thu, Jan 20, 2011 at 11:50:11PM -0800, David Miller wrote:
>>> > 466 lines of code deleted from the tree as a result.
>>>
>>> And a 20% blowout in reloc size. I can't say I like that. Well, to
>>> be fair, this really only matters in the linker and not all backend
>>> linkers use arelent to handle relocs. Still, many do, even some ELF
>>> linkers.
>>
>> Solvable by selecting it with a want_arelent2 like the want64 in
>> config.bfd for 64-bit bfd_vma?
>
> That is one possible way to handle this.
Ok, I just tossed the following together, have a look.
bfd/
2011-01-20 David S. Miller <davem@sunset.davemloft.net>
* configure.in (want_addend2): New variable, set
for 64-bit sparc ELF configurations.
(have_addend2): Set to 1 or 0 based upon want_addend2,
substitute into headers.
* configure: Rebuild.
* bfd-in.h (BFD_HAVE_ADDEND2): New.
* reloc.c (arelent): Add addend2 member if BFD_HAVE_ADDEND2.
* bfd-in2.h: Rebuild.
* elf64-sparc.c (MINUS_ONE): Delete.
(elf64_sparc_get_reloc_upper_bound,
elf64_sparc_get_dynamic_reloc_upper_bound,
elf64_sparc_slurp_one_reloc_table,
elf64_sparc_slurp_reloc_table,
elf64_sparc_canonicalize_reloc,
elf64_sparc_canonicalize_dynamic_reloc,
elf64_sparc_write_relocs,
elf64_sparc_size_info): Delete.
(bfd_elf64_get_reloc_upper_bound,
bfd_elf64_get_dynamic_reloc_upper_bound,
bfd_elf64_canonicalize_reloc,
bfd_elf64_canonicalize_dynamic_reloc,
elf_backend_size_info): No longer override.
* elfcode.h (elf_write_relocs): Encode addend2 into r_info.
* elfxx-sparc.c (_bf_sparc_elf_howto_table): Make R_SPARC_OLO10 use
complain_overflow_dont and bfd_elf_generic_reloc.
(_bfd_sparc_elf_info_to_howto): Remember addend2 value if
BFD_HAVE_ADDEND2.
binutils/
* objdump.c (disassemble_bytes): Report addend2 if BFD_HAVE_ADDEND2.
(dump_reloc_set): Likewise.
gas/
* config/tc-sparc.h (RELOC_EXPANSION_POSSIBLE,
MAX_RELOC_EXPANSION): Do not define.
* config/tc-sparc.c (tc_gen_reloc): Return "arelent *", do not
treat BFD_RELOC_SPARC_OLO10 specially except to record addend2
when BFD_HAVE_ADDEND2.
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 63fcdc9..aeea1e7 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -65,6 +65,7 @@ extern "C" {
#define LITMEMCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2) - 1)
#define LITSTRCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2))
+#define BFD_HAVE_ADDEND2 @have_addend2@
#define BFD_SUPPORTS_PLUGINS @supports_plugins@
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 84fc75d..bc24425 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -72,6 +72,7 @@ extern "C" {
#define LITMEMCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2) - 1)
#define LITSTRCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2))
+#define BFD_HAVE_ADDEND2 @have_addend2@
#define BFD_SUPPORTS_PLUGINS @supports_plugins@
@@ -2218,7 +2219,10 @@ typedef struct reloc_cache_entry
/* addend for relocation value. */
bfd_vma addend;
-
+#if BFD_HAVE_ADDEND2
+ /* second addend for relocation value. */
+ bfd_vma addend2;
+#endif
/* Pointer to how to perform the required relocation. */
reloc_howto_type *howto;
diff --git a/bfd/configure b/bfd/configure
index 5085580..f38b0bc 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -606,6 +606,7 @@ havevecs
tdefaults
bfd_ufile_ptr
bfd_file_ptr
+have_addend2
supports_plugins
bfd_default_target_size
bfd_machines
@@ -12321,6 +12322,7 @@ fi
host64=false
target64=false
bfd_default_target_size=32
+want_addend2=false
# host stuff:
@@ -15188,9 +15190,9 @@ do
bfd_elf64_sh64blin_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_sh64lnbsd_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_sh64nbsd_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
- bfd_elf64_sparc_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
- bfd_elf64_sparc_freebsd_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
- bfd_elf64_sparc_sol2_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
+ bfd_elf64_sparc_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64; want_addend2=true ;;
+ bfd_elf64_sparc_freebsd_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64; want_addend2=true ;;
+ bfd_elf64_sparc_sol2_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64; want_addend2=true ;;
bfd_elf64_tradbigmips_vec | bfd_elf64_tradbigmips_freebsd_vec)
tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf64_tradlittlemips_vec | bfd_elf64_tradlittlemips_freebsd_vec)
@@ -15432,7 +15434,11 @@ esac
-
+if test "$want_addend2" = "true"; then
+ have_addend2=1
+else
+ have_addend2=0
+fi
if test "$plugins" = "yes"; then
supports_plugins=1
diff --git a/bfd/configure.in b/bfd/configure.in
index 5908a57..fcd2fa9 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -129,6 +129,7 @@ AC_EXEEXT
host64=false
target64=false
bfd_default_target_size=32
+want_addend2=false
# host stuff:
@@ -823,9 +824,9 @@ do
bfd_elf64_sh64blin_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_sh64lnbsd_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_sh64nbsd_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
- bfd_elf64_sparc_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
- bfd_elf64_sparc_freebsd_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
- bfd_elf64_sparc_sol2_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
+ bfd_elf64_sparc_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64; want_addend2=true ;;
+ bfd_elf64_sparc_freebsd_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64; want_addend2=true ;;
+ bfd_elf64_sparc_sol2_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64; want_addend2=true ;;
bfd_elf64_tradbigmips_vec | bfd_elf64_tradbigmips_freebsd_vec)
tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf64_tradlittlemips_vec | bfd_elf64_tradlittlemips_freebsd_vec)
@@ -1055,6 +1056,13 @@ AC_SUBST(bfd_backends)
AC_SUBST(bfd_machines)
AC_SUBST(bfd_default_target_size)
+if test "$want_addend2" = "true"; then
+ have_addend2=1
+else
+ have_addend2=0
+fi
+AC_SUBST(have_addend2)
+
if test "$plugins" = "yes"; then
supports_plugins=1
else
diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c
index 9f05b85..7483360 100644
--- a/bfd/elf64-sparc.c
+++ b/bfd/elf64-sparc.c
@@ -27,392 +27,6 @@
#include "opcode/sparc.h"
#include "elfxx-sparc.h"
-/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
-#define MINUS_ONE (~ (bfd_vma) 0)
-
-/* Due to the way how we handle R_SPARC_OLO10, each entry in a SHT_RELA
- section can represent up to two relocs, we must tell the user to allocate
- more space. */
-
-static long
-elf64_sparc_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
-{
- return (sec->reloc_count * 2 + 1) * sizeof (arelent *);
-}
-
-static long
-elf64_sparc_get_dynamic_reloc_upper_bound (bfd *abfd)
-{
- return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 2;
-}
-
-/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
- them. We cannot use generic elf routines for this, because R_SPARC_OLO10
- has secondary addend in ELF64_R_TYPE_DATA. We handle it as two relocations
- for the same location, R_SPARC_LO10 and R_SPARC_13. */
-
-static bfd_boolean
-elf64_sparc_slurp_one_reloc_table (bfd *abfd, asection *asect,
- Elf_Internal_Shdr *rel_hdr,
- asymbol **symbols, bfd_boolean dynamic)
-{
- PTR allocated = NULL;
- bfd_byte *native_relocs;
- arelent *relent;
- unsigned int i;
- int entsize;
- bfd_size_type count;
- arelent *relents;
-
- allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
- if (allocated == NULL)
- goto error_return;
-
- if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size)
- goto error_return;
-
- native_relocs = (bfd_byte *) allocated;
-
- relents = asect->relocation + canon_reloc_count (asect);
-
- entsize = rel_hdr->sh_entsize;
- BFD_ASSERT (entsize == sizeof (Elf64_External_Rela));
-
- count = rel_hdr->sh_size / entsize;
-
- for (i = 0, relent = relents; i < count;
- i++, relent++, native_relocs += entsize)
- {
- Elf_Internal_Rela rela;
- unsigned int r_type;
-
- bfd_elf64_swap_reloca_in (abfd, native_relocs, &rela);
-
- /* The address of an ELF reloc is section relative for an object
- file, and absolute for an executable file or shared library.
- The address of a normal BFD reloc is always section relative,
- and the address of a dynamic reloc is absolute.. */
- if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
- relent->address = rela.r_offset;
- else
- relent->address = rela.r_offset - asect->vma;
-
- if (ELF64_R_SYM (rela.r_info) == STN_UNDEF)
- relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
- else
- {
- asymbol **ps, *s;
-
- ps = symbols + ELF64_R_SYM (rela.r_info) - 1;
- s = *ps;
-
- /* Canonicalize ELF section symbols. FIXME: Why? */
- if ((s->flags & BSF_SECTION_SYM) == 0)
- relent->sym_ptr_ptr = ps;
- else
- relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
- }
-
- relent->addend = rela.r_addend;
-
- r_type = ELF64_R_TYPE_ID (rela.r_info);
- if (r_type == R_SPARC_OLO10)
- {
- relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_LO10);
- relent[1].address = relent->address;
- relent++;
- relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
- relent->addend = ELF64_R_TYPE_DATA (rela.r_info);
- relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_13);
- }
- else
- relent->howto = _bfd_sparc_elf_info_to_howto_ptr (r_type);
- }
-
- canon_reloc_count (asect) += relent - relents;
-
- if (allocated != NULL)
- free (allocated);
-
- return TRUE;
-
- error_return:
- if (allocated != NULL)
- free (allocated);
- return FALSE;
-}
-
-/* Read in and swap the external relocs. */
-
-static bfd_boolean
-elf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
- asymbol **symbols, bfd_boolean dynamic)
-{
- struct bfd_elf_section_data * const d = elf_section_data (asect);
- Elf_Internal_Shdr *rel_hdr;
- Elf_Internal_Shdr *rel_hdr2;
- bfd_size_type amt;
-
- if (asect->relocation != NULL)
- return TRUE;
-
- if (! dynamic)
- {
- if ((asect->flags & SEC_RELOC) == 0
- || asect->reloc_count == 0)
- return TRUE;
-
- rel_hdr = d->rel.hdr;
- rel_hdr2 = d->rela.hdr;
-
- BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
- || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
- }
- else
- {
- /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
- case because relocations against this section may use the
- dynamic symbol table, and in that case bfd_section_from_shdr
- in elf.c does not update the RELOC_COUNT. */
- if (asect->size == 0)
- return TRUE;
-
- rel_hdr = &d->this_hdr;
- asect->reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
- rel_hdr2 = NULL;
- }
-
- amt = asect->reloc_count;
- amt *= 2 * sizeof (arelent);
- asect->relocation = (arelent *) bfd_alloc (abfd, amt);
- if (asect->relocation == NULL)
- return FALSE;
-
- /* The elf64_sparc_slurp_one_reloc_table routine increments
- canon_reloc_count. */
- canon_reloc_count (asect) = 0;
-
- if (rel_hdr
- && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
- dynamic))
- return FALSE;
-
- if (rel_hdr2
- && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr2, symbols,
- dynamic))
- return FALSE;
-
- return TRUE;
-}
-
-/* Canonicalize the relocs. */
-
-static long
-elf64_sparc_canonicalize_reloc (bfd *abfd, sec_ptr section,
- arelent **relptr, asymbol **symbols)
-{
- arelent *tblptr;
- unsigned int i;
- const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-
- if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
- return -1;
-
- tblptr = section->relocation;
- for (i = 0; i < canon_reloc_count (section); i++)
- *relptr++ = tblptr++;
-
- *relptr = NULL;
-
- return canon_reloc_count (section);
-}
-
-
-/* Canonicalize the dynamic relocation entries. Note that we return
- the dynamic relocations as a single block, although they are
- actually associated with particular sections; the interface, which
- was designed for SunOS style shared libraries, expects that there
- is only one set of dynamic relocs. Any section that was actually
- installed in the BFD, and has type SHT_REL or SHT_RELA, and uses
- the dynamic symbol table, is considered to be a dynamic reloc
- section. */
-
-static long
-elf64_sparc_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
- asymbol **syms)
-{
- asection *s;
- long ret;
-
- if (elf_dynsymtab (abfd) == 0)
- {
- bfd_set_error (bfd_error_invalid_operation);
- return -1;
- }
-
- ret = 0;
- for (s = abfd->sections; s != NULL; s = s->next)
- {
- if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
- && (elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
- {
- arelent *p;
- long count, i;
-
- if (! elf64_sparc_slurp_reloc_table (abfd, s, syms, TRUE))
- return -1;
- count = canon_reloc_count (s);
- p = s->relocation;
- for (i = 0; i < count; i++)
- *storage++ = p++;
- ret += count;
- }
- }
-
- *storage = NULL;
-
- return ret;
-}
-
-/* Write out the relocs. */
-
-static void
-elf64_sparc_write_relocs (bfd *abfd, asection *sec, PTR data)
-{
- bfd_boolean *failedp = (bfd_boolean *) data;
- Elf_Internal_Shdr *rela_hdr;
- bfd_vma addr_offset;
- Elf64_External_Rela *outbound_relocas, *src_rela;
- unsigned int idx, count;
- asymbol *last_sym = 0;
- int last_sym_idx = 0;
-
- /* If we have already failed, don't do anything. */
- if (*failedp)
- return;
-
- if ((sec->flags & SEC_RELOC) == 0)
- return;
-
- /* The linker backend writes the relocs out itself, and sets the
- reloc_count field to zero to inhibit writing them here. Also,
- sometimes the SEC_RELOC flag gets set even when there aren't any
- relocs. */
- if (sec->reloc_count == 0)
- return;
-
- /* We can combine two relocs that refer to the same address
- into R_SPARC_OLO10 if first one is R_SPARC_LO10 and the
- latter is R_SPARC_13 with no associated symbol. */
- count = 0;
- for (idx = 0; idx < sec->reloc_count; idx++)
- {
- bfd_vma addr;
-
- ++count;
-
- addr = sec->orelocation[idx]->address;
- if (sec->orelocation[idx]->howto->type == R_SPARC_LO10
- && idx < sec->reloc_count - 1)
- {
- arelent *r = sec->orelocation[idx + 1];
-
- if (r->howto->type == R_SPARC_13
- && r->address == addr
- && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
- && (*r->sym_ptr_ptr)->value == 0)
- ++idx;
- }
- }
-
- rela_hdr = elf_section_data (sec)->rela.hdr;
-
- rela_hdr->sh_size = rela_hdr->sh_entsize * count;
- rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
- if (rela_hdr->contents == NULL)
- {
- *failedp = TRUE;
- return;
- }
-
- /* Figure out whether the relocations are RELA or REL relocations. */
- if (rela_hdr->sh_type != SHT_RELA)
- abort ();
-
- /* The address of an ELF reloc is section relative for an object
- file, and absolute for an executable file or shared library.
- The address of a BFD reloc is always section relative. */
- addr_offset = 0;
- if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
- addr_offset = sec->vma;
-
- /* orelocation has the data, reloc_count has the count... */
- outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
- src_rela = outbound_relocas;
-
- for (idx = 0; idx < sec->reloc_count; idx++)
- {
- Elf_Internal_Rela dst_rela;
- arelent *ptr;
- asymbol *sym;
- int n;
-
- ptr = sec->orelocation[idx];
- sym = *ptr->sym_ptr_ptr;
- if (sym == last_sym)
- n = last_sym_idx;
- else if (bfd_is_abs_section (sym->section) && sym->value == 0)
- n = STN_UNDEF;
- else
- {
- last_sym = sym;
- n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
- if (n < 0)
- {
- *failedp = TRUE;
- return;
- }
- last_sym_idx = n;
- }
-
- if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
- && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
- && ! _bfd_elf_validate_reloc (abfd, ptr))
- {
- *failedp = TRUE;
- return;
- }
-
- if (ptr->howto->type == R_SPARC_LO10
- && idx < sec->reloc_count - 1)
- {
- arelent *r = sec->orelocation[idx + 1];
-
- if (r->howto->type == R_SPARC_13
- && r->address == ptr->address
- && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
- && (*r->sym_ptr_ptr)->value == 0)
- {
- idx++;
- dst_rela.r_info
- = ELF64_R_INFO (n, ELF64_R_TYPE_INFO (r->addend,
- R_SPARC_OLO10));
- }
- else
- dst_rela.r_info = ELF64_R_INFO (n, R_SPARC_LO10);
- }
- else
- dst_rela.r_info = ELF64_R_INFO (n, ptr->howto->type);
-
- dst_rela.r_offset = ptr->address + addr_offset;
- dst_rela.r_addend = ptr->addend;
-
- bfd_elf64_swap_reloca_out (abfd, &dst_rela, (bfd_byte *) src_rela);
- ++src_rela;
- }
-}
-
/* Hook called by the linker routine which adds symbols from an object
file. We use it for STT_REGISTER symbols. */
@@ -777,47 +391,6 @@ elf64_sparc_reloc_type_class (const Elf_Internal_Rela *rela)
}
}
-/* Relocations in the 64 bit SPARC ELF ABI are more complex than in
- standard ELF, because R_SPARC_OLO10 has secondary addend in
- ELF64_R_TYPE_DATA field. This structure is used to redirect the
- relocation handling routines. */
-
-const struct elf_size_info elf64_sparc_size_info =
-{
- sizeof (Elf64_External_Ehdr),
- sizeof (Elf64_External_Phdr),
- sizeof (Elf64_External_Shdr),
- sizeof (Elf64_External_Rel),
- sizeof (Elf64_External_Rela),
- sizeof (Elf64_External_Sym),
- sizeof (Elf64_External_Dyn),
- sizeof (Elf_External_Note),
- 4, /* hash-table entry size. */
- /* Internal relocations per external relocations.
- For link purposes we use just 1 internal per
- 1 external, for assembly and slurp symbol table
- we use 2. */
- 1,
- 64, /* arch_size. */
- 3, /* log_file_align. */
- ELFCLASS64,
- EV_CURRENT,
- bfd_elf64_write_out_phdrs,
- bfd_elf64_write_shdrs_and_ehdr,
- bfd_elf64_checksum_contents,
- elf64_sparc_write_relocs,
- bfd_elf64_swap_symbol_in,
- bfd_elf64_swap_symbol_out,
- elf64_sparc_slurp_reloc_table,
- bfd_elf64_slurp_symbol_table,
- bfd_elf64_swap_dyn_in,
- bfd_elf64_swap_dyn_out,
- bfd_elf64_swap_reloc_in,
- bfd_elf64_swap_reloc_out,
- bfd_elf64_swap_reloca_in,
- bfd_elf64_swap_reloca_out
-};
-
#define TARGET_BIG_SYM bfd_elf64_sparc_vec
#define TARGET_BIG_NAME "elf64-sparc"
#define ELF_ARCH bfd_arch_sparc
@@ -832,14 +405,6 @@ const struct elf_size_info elf64_sparc_size_info =
#define elf_backend_reloc_type_class \
elf64_sparc_reloc_type_class
-#define bfd_elf64_get_reloc_upper_bound \
- elf64_sparc_get_reloc_upper_bound
-#define bfd_elf64_get_dynamic_reloc_upper_bound \
- elf64_sparc_get_dynamic_reloc_upper_bound
-#define bfd_elf64_canonicalize_reloc \
- elf64_sparc_canonicalize_reloc
-#define bfd_elf64_canonicalize_dynamic_reloc \
- elf64_sparc_canonicalize_dynamic_reloc
#define elf_backend_add_symbol_hook \
elf64_sparc_add_symbol_hook
#define elf_backend_get_symbol_type \
@@ -854,8 +419,6 @@ const struct elf_size_info elf64_sparc_size_info =
elf64_sparc_merge_private_bfd_data
#define elf_backend_fake_sections \
elf64_sparc_fake_sections
-#define elf_backend_size_info \
- elf64_sparc_size_info
#define elf_backend_plt_sym_val \
_bfd_sparc_elf_plt_sym_val
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 509d426..a15e536 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -1033,7 +1033,12 @@ elf_write_relocs (bfd *abfd, asection *sec, void *data)
}
src_rela.r_offset = ptr->address + addr_offset;
- src_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
+ src_rela.r_info = ELF_R_INFO (n, (ptr->howto->type
+#if BFD_HAVE_ADDEND2
+ | ((ptr->addend2 << 8)
+ & 0xffffff00)
+#endif
+ ));
src_rela.r_addend = ptr->addend;
(*swap_out) (abfd, &src_rela, dst_rela);
}
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 33b6f13..14c238a 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -214,7 +214,7 @@ static reloc_howto_type _bfd_sparc_elf_howto_table[] =
HOWTO(R_SPARC_10, 0,2,10,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_10", FALSE,0,0x000003ff,TRUE),
HOWTO(R_SPARC_11, 0,2,11,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_11", FALSE,0,0x000007ff,TRUE),
HOWTO(R_SPARC_64, 0,4,64,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_64", FALSE,0,MINUS_ONE, TRUE),
- HOWTO(R_SPARC_OLO10, 0,2,13,FALSE,0,complain_overflow_signed, sparc_elf_notsup_reloc, "R_SPARC_OLO10", FALSE,0,0x00001fff,TRUE),
+ HOWTO(R_SPARC_OLO10, 0,2,13,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_OLO10", FALSE,0,0x00001fff,TRUE),
HOWTO(R_SPARC_HH22, 42,2,22,FALSE,0,complain_overflow_unsigned,bfd_elf_generic_reloc, "R_SPARC_HH22", FALSE,0,0x003fffff,TRUE),
HOWTO(R_SPARC_HM10, 32,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", FALSE,0,0x000003ff,TRUE),
HOWTO(R_SPARC_LM22, 10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", FALSE,0,0x003fffff,TRUE),
@@ -612,6 +612,11 @@ _bfd_sparc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
unsigned int r_type = SPARC_ELF_R_TYPE (dst->r_info);
cache_ptr->howto = _bfd_sparc_elf_info_to_howto_ptr (r_type);
+#if BFD_HAVE_ADDEND2
+ if (r_type == R_SPARC_OLO10)
+ cache_ptr->addend2 = (((bfd_signed_vma) ((dst->r_info & 0xffffffff) >> 8)
+ ^ 0x800000) - 0x800000);
+#endif
}
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 719eb00..830769c 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -106,7 +106,10 @@ CODE_FRAGMENT
.
. {* addend for relocation value. *}
. bfd_vma addend;
-.
+.#if BFD_HAVE_ADDEND2
+. {* second addend for relocation value. *}
+. bfd_vma addend2;
+.#endif
. {* Pointer to how to perform the required relocation. *}
. reloc_howto_type *howto;
.
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 0be662f..18d24eb 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -1809,7 +1809,13 @@ disassemble_bytes (struct disassemble_info * inf,
printf ("+0x");
objdump_print_value (q->addend, inf, TRUE);
}
-
+#if BFD_HAVE_ADDEND2
+ if (q->addend2)
+ {
+ printf ("+0x");
+ objdump_print_value (q->addend2, inf, TRUE);
+ }
+#endif
printf ("\n");
need_nl = FALSE;
}
@@ -2904,7 +2910,13 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
printf ("+0x");
bfd_printf_vma (abfd, q->addend);
}
-
+#if BFD_HAVE_ADDEND2
+ if (q->addend2)
+ {
+ printf ("+0x");
+ bfd_printf_vma (abfd, q->addend2);
+ }
+#endif
printf ("\n");
}
}
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index a9d633d..d55b59f 100644
--- a/gas/config/tc-sparc.c
+++ b/gas/config/tc-sparc.c
@@ -3340,15 +3340,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
/* Translate internal representation of relocation info to BFD target
format. */
-arelent **
+arelent *
tc_gen_reloc (asection *section, fixS *fixp)
{
- static arelent *relocs[3];
arelent *reloc;
bfd_reloc_code_real_type code;
- relocs[0] = reloc = (arelent *) xmalloc (sizeof (arelent));
- relocs[1] = NULL;
+ reloc = (arelent *) xmalloc (sizeof (arelent));
reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
@@ -3498,18 +3496,14 @@ tc_gen_reloc (asection *section, fixS *fixp)
default: break;
}
- if (code == BFD_RELOC_SPARC_OLO10)
- reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO10);
- else
- reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
if (reloc->howto == 0)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
_("internal error: can't export reloc type %d (`%s')"),
fixp->fx_r_type, bfd_get_reloc_code_name (code));
xfree (reloc);
- relocs[0] = NULL;
- return relocs;
+ return NULL;
}
/* @@ Why fx_addnumber sometimes and fx_offset other times? */
@@ -3547,23 +3541,11 @@ tc_gen_reloc (asection *section, fixS *fixp)
else
reloc->addend = fixp->fx_offset;
#endif
-
- /* We expand R_SPARC_OLO10 to R_SPARC_LO10 and R_SPARC_13
- on the same location. */
+#if BFD_HAVE_ADDEND2
if (code == BFD_RELOC_SPARC_OLO10)
- {
- relocs[1] = reloc = (arelent *) xmalloc (sizeof (arelent));
- relocs[2] = NULL;
-
- reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
- *reloc->sym_ptr_ptr
- = symbol_get_bfdsym (section_symbol (absolute_section));
- reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
- reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_SPARC13);
- reloc->addend = fixp->tc_fix_data;
- }
-
- return relocs;
+ reloc->addend2 = fixp->tc_fix_data;
+#endif
+ return reloc;
}
/* We have no need to default values of symbols. */
diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h
index 3d4636d..4680b5d 100644
--- a/gas/config/tc-sparc.h
+++ b/gas/config/tc-sparc.h
@@ -53,9 +53,6 @@ struct frag;
extern const char *sparc_target_format (void);
#define TARGET_FORMAT sparc_target_format ()
-#define RELOC_EXPANSION_POSSIBLE
-#define MAX_RELOC_EXPANSION 2
-
/* Make it unconditional and check if -EL is valid after option parsing */
#define SPARC_BIENDIAN