This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]