bfd/
authorBernd Schmidt <bernds@codesourcery.com>
Mon, 4 Oct 2010 14:13:10 +0000 (14:13 +0000)
committerBernd Schmidt <bernds@codesourcery.com>
Mon, 4 Oct 2010 14:13:10 +0000 (14:13 +0000)
* elf-bfd.h (struct bfd_elf_section_reloc_data): New structure.
(struct bfd_elf_section_data): New members REL and RELA; delete
members REL_HDR, REL_HDR2, REL_COUNT, REL_COUNT2, REL_IDX,
REL_IDX2, REL_HASHES.
(_bfd_elf_init_reloc_shdr): Adjust declaration.
(_bfd_elf_single_rel_hdr): Declare.
(RELOC_AGAINST_DISCARDED_SECTION): Use it.
* elf.c (bfd_section_from_shdr): Adjusted to match changes in
data structures.
(_bfd_elf_init_reloc_shdr): New arg RELDATA.  Remove arg REL_HDR.
All callers changed.  Allocate memory for the Elf_Internal_Shdr
structure.
(_bfd_elf_single_rel_hdr): New function.
(struct fake_section_arg): New structure.
(elf_fake_section): Expect to see a pointer to it in the third
argument.  If doing a relocatable link, allocate both REL and RELA
sections as needed.
(assign_section_numbers): Adjusted to match changes in
data structures.
(_bfd_elf_compute_section_file_positions): Call elf_fake_sections
with a struct fake_section_args argument.
* elfcode.h (elf_write_relocs): Adjusted to match changes in
data structures.
(elf_slurp_reloc_table): Likewise.
* elflink.c (_bfd_elf_link_read_relocs): Likewise.
(_bfd_elf_link_size_reloc_section): Remove arg REL_HDR, replace with
RELDATA.  Remove argument O.  All callers changed.  Remove code to
discover the right rel_hdr and count.
(_bfd_elf_link_output_relocs): Adjusted to match changes in
data structures.
(elf_link_adjust_relocs): Remove args REL_HDR, COUNT and REL_HASH;
replace with RELDATA.  All callers changed.
(elf_link_input_bfd): Correctly generate rel_hash data when both
REL and RELA sections are present.
(elf_reloc_link_order): Adjusted to match changes in
data structures.
(bfd_elf_final_link): Simplify code to count relocs.  Free the
hashes array for both REL and RELA.
(get_dynamic_reloc_section_name): Use _bfd_elf_single_reloc_hdr
* elf32-m32r.c (m32r_elf_fake_sections, elf_backend_fake_sections):
Delete.
* elf32-tic6x.c (elf32_tic6x_fake_sections, elf_backend_fake_sections):
Delete.
(elf32_tic6x_rel_relocation_p): Adjusted to match changes in
data structures.
  * elf32-microblaze.c (microblaze_elf_check_relocs): Use
_bfd_elf_single_rel_hdr.
* elf32-ppc.c (ppc_elf_relax_section): Likewise.
* elf32-spu.c (spu_elf_relocate_section): Likewise.
* elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
* elf64-hppa.c (get_reloc_section): Likewise.
* elf64-mips.c (mips_elf64_slurp_reloc_table): Adjusted to match
changes in data structures.
(mips_elf64_write_relocs): Use _bfd_elf_single_rel_hdr.
* elf64-ppc.c (ppc64_elf_edit_opd): Likewise.
(ppc64_elf_edit_toc): Likewise.
(get_relocs): Adjusted to match changes in data structures.
Allocate an Elf_Internal_Shdr structure if necessary.
(ppc64_elf_finish_dynamic_sections): Use _bfd_elf_single_rel_hdr.
* elf64-sparc.c (elf64_sparc_slurp_reloc_table): Adjusted to match
changes in data structures.
* elfxx-ia64.c (get_reloc_section): Use _bfd_elf_single_rel_hdr.
* elfxx-mips.c (MIPS_RELOC_RELA_P): Remove macro.
(mips_elf_rel_relocation_p): Adjusted to match changes in data
structures.
(_bfd_mips_elf_relocate_section): Use mips_elf_rel_relocation_p rather
than MIPS_RELOC_RELOCA_P.
* elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Use
_bfd_elf_single_rel_hdr.
(_bfd_sparc_elf_relocate_section): Likewise.

ld/
* emultempl/xtensaelf.em (replace_insn_sec_with_prop_sec): Use
_bfd_elf_single_rel_hdr.

20 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
bfd/elf32-m32r.c
bfd/elf32-microblaze.c
bfd/elf32-ppc.c
bfd/elf32-spu.c
bfd/elf32-tic6x.c
bfd/elf64-alpha.c
bfd/elf64-hppa.c
bfd/elf64-mips.c
bfd/elf64-ppc.c
bfd/elf64-sparc.c
bfd/elfcode.h
bfd/elflink.c
bfd/elfxx-ia64.c
bfd/elfxx-mips.c
bfd/elfxx-sparc.c
ld/ChangeLog
ld/emultempl/xtensaelf.em

index f9aba1cddf46012571949df6bd1fd24355890fa9..f7d2587e04475c8f3cb899f900e6ab320a7368c1 100644 (file)
@@ -1,3 +1,76 @@
+2010-10-04  Bernd Schmidt  <bernds@codesourcery.com>
+
+       * elf-bfd.h (struct bfd_elf_section_reloc_data): New structure.
+       (struct bfd_elf_section_data): New members REL and RELA; delete
+       members REL_HDR, REL_HDR2, REL_COUNT, REL_COUNT2, REL_IDX,
+       REL_IDX2, REL_HASHES.
+       (_bfd_elf_init_reloc_shdr): Adjust declaration.
+       (_bfd_elf_single_rel_hdr): Declare.
+       (RELOC_AGAINST_DISCARDED_SECTION): Use it.
+       * elf.c (bfd_section_from_shdr): Adjusted to match changes in
+       data structures.
+       (_bfd_elf_init_reloc_shdr): New arg RELDATA.  Remove arg REL_HDR.
+       All callers changed.  Allocate memory for the Elf_Internal_Shdr
+       structure.
+       (_bfd_elf_single_rel_hdr): New function.
+       (struct fake_section_arg): New structure.
+       (elf_fake_section): Expect to see a pointer to it in the third
+       argument.  If doing a relocatable link, allocate both REL and RELA
+       sections as needed.
+       (assign_section_numbers): Adjusted to match changes in
+       data structures.
+       (_bfd_elf_compute_section_file_positions): Call elf_fake_sections
+       with a struct fake_section_args argument.
+       * elfcode.h (elf_write_relocs): Adjusted to match changes in
+       data structures.
+       (elf_slurp_reloc_table): Likewise.
+       * elflink.c (_bfd_elf_link_read_relocs): Likewise.
+       (_bfd_elf_link_size_reloc_section): Remove arg REL_HDR, replace with
+       RELDATA.  Remove argument O.  All callers changed.  Remove code to
+       discover the right rel_hdr and count.
+       (_bfd_elf_link_output_relocs): Adjusted to match changes in
+       data structures.
+       (elf_link_adjust_relocs): Remove args REL_HDR, COUNT and REL_HASH;
+       replace with RELDATA.  All callers changed.
+       (elf_link_input_bfd): Correctly generate rel_hash data when both
+       REL and RELA sections are present.
+       (elf_reloc_link_order): Adjusted to match changes in
+       data structures.
+       (bfd_elf_final_link): Simplify code to count relocs.  Free the
+       hashes array for both REL and RELA.
+       (get_dynamic_reloc_section_name): Use _bfd_elf_single_reloc_hdr
+       * elf32-m32r.c (m32r_elf_fake_sections, elf_backend_fake_sections):
+       Delete.
+       * elf32-tic6x.c (elf32_tic6x_fake_sections, elf_backend_fake_sections):
+       Delete.
+       (elf32_tic6x_rel_relocation_p): Adjusted to match changes in
+       data structures.
+       * elf32-microblaze.c (microblaze_elf_check_relocs): Use
+       _bfd_elf_single_rel_hdr.
+       * elf32-ppc.c (ppc_elf_relax_section): Likewise.
+       * elf32-spu.c (spu_elf_relocate_section): Likewise.
+       * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+       * elf64-hppa.c (get_reloc_section): Likewise.
+       * elf64-mips.c (mips_elf64_slurp_reloc_table): Adjusted to match
+       changes in data structures.
+       (mips_elf64_write_relocs): Use _bfd_elf_single_rel_hdr.
+       * elf64-ppc.c (ppc64_elf_edit_opd): Likewise.
+       (ppc64_elf_edit_toc): Likewise.
+       (get_relocs): Adjusted to match changes in data structures.
+       Allocate an Elf_Internal_Shdr structure if necessary.
+       (ppc64_elf_finish_dynamic_sections): Use _bfd_elf_single_rel_hdr.
+       * elf64-sparc.c (elf64_sparc_slurp_reloc_table): Adjusted to match
+       changes in data structures.
+       * elfxx-ia64.c (get_reloc_section): Use _bfd_elf_single_rel_hdr.
+       * elfxx-mips.c (MIPS_RELOC_RELA_P): Remove macro.
+       (mips_elf_rel_relocation_p): Adjusted to match changes in data
+       structures.
+       (_bfd_mips_elf_relocate_section): Use mips_elf_rel_relocation_p rather
+       than MIPS_RELOC_RELOCA_P.
+       * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Use
+       _bfd_elf_single_rel_hdr.
+       (_bfd_sparc_elf_relocate_section): Likewise.
+
 2010-10-01  Thomas Schwinge  <thomas@codesourcery.com>
 
        * elf32-arm.c (elf32_arm_size_stubs): Don't choke on local symbols in
index dbcebd2c6bbf6eb5b1feab279f9f93583f3ee621..66dcbcd5eac253794fed02cb0169b7e49388f12e 100644 (file)
@@ -1319,6 +1319,23 @@ struct elf_backend_data
   unsigned default_execstack : 1;
 };
 
+/* Information about reloc sections associated with a bfd_elf_section_data
+   structure.  */
+struct bfd_elf_section_reloc_data
+{
+  /* The ELF header for the reloc section associated with this
+     section, if any.  */
+  Elf_Internal_Shdr *hdr;
+  /* The number of relocations currently assigned to HDR.  */
+  unsigned int count;
+  /* The ELF section number of the reloc section.  Only used for an
+     output file.  */
+  int idx;
+  /* Used by the backend linker to store the symbol hash table entries
+     associated with relocs against global symbols.  */
+  struct elf_link_hash_entry **hashes;
+};
+
 /* Information stored for each BFD section in an ELF file.  This
    structure is allocated by elf_new_section_hook.  */
 
@@ -1327,31 +1344,13 @@ struct bfd_elf_section_data
   /* The ELF header for this section.  */
   Elf_Internal_Shdr this_hdr;
 
-  /* The ELF header for the reloc section associated with this
-     section, if any.  */
-  Elf_Internal_Shdr rel_hdr;
-
-  /* If there is a second reloc section associated with this section,
-     as can happen on Irix 6, this field points to the header.  */
-  Elf_Internal_Shdr *rel_hdr2;
-
-  /* The number of relocations currently assigned to REL_HDR.  */
-  unsigned int rel_count;
-
-  /* The number of relocations currently assigned to REL_HDR2.  */
-  unsigned int rel_count2;
+  /* Information about the REL and RELA reloc sections associated
+     with this section, if any.  */
+  struct bfd_elf_section_reloc_data rel, rela;
 
   /* The ELF section number of this section.  */
   int this_idx;
 
-  /* The ELF section number of the reloc section indicated by
-     REL_HDR if any.  Only used for an output file.  */
-  int rel_idx;
-
-  /* The ELF section number of the reloc section indicated by
-     REL_HDR2 if any.  Only used for an output file.  */
-  int rel_idx2;
-
   /* Used by the backend linker when generating a shared library to
      record the dynamic symbol index for a section symbol
      corresponding to this section.  A value of 0 means that there is
@@ -1361,10 +1360,6 @@ struct bfd_elf_section_data
   /* A pointer to the linked-to section for SHF_LINK_ORDER.  */
   asection *linked_to;
 
-  /* Used by the backend linker to store the symbol hash table entries
-     associated with relocs against global symbols.  */
-  struct elf_link_hash_entry **rel_hashes;
-
   /* A pointer to the swapped relocs.  If the section uses REL relocs,
      rather than RELA, all the r_addend fields will be zero.  This
      pointer may be NULL.  It is used by the backend linker.  */
@@ -1852,7 +1847,7 @@ extern int _bfd_elf_sizeof_headers
 extern bfd_boolean _bfd_elf_new_section_hook
   (bfd *, asection *);
 extern bfd_boolean _bfd_elf_init_reloc_shdr
-  (bfd *, Elf_Internal_Shdr *, asection *, bfd_boolean);
+  (bfd *, struct bfd_elf_section_reloc_data *, asection *, bfd_boolean);
 extern const struct bfd_elf_special_section *_bfd_elf_get_special_section
   (const char *, const struct bfd_elf_special_section *, unsigned int);
 extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr
@@ -2237,6 +2232,7 @@ extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *);
 extern int _bfd_elf_obj_attrs_arg_type (bfd *, int, int);
 extern void _bfd_elf_parse_attributes (bfd *, Elf_Internal_Shdr *);
 extern bfd_boolean _bfd_elf_merge_object_attributes (bfd *, bfd *);
+extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec);
 
 /* The linker may needs to keep track of the number of relocs that it
    decides to copy as dynamic relocs in check_relocs for each symbol.
@@ -2363,13 +2359,13 @@ extern asection _bfd_elf_large_com_section;
           sections may require relocations.  */                        \
        Elf_Internal_Shdr *rel_hdr;                                     \
                                                                        \
-       rel_hdr = &elf_section_data (input_section->output_section)->rel_hdr; \
+       rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \
                                                                        \
        /* Avoid empty output section.  */                              \
        if (rel_hdr->sh_size > rel_hdr->sh_entsize)                     \
          {                                                             \
            rel_hdr->sh_size -= rel_hdr->sh_entsize;                    \
-           rel_hdr = &elf_section_data (input_section)->rel_hdr;       \
+           rel_hdr = _bfd_elf_single_rel_hdr (input_section);          \
            rel_hdr->sh_size -= rel_hdr->sh_entsize;                    \
                                                                        \
            memmove (rel, rel + 1, (relend - rel) * sizeof (*rel));     \
index fe5f19fc075d1304b47be3cce504147407ebbc37..85d4c18eea323a19e5309de7f2f6cdb2d3936ca8 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1710,8 +1710,10 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
       /* *These* do a lot of work -- but build no sections!  */
       {
        asection *target_sect;
-       Elf_Internal_Shdr *hdr2;
+       Elf_Internal_Shdr *hdr2, **p_hdr;
        unsigned int num_sec = elf_numsections (abfd);
+       struct bfd_elf_section_data *esdt;
+       bfd_size_type amt;
 
        if (hdr->sh_entsize
            != (bfd_size_type) (hdr->sh_type == SHT_REL
@@ -1790,20 +1792,19 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
        if (target_sect == NULL)
          return FALSE;
 
-       if ((target_sect->flags & SEC_RELOC) == 0
-           || target_sect->reloc_count == 0)
-         hdr2 = &elf_section_data (target_sect)->rel_hdr;
+       esdt = elf_section_data (target_sect);
+       if (hdr->sh_type == SHT_RELA)
+         p_hdr = &esdt->rela.hdr;
        else
-         {
-           bfd_size_type amt;
-           BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
-           amt = sizeof (*hdr2);
-           hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
-           if (hdr2 == NULL)
-             return FALSE;
-           elf_section_data (target_sect)->rel_hdr2 = hdr2;
-         }
+         p_hdr = &esdt->rel.hdr;
+
+       BFD_ASSERT (*p_hdr == NULL);
+       amt = sizeof (*hdr2);
+       hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
+       if (hdr2 == NULL)
+         return FALSE;
        *hdr2 = *hdr;
+       *p_hdr = hdr2;
        elf_elfsections (abfd)[shindex] = hdr2;
        target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr);
        target_sect->flags |= SEC_RELOC;
@@ -1812,7 +1813,10 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
        /* In the section to which the relocations apply, mark whether
           its relocations are of the REL or RELA variety.  */
        if (hdr->sh_size != 0)
-         target_sect->use_rela_p = hdr->sh_type == SHT_RELA;
+         {
+           if (hdr->sh_type == SHT_RELA)
+             target_sect->use_rela_p = 1;
+         }
        abfd->flags |= HAS_RELOC;
        return TRUE;
       }
@@ -2410,20 +2414,43 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
     }
 }
 
-/* Initialize REL_HDR, the section-header for new section, containing
-   relocations against ASECT.  If USE_RELA_P is TRUE, we use RELA
-   relocations; otherwise, we use REL relocations.  */
+/* Return the REL_HDR for SEC, assuming there is only a single one, either
+   REL or RELA.  */
+
+Elf_Internal_Shdr *
+_bfd_elf_single_rel_hdr (asection *sec)
+{
+  if (elf_section_data (sec)->rel.hdr)
+    {
+      BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL);
+      return elf_section_data (sec)->rel.hdr;
+    }
+  else
+    return elf_section_data (sec)->rela.hdr;
+}
+
+/* Allocate and initialize a section-header for a new reloc section,
+   containing relocations against ASECT.  It is stored in RELDATA.  If
+   USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
+   relocations.  */
 
 bfd_boolean
 _bfd_elf_init_reloc_shdr (bfd *abfd,
-                         Elf_Internal_Shdr *rel_hdr,
+                         struct bfd_elf_section_reloc_data *reldata,
                          asection *asect,
                          bfd_boolean use_rela_p)
 {
+  Elf_Internal_Shdr *rel_hdr;
   char *name;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-  bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
+  bfd_size_type amt;
+
+  amt = sizeof (Elf_Internal_Shdr);
+  BFD_ASSERT (reldata->hdr == NULL);
+  rel_hdr = bfd_zalloc (abfd, amt);
+  reldata->hdr = rel_hdr;
 
+  amt = sizeof ".rela" + strlen (asect->name);      
   name = (char *) bfd_alloc (abfd, amt);
   if (name == NULL)
     return FALSE;
@@ -2457,30 +2484,37 @@ bfd_elf_get_default_section_type (flagword flags)
   return SHT_PROGBITS;
 }
 
+struct fake_section_arg
+{
+  struct bfd_link_info *link_info;
+  bfd_boolean failed;
+};
+
 /* Set up an ELF internal section header for a section.  */
 
 static void
-elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
+elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
 {
+  struct fake_section_arg *arg = (struct fake_section_arg *)fsarg;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-  bfd_boolean *failedptr = (bfd_boolean *) failedptrarg;
+  struct bfd_elf_section_data *esd = elf_section_data (asect);
   Elf_Internal_Shdr *this_hdr;
   unsigned int sh_type;
 
-  if (*failedptr)
+  if (arg->failed)
     {
       /* We already failed; just get out of the bfd_map_over_sections
         loop.  */
       return;
     }
 
-  this_hdr = &elf_section_data (asect)->this_hdr;
+  this_hdr = &esd->this_hdr;
 
   this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
                                                          asect->name, FALSE);
   if (this_hdr->sh_name == (unsigned int) -1)
     {
-      *failedptr = TRUE;
+      arg->failed = TRUE;
       return;
     }
 
@@ -2632,11 +2666,45 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
   if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
     this_hdr->sh_flags |= SHF_EXCLUDE;
 
+  /* If the section has relocs, set up a section header for the
+     SHT_REL[A] section.  If two relocation sections are required for
+     this section, it is up to the processor-specific back-end to
+     create the other.  */
+  if ((asect->flags & SEC_RELOC) != 0)
+    {
+      /* When doing a relocatable link, create both REL and RELA sections if
+        needed.  */
+      if (arg->link_info
+         /* Do the normal setup if we wouldn't create any sections here.  */
+         && esd->rel.count + esd->rela.count > 0
+         && (arg->link_info->relocatable || arg->link_info->emitrelocations))
+       {
+         if (esd->rel.count && esd->rel.hdr == NULL
+             && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, asect, FALSE))
+           {
+             arg->failed = TRUE;
+             return;
+           }
+         if (esd->rela.count && esd->rela.hdr == NULL
+             && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, asect, TRUE))
+           {
+             arg->failed = TRUE;
+             return;
+           }
+       }
+      else if (!_bfd_elf_init_reloc_shdr (abfd,
+                                         (asect->use_rela_p
+                                          ? &esd->rela : &esd->rel),
+                                         asect,
+                                         asect->use_rela_p))
+         arg->failed = TRUE;
+    }
+
   /* Check for processor-specific section types.  */
   sh_type = this_hdr->sh_type;
   if (bed->elf_backend_fake_sections
       && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
-    *failedptr = TRUE;
+    arg->failed = TRUE;
 
   if (sh_type == SHT_NOBITS && asect->size != 0)
     {
@@ -2644,17 +2712,6 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
         called for objcopy --only-keep-debug.  */
       this_hdr->sh_type = sh_type;
     }
-
-  /* If the section has relocs, set up a section header for the
-     SHT_REL[A] section.  If two relocation sections are required for
-     this section, it is up to the processor-specific back-end to
-     create the other.  */
-  if ((asect->flags & SEC_RELOC) != 0
-      && !_bfd_elf_init_reloc_shdr (abfd,
-                                   &elf_section_data (asect)->rel_hdr,
-                                   asect,
-                                   asect->use_rela_p))
-    *failedptr = TRUE;
 }
 
 /* Fill in the contents of a SHT_GROUP section.  Called from
@@ -2820,21 +2877,21 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
       if (d->this_hdr.sh_type != SHT_GROUP)
        d->this_idx = section_number++;
       _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
-      if ((sec->flags & SEC_RELOC) == 0)
-       d->rel_idx = 0;
-      else
+      if (d->rel.hdr)
        {
-         d->rel_idx = section_number++;
-         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
+         d->rel.idx = section_number++;
+         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
        }
+      else
+       d->rel.idx = 0;
 
-      if (d->rel_hdr2)
+      if (d->rela.hdr)
        {
-         d->rel_idx2 = section_number++;
-         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
+         d->rela.idx = section_number++;
+         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
        }
       else
-       d->rel_idx2 = 0;
+       d->rela.idx = 0;
     }
 
   t->shstrtab_section = section_number++;
@@ -2906,25 +2963,25 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
       d = elf_section_data (sec);
 
       i_shdrp[d->this_idx] = &d->this_hdr;
-      if (d->rel_idx != 0)
-       i_shdrp[d->rel_idx] = &d->rel_hdr;
-      if (d->rel_idx2 != 0)
-       i_shdrp[d->rel_idx2] = d->rel_hdr2;
+      if (d->rel.idx != 0)
+       i_shdrp[d->rel.idx] = d->rel.hdr;
+      if (d->rela.idx != 0)
+       i_shdrp[d->rela.idx] = d->rela.hdr;
 
       /* Fill in the sh_link and sh_info fields while we're at it.  */
 
       /* sh_link of a reloc section is the section index of the symbol
         table.  sh_info is the section index of the section to which
         the relocation entries apply.  */
-      if (d->rel_idx != 0)
+      if (d->rel.idx != 0)
        {
-         d->rel_hdr.sh_link = t->symtab_section;
-         d->rel_hdr.sh_info = d->this_idx;
+         d->rel.hdr->sh_link = t->symtab_section;
+         d->rel.hdr->sh_info = d->this_idx;
        }
-      if (d->rel_idx2 != 0)
+      if (d->rela.idx != 0)
        {
-         d->rel_hdr2->sh_link = t->symtab_section;
-         d->rel_hdr2->sh_info = d->this_idx;
+         d->rela.hdr->sh_link = t->symtab_section;
+         d->rela.hdr->sh_info = d->this_idx;
        }
 
       /* We need to set up sh_link for SHF_LINK_ORDER.  */
@@ -3278,6 +3335,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
                                         struct bfd_link_info *link_info)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  struct fake_section_arg fsargs;
   bfd_boolean failed;
   struct bfd_strtab_hash *strtab = NULL;
   Elf_Internal_Shdr *shstrtab_hdr;
@@ -3297,9 +3355,10 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
   if (bed->elf_backend_post_process_headers)
     (*bed->elf_backend_post_process_headers) (abfd, link_info);
 
-  failed = FALSE;
-  bfd_map_over_sections (abfd, elf_fake_sections, &failed);
-  if (failed)
+  fsargs.failed = FALSE;
+  fsargs.link_info = link_info;
+  bfd_map_over_sections (abfd, elf_fake_sections, &fsargs);
+  if (fsargs.failed)
     return FALSE;
 
   if (!assign_section_numbers (abfd, link_info))
@@ -3319,6 +3378,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
        return FALSE;
     }
 
+  failed = FALSE;
   if (link_info == NULL)
     {
       bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
index 3df6addb69e72a778a3100b4bdcbf2196c51812c..db7dcf9d9a56002e95fe97b134f9c5fd502ee627 100644 (file)
@@ -4034,39 +4034,6 @@ static const struct bfd_elf_special_section m32r_elf_special_sections[] =
   { NULL,                     0,  0, 0,            0 }
 };
 
-static bfd_boolean
-m32r_elf_fake_sections (bfd *abfd,
-                       Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
-                       asection *sec)
-{
-  /* The generic elf_fake_sections will set up REL_HDR using the
-     default kind of relocations.  But, we may actually need both
-     kinds of relocations, so we set up the second header here.
-
-     This is not necessary for the O32 ABI since that only uses Elf32_Rel
-     relocations (cf. System V ABI, MIPS RISC Processor Supplement,
-     3rd Edition, p. 4-17).  It breaks the IRIX 5/6 32-bit ld, since one
-     of the resulting empty .rela.<section> sections starts with
-     sh_offset == object size, and ld doesn't allow that.  While the check
-     is arguably bogus for empty or SHT_NOBITS sections, it can easily be
-     avoided by not emitting those useless sections in the first place.  */
-  if ((sec->flags & SEC_RELOC) != 0)
-    {
-      struct bfd_elf_section_data *esd;
-      bfd_size_type amt = sizeof (Elf_Internal_Shdr);
-
-      esd = elf_section_data (sec);
-      BFD_ASSERT (esd->rel_hdr2 == NULL);
-      esd->rel_hdr2 = bfd_zalloc (abfd, amt);
-      if (!esd->rel_hdr2)
-        return FALSE;
-      _bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec,
-                                !sec->use_rela_p);
-    }
-
-  return TRUE;
-}
-
 static enum elf_reloc_type_class
 m32r_elf_reloc_type_class (const Elf_Internal_Rela *rela)
 {
@@ -4128,7 +4095,6 @@ m32r_elf_reloc_type_class (const Elf_Internal_Rela *rela)
 #else
 #define elf_backend_default_use_rela_p  1
 #define elf_backend_may_use_rela_p      1
-#define elf_backend_fake_sections       m32r_elf_fake_sections
 #endif
 
 #define elf_backend_object_p                   m32r_elf_object_p
index e260c5557758351bfb8e8663a792388153a9e6a8..f32e06e3fffab6d70ca28bda0b5f41a543d8a298 100644 (file)
@@ -2060,7 +2060,7 @@ microblaze_elf_check_relocs (bfd * abfd,
                    const char *name;
                    bfd *dynobj;
                    unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
-                   unsigned int shnam = elf_section_data (sec)->rel_hdr.sh_name;
+                   unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name;
 
                    name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
                    if (name == NULL)
index 2b457d6d9bfe43e6a89151c7121fa4a1c0c4d254..58e98071268a5bbfb52dfc55a84d86a39b209c5b 100644 (file)
@@ -6391,6 +6391,7 @@ ppc_elf_relax_section (bfd *abfd,
     {
       /* Append sufficient NOP relocs so we can write out relocation
         information for the trampolines.  */
+      Elf_Internal_Shdr *rel_hdr;
       Elf_Internal_Rela *new_relocs = bfd_malloc ((changes + isec->reloc_count)
                                                  * sizeof (*new_relocs));
       unsigned ix;
@@ -6409,8 +6410,8 @@ ppc_elf_relax_section (bfd *abfd,
        free (internal_relocs);
       elf_section_data (isec)->relocs = new_relocs;
       isec->reloc_count += changes;
-      elf_section_data (isec)->rel_hdr.sh_size
-       += changes * elf_section_data (isec)->rel_hdr.sh_entsize;
+      rel_hdr = _bfd_elf_single_rel_hdr (isec);
+      rel_hdr->sh_size += changes * rel_hdr->sh_entsize;
     }
   else if (elf_section_data (isec)->relocs != internal_relocs)
     free (internal_relocs);
index b1ea43c5297ca8e5cc5f2dffddb6fac738a3dfd1..ed52c64e2dfe4be80a0dbc4377194c1e25f93ffc 100644 (file)
@@ -5091,7 +5091,7 @@ spu_elf_relocate_section (bfd *output_bfd,
        }
       input_section->reloc_count = wrel - relocs;
       /* Backflips for _bfd_elf_link_output_relocs.  */
-      rel_hdr = &elf_section_data (input_section)->rel_hdr;
+      rel_hdr = _bfd_elf_single_rel_hdr (input_section);
       rel_hdr->sh_size = input_section->reloc_count * rel_hdr->sh_entsize;
       ret = 2;
     }
index ed3d3d92a870acc52f07d55f0033510e71ffcea1..a570f88c5805db0e5c0047a72b88d0908305e2e7 100644 (file)
@@ -1347,31 +1347,6 @@ elf32_tic6x_set_use_rela_p (bfd *abfd, bfd_boolean use_rela_p)
   elf32_tic6x_tdata (abfd)->use_rela_p = use_rela_p;
 }
 
-static bfd_boolean
-elf32_tic6x_fake_sections (bfd *abfd,
-                          Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
-                          asection *sec)
-{
-  /* The generic elf_fake_sections will set up REL_HDR using the
-     default kind of relocations.  But, we may actually need both
-     kinds of relocations, so we set up the second header here.  */
-  if ((sec->flags & SEC_RELOC) != 0)
-    {
-      struct bfd_elf_section_data *esd;
-      bfd_size_type amt = sizeof (Elf_Internal_Shdr);
-
-      esd = elf_section_data (sec);
-      BFD_ASSERT (esd->rel_hdr2 == NULL);
-      esd->rel_hdr2 = bfd_zalloc (abfd, amt);
-      if (!esd->rel_hdr2)
-        return FALSE;
-      _bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec,
-                                !sec->use_rela_p);
-    }
-
-  return TRUE;
-}
-
 static bfd_boolean
 elf32_tic6x_mkobject (bfd *abfd)
 {
@@ -1408,14 +1383,13 @@ elf32_tic6x_rel_relocation_p (bfd *abfd, asection *sec,
   const struct elf_backend_data *bed;
 
   /* To determine which flavor of relocation this is, we depend on the
-     fact that the INPUT_SECTION's REL_HDR is read before its
-     REL_HDR2.  */
-  rel_hdr = &elf_section_data (sec)->rel_hdr;
+     fact that the INPUT_SECTION's REL_HDR is read before RELA_HDR.  */
+  rel_hdr = elf_section_data (sec)->rel.hdr;
+  if (rel_hdr == NULL)
+    return FALSE;
   bed = get_elf_backend_data (abfd);
-  if ((size_t) (rel - relocs)
-      >= (NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel))
-    rel_hdr = elf_section_data (sec)->rel_hdr2;
-  return rel_hdr->sh_entsize == bed->s->sizeof_rel;
+  return ((size_t) (rel - relocs)
+         < NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel);
 }
 
 static bfd_boolean
@@ -1790,7 +1764,6 @@ elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 #define elf_backend_default_use_rela_p 1
 #define elf_backend_may_use_rel_p      1
 #define elf_backend_may_use_rela_p     1
-#define elf_backend_fake_sections       elf32_tic6x_fake_sections
 #define elf_backend_obj_attrs_arg_type elf32_tic6x_obj_attrs_arg_type
 #define elf_backend_obj_attrs_section  "__TI_build_attributes"
 #define elf_backend_obj_attrs_section_type     SHT_C6000_ATTRIBUTES
index 1df020c3975b7ec4afdfdba58d06aa07265122c6..a6a795ddcdc772d4c24726f8602fae8bbd59c0b7 100644 (file)
@@ -4086,7 +4086,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
       const char *section_name;
       section_name = (bfd_elf_string_from_elf_section
                      (input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
-                      elf_section_data(input_section)->rel_hdr.sh_name));
+                      _bfd_elf_single_rel_hdr (input_section)->sh_name));
       BFD_ASSERT(section_name != NULL);
       srel = bfd_get_section_by_name (dynobj, section_name);
     }
index 4efab4fc269bd64489d71861d277ce21326a0448..e7e61a1fe68f52cab763e6a704edf01a5181cac3 100644 (file)
@@ -407,7 +407,7 @@ get_reloc_section (bfd *abfd,
 
   srel_name = (bfd_elf_string_from_elf_section
               (abfd, elf_elfheader(abfd)->e_shstrndx,
-               elf_section_data(sec)->rel_hdr.sh_name));
+               _bfd_elf_single_rel_hdr(sec)->sh_name));
   if (srel_name == NULL)
     return FALSE;
 
index 5001d42315bbb6f64feb0a68efa2235652b0da06..7ed54fac78a4067939ce66190c4004b9623356ac 100644 (file)
@@ -2722,13 +2722,13 @@ mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
          || asect->reloc_count == 0)
        return TRUE;
 
-      rel_hdr = &d->rel_hdr;
-      reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
-      rel_hdr2 = d->rel_hdr2;
+      rel_hdr = d->rel.hdr;
+      reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
+      rel_hdr2 = d->rela.hdr;
       reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
 
       BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
-      BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
+      BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
                  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
 
     }
@@ -2756,19 +2756,18 @@ mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
   /* The slurp_one_reloc_table routine increments reloc_count.  */
   asect->reloc_count = 0;
 
-  if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
-                                         rel_hdr, reloc_count,
-                                         relents,
-                                         symbols, dynamic))
+  if (rel_hdr != NULL
+      && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
+                                            rel_hdr, reloc_count,
+                                            relents,
+                                            symbols, dynamic))
+    return FALSE;
+  if (rel_hdr2 != NULL
+      && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
+                                            rel_hdr2, reloc_count2,
+                                            relents + reloc_count * 3,
+                                            symbols, dynamic))
     return FALSE;
-  if (d->rel_hdr2 != NULL)
-    {
-      if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
-                                             rel_hdr2, reloc_count2,
-                                             relents + reloc_count * 3,
-                                             symbols, dynamic))
-       return FALSE;
-    }
 
   asect->relocation = relents;
   return TRUE;
@@ -2827,7 +2826,7 @@ mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
        }
     }
 
-  rel_hdr = &elf_section_data (sec)->rel_hdr;
+  rel_hdr = _bfd_elf_single_rel_hdr (sec);
 
   /* Do the actual relocation.  */
 
index a4f3064a4f7702210a929e632f2082e3e63a7bed..2cdb0a265a14bb0f44eb1ae4eee7b9d166daafc6 100644 (file)
@@ -7073,6 +7073,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
       if (need_edit || add_aux_fields)
        {
          Elf_Internal_Rela *write_rel;
+         Elf_Internal_Shdr *rel_hdr;
          bfd_byte *rptr, *wptr;
          bfd_byte *new_contents;
          bfd_boolean skip;
@@ -7252,9 +7253,8 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
 
          /* Fudge the header size too, as this is used later in
             elf_bfd_final_link if we are emitting relocs.  */
-         elf_section_data (sec)->rel_hdr.sh_size
-           = sec->reloc_count * elf_section_data (sec)->rel_hdr.sh_entsize;
-         BFD_ASSERT (elf_section_data (sec)->rel_hdr2 == NULL);
+         rel_hdr = _bfd_elf_single_rel_hdr (sec);
+         rel_hdr->sh_size = sec->reloc_count * rel_hdr->sh_entsize;
          some_edited = TRUE;
        }
       else if (elf_section_data (sec)->relocs != relstart)
@@ -8413,6 +8413,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
 
          if (toc->reloc_count != 0)
            {
+             Elf_Internal_Shdr *rel_hdr;
              Elf_Internal_Rela *wrel;
              bfd_size_type sz;
 
@@ -8438,9 +8439,9 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
                  goto error_ret;
 
              toc->reloc_count = wrel - relstart;
-             sz = elf_section_data (toc)->rel_hdr.sh_entsize;
-             elf_section_data (toc)->rel_hdr.sh_size = toc->reloc_count * sz;
-             BFD_ASSERT (elf_section_data (toc)->rel_hdr2 == NULL);
+             rel_hdr = _bfd_elf_single_rel_hdr (toc);
+             sz = rel_hdr->sh_entsize;
+             rel_hdr->sh_size = toc->reloc_count * sz;
            }
        }
 
@@ -9376,9 +9377,13 @@ get_relocs (asection *sec, int count)
       if (relocs == NULL)
        return NULL;
       elfsec_data->relocs = relocs;
-      elfsec_data->rel_hdr.sh_size = (sec->reloc_count
-                                     * sizeof (Elf64_External_Rela));
-      elfsec_data->rel_hdr.sh_entsize = sizeof (Elf64_External_Rela);
+      elfsec_data->rela.hdr = bfd_zalloc (sec->owner,
+                                         sizeof (Elf_Internal_Shdr));
+      if (elfsec_data->rela.hdr == NULL)
+       return NULL;
+      elfsec_data->rela.hdr->sh_size = (sec->reloc_count
+                                       * sizeof (Elf64_External_Rela));
+      elfsec_data->rela.hdr->sh_entsize = sizeof (Elf64_External_Rela);
       sec->reloc_count = 0;
     }
   relocs += sec->reloc_count;
@@ -13472,7 +13477,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
       && htab->brlt->reloc_count != 0
       && !_bfd_elf_link_output_relocs (output_bfd,
                                       htab->brlt,
-                                      &elf_section_data (htab->brlt)->rel_hdr,
+                                      elf_section_data (htab->brlt)->rela.hdr,
                                       elf_section_data (htab->brlt)->relocs,
                                       NULL))
     return FALSE;
@@ -13481,7 +13486,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
       && htab->glink->reloc_count != 0
       && !_bfd_elf_link_output_relocs (output_bfd,
                                       htab->glink,
-                                      &elf_section_data (htab->glink)->rel_hdr,
+                                      elf_section_data (htab->glink)->rela.hdr,
                                       elf_section_data (htab->glink)->relocs,
                                       NULL))
     return FALSE;
index ca692d291dce93a0559c4260c6d1bffc551a7b06..1ad0c14e09530d489ec5a11930764d1af64de77c 100644 (file)
@@ -163,10 +163,10 @@ elf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
          || asect->reloc_count == 0)
        return TRUE;
 
-      rel_hdr = &d->rel_hdr;
-      rel_hdr2 = d->rel_hdr2;
+      rel_hdr = d->rel.hdr;
+      rel_hdr2 = d->rela.hdr;
 
-      BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
+      BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
                  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
     }
   else
@@ -193,8 +193,9 @@ elf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
      canon_reloc_count.  */
   canon_reloc_count (asect) = 0;
 
-  if (!elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
-                                         dynamic))
+  if (rel_hdr
+      && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
+                                            dynamic))
     return FALSE;
 
   if (rel_hdr2
@@ -325,7 +326,7 @@ elf64_sparc_write_relocs (bfd *abfd, asection *sec, PTR data)
        }
     }
 
-  rela_hdr = &elf_section_data (sec)->rel_hdr;
+  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);
index 0cd11830bd2f0851d621b57f6d2c34785e9cd6b6..5ef461018d97bbc8e08d9150a894ae26e60e50f8 100644 (file)
@@ -959,7 +959,9 @@ elf_write_relocs (bfd *abfd, asection *sec, void *data)
   if (sec->orelocation == NULL)
     return;
 
-  rela_hdr = &elf_section_data (sec)->rel_hdr;
+  rela_hdr = elf_section_data (sec)->rela.hdr;
+  if (rela_hdr == NULL)
+    rela_hdr = elf_section_data (sec)->rel.hdr;
 
   rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
   rela_hdr->contents = (unsigned char *) bfd_alloc (abfd, rela_hdr->sh_size);
@@ -1530,13 +1532,13 @@ elf_slurp_reloc_table (bfd *abfd,
          || asect->reloc_count == 0)
        return TRUE;
 
-      rel_hdr = &d->rel_hdr;
-      reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
-      rel_hdr2 = d->rel_hdr2;
-      reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
+      rel_hdr = d->rel.hdr;
+      reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
+      rel_hdr2 = d->rela.hdr;
+      reloc_count2 = rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0;
 
       BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
-      BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
+      BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
                  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
 
     }
@@ -1560,10 +1562,11 @@ elf_slurp_reloc_table (bfd *abfd,
   if (relents == NULL)
     return FALSE;
 
-  if (!elf_slurp_reloc_table_from_section (abfd, asect,
-                                          rel_hdr, reloc_count,
-                                          relents,
-                                          symbols, dynamic))
+  if (rel_hdr
+      && !elf_slurp_reloc_table_from_section (abfd, asect,
+                                             rel_hdr, reloc_count,
+                                             relents,
+                                             symbols, dynamic))
     return FALSE;
 
   if (rel_hdr2
index 46f1e2556c40dd36e97e35db3118e0df75f21179..2c4564963b660441e187cdc3b8aea4eceb449727 100644 (file)
@@ -2196,7 +2196,7 @@ elf_link_read_relocs_from_section (bfd *abfd,
    according to the KEEP_MEMORY argument.  If O has two relocation
    sections (both REL and RELA relocations), then the REL_HDR
    relocations will appear first in INTERNAL_RELOCS, followed by the
-   REL_HDR2 relocations.  */
+   RELA_HDR relocations.  */
 
 Elf_Internal_Rela *
 _bfd_elf_link_read_relocs (bfd *abfd,
@@ -2205,19 +2205,18 @@ _bfd_elf_link_read_relocs (bfd *abfd,
                           Elf_Internal_Rela *internal_relocs,
                           bfd_boolean keep_memory)
 {
-  Elf_Internal_Shdr *rel_hdr;
   void *alloc1 = NULL;
   Elf_Internal_Rela *alloc2 = NULL;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  struct bfd_elf_section_data *esdo = elf_section_data (o);
+  Elf_Internal_Rela *internal_rela_relocs;
 
-  if (elf_section_data (o)->relocs != NULL)
-    return elf_section_data (o)->relocs;
+  if (esdo->relocs != NULL)
+    return esdo->relocs;
 
   if (o->reloc_count == 0)
     return NULL;
 
-  rel_hdr = &elf_section_data (o)->rel_hdr;
-
   if (internal_relocs == NULL)
     {
       bfd_size_type size;
@@ -2234,32 +2233,41 @@ _bfd_elf_link_read_relocs (bfd *abfd,
 
   if (external_relocs == NULL)
     {
-      bfd_size_type size = rel_hdr->sh_size;
+      bfd_size_type size = 0;
+
+      if (esdo->rel.hdr)
+       size += esdo->rel.hdr->sh_size;
+      if (esdo->rela.hdr)
+       size += esdo->rela.hdr->sh_size;
 
-      if (elf_section_data (o)->rel_hdr2)
-       size += elf_section_data (o)->rel_hdr2->sh_size;
       alloc1 = bfd_malloc (size);
       if (alloc1 == NULL)
        goto error_return;
       external_relocs = alloc1;
     }
 
-  if (!elf_link_read_relocs_from_section (abfd, o, rel_hdr,
-                                         external_relocs,
-                                         internal_relocs))
-    goto error_return;
-  if (elf_section_data (o)->rel_hdr2
-      && (!elf_link_read_relocs_from_section
-         (abfd, o,
-          elf_section_data (o)->rel_hdr2,
-          ((bfd_byte *) external_relocs) + rel_hdr->sh_size,
-          internal_relocs + (NUM_SHDR_ENTRIES (rel_hdr)
-                             * bed->s->int_rels_per_ext_rel))))
+  internal_rela_relocs = internal_relocs;
+  if (esdo->rel.hdr)
+    {
+      if (!elf_link_read_relocs_from_section (abfd, o, esdo->rel.hdr,
+                                             external_relocs,
+                                             internal_relocs))
+       goto error_return;
+      external_relocs = (((bfd_byte *) external_relocs)
+                        + esdo->rel.hdr->sh_size);
+      internal_rela_relocs += (NUM_SHDR_ENTRIES (esdo->rel.hdr)
+                              * bed->s->int_rels_per_ext_rel);
+    }
+
+  if (esdo->rela.hdr
+      && (!elf_link_read_relocs_from_section (abfd, o, esdo->rela.hdr,
+                                             external_relocs,
+                                             internal_rela_relocs)))
     goto error_return;
 
   /* Cache the results for next time, if we can.  */
   if (keep_memory)
-    elf_section_data (o)->relocs = internal_relocs;
+    esdo->relocs = internal_relocs;
 
   if (alloc1 != NULL)
     free (alloc1);
@@ -2287,24 +2295,12 @@ _bfd_elf_link_read_relocs (bfd *abfd,
 
 static bfd_boolean
 _bfd_elf_link_size_reloc_section (bfd *abfd,
-                                 Elf_Internal_Shdr *rel_hdr,
-                                 asection *o)
+                                 struct bfd_elf_section_reloc_data *reldata)
 {
-  bfd_size_type reloc_count;
-  bfd_size_type num_rel_hashes;
-
-  /* Figure out how many relocations there will be.  */
-  if (rel_hdr == &elf_section_data (o)->rel_hdr)
-    reloc_count = elf_section_data (o)->rel_count;
-  else
-    reloc_count = elf_section_data (o)->rel_count2;
-
-  num_rel_hashes = o->reloc_count;
-  if (num_rel_hashes < reloc_count)
-    num_rel_hashes = reloc_count;
+  Elf_Internal_Shdr *rel_hdr = reldata->hdr;
 
   /* That allows us to calculate the size of the section.  */
-  rel_hdr->sh_size = rel_hdr->sh_entsize * reloc_count;
+  rel_hdr->sh_size = rel_hdr->sh_entsize * reldata->count;
 
   /* The contents field must last into write_object_contents, so we
      allocate it with bfd_alloc rather than malloc.  Also since we
@@ -2314,19 +2310,16 @@ _bfd_elf_link_size_reloc_section (bfd *abfd,
   if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
     return FALSE;
 
-  /* We only allocate one set of hash entries, so we only do it the
-     first time we are called.  */
-  if (elf_section_data (o)->rel_hashes == NULL
-      && num_rel_hashes)
+  if (reldata->hashes == NULL && reldata->count)
     {
       struct elf_link_hash_entry **p;
 
       p = (struct elf_link_hash_entry **)
-          bfd_zmalloc (num_rel_hashes * sizeof (struct elf_link_hash_entry *));
+          bfd_zmalloc (reldata->count * sizeof (struct elf_link_hash_entry *));
       if (p == NULL)
        return FALSE;
 
-      elf_section_data (o)->rel_hashes = p;
+      reldata->hashes = p;
     }
 
   return TRUE;
@@ -2347,27 +2340,28 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
   Elf_Internal_Rela *irela;
   Elf_Internal_Rela *irelaend;
   bfd_byte *erel;
+  struct bfd_elf_section_reloc_data *output_reldata;
   Elf_Internal_Shdr *output_rel_hdr;
   asection *output_section;
-  unsigned int *rel_countp = NULL;
   const struct elf_backend_data *bed;
   void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+  struct bfd_elf_section_data *esdo;
 
   output_section = input_section->output_section;
   output_rel_hdr = NULL;
 
-  if (elf_section_data (output_section)->rel_hdr.sh_entsize
-      == input_rel_hdr->sh_entsize)
+  bed = get_elf_backend_data (output_bfd);
+  esdo = elf_section_data (output_section);
+  if (esdo->rel.hdr && esdo->rel.hdr->sh_entsize == input_rel_hdr->sh_entsize)
     {
-      output_rel_hdr = &elf_section_data (output_section)->rel_hdr;
-      rel_countp = &elf_section_data (output_section)->rel_count;
+      output_reldata = &esdo->rel;
+      swap_out = bed->s->swap_reloc_out;
     }
-  else if (elf_section_data (output_section)->rel_hdr2
-          && (elf_section_data (output_section)->rel_hdr2->sh_entsize
-              == input_rel_hdr->sh_entsize))
+  else if (esdo->rela.hdr
+          && esdo->rela.hdr->sh_entsize == input_rel_hdr->sh_entsize)
     {
-      output_rel_hdr = elf_section_data (output_section)->rel_hdr2;
-      rel_countp = &elf_section_data (output_section)->rel_count2;
+      output_reldata = &esdo->rela;
+      swap_out = bed->s->swap_reloca_out;
     }
   else
     {
@@ -2378,16 +2372,8 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
       return FALSE;
     }
 
-  bed = get_elf_backend_data (output_bfd);
-  if (input_rel_hdr->sh_entsize == bed->s->sizeof_rel)
-    swap_out = bed->s->swap_reloc_out;
-  else if (input_rel_hdr->sh_entsize == bed->s->sizeof_rela)
-    swap_out = bed->s->swap_reloca_out;
-  else
-    abort ();
-
-  erel = output_rel_hdr->contents;
-  erel += *rel_countp * input_rel_hdr->sh_entsize;
+  erel = output_reldata->hdr->contents;
+  erel += output_reldata->count * input_rel_hdr->sh_entsize;
   irela = internal_relocs;
   irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
                      * bed->s->int_rels_per_ext_rel);
@@ -2400,7 +2386,7 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
 
   /* Bump the counter, so that we know where to add the next set of
      relocations.  */
-  *rel_countp += NUM_SHDR_ENTRIES (input_rel_hdr);
+  output_reldata->count += NUM_SHDR_ENTRIES (input_rel_hdr);
 
   return TRUE;
 }
@@ -7928,14 +7914,12 @@ bfd_elf_perform_complex_relocation (bfd *input_bfd,
 
 /* When performing a relocatable link, the input relocations are
    preserved.  But, if they reference global symbols, the indices
-   referenced must be updated.  Update all the relocations in
-   REL_HDR (there are COUNT of them), using the data in REL_HASH.  */
+   referenced must be updated.  Update all the relocations found in
+   RELDATA.  */
 
 static void
 elf_link_adjust_relocs (bfd *abfd,
-                       Elf_Internal_Shdr *rel_hdr,
-                       unsigned int count,
-                       struct elf_link_hash_entry **rel_hash)
+                       struct bfd_elf_section_reloc_data *reldata)
 {
   unsigned int i;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
@@ -7944,13 +7928,15 @@ elf_link_adjust_relocs (bfd *abfd,
   void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
   bfd_vma r_type_mask;
   int r_sym_shift;
+  unsigned int count = reldata->count;
+  struct elf_link_hash_entry **rel_hash = reldata->hashes;
 
-  if (rel_hdr->sh_entsize == bed->s->sizeof_rel)
+  if (reldata->hdr->sh_entsize == bed->s->sizeof_rel)
     {
       swap_in = bed->s->swap_reloc_in;
       swap_out = bed->s->swap_reloc_out;
     }
-  else if (rel_hdr->sh_entsize == bed->s->sizeof_rela)
+  else if (reldata->hdr->sh_entsize == bed->s->sizeof_rela)
     {
       swap_in = bed->s->swap_reloca_in;
       swap_out = bed->s->swap_reloca_out;
@@ -7972,8 +7958,8 @@ elf_link_adjust_relocs (bfd *abfd,
       r_sym_shift = 32;
     }
 
-  erela = rel_hdr->contents;
-  for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize)
+  erela = reldata->hdr->contents;
+  for (i = 0; i < count; i++, rel_hash++, erela += reldata->hdr->sh_entsize)
     {
       Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL];
       unsigned int j;
@@ -9563,27 +9549,32 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
              || finfo->info->emitrelocations)
            {
              Elf_Internal_Rela *irela;
-             Elf_Internal_Rela *irelaend;
+             Elf_Internal_Rela *irelaend, *irelamid;
              bfd_vma last_offset;
              struct elf_link_hash_entry **rel_hash;
-             struct elf_link_hash_entry **rel_hash_list;
-             Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2;
+             struct elf_link_hash_entry **rel_hash_list, **rela_hash_list;
+             Elf_Internal_Shdr *input_rel_hdr, *input_rela_hdr;
              unsigned int next_erel;
              bfd_boolean rela_normal;
+             struct bfd_elf_section_data *esdi, *esdo;
 
-             input_rel_hdr = &elf_section_data (o)->rel_hdr;
-             rela_normal = (bed->rela_normal
-                            && (input_rel_hdr->sh_entsize
-                                == bed->s->sizeof_rela));
+             esdi = elf_section_data (o);
+             esdo = elf_section_data (o->output_section);
+             rela_normal = FALSE;
 
              /* Adjust the reloc addresses and symbol indices.  */
 
              irela = internal_relocs;
              irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel;
-             rel_hash = (elf_section_data (o->output_section)->rel_hashes
-                         + elf_section_data (o->output_section)->rel_count
-                         + elf_section_data (o->output_section)->rel_count2);
+             rel_hash = esdo->rel.hashes + esdo->rel.count;
+             /* We start processing the REL relocs, if any.  When we reach
+                IRELAMID in the loop, we switch to the RELA relocs.  */
+             irelamid = irela;
+             if (esdi->rel.hdr != NULL)
+               irelamid += (NUM_SHDR_ENTRIES (esdi->rel.hdr)
+                            * bed->s->int_rels_per_ext_rel);
              rel_hash_list = rel_hash;
+             rela_hash_list = NULL;
              last_offset = o->output_offset;
              if (!finfo->info->relocatable)
                last_offset += o->output_section->vma;
@@ -9599,6 +9590,13 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                      next_erel = 0;
                    }
 
+                 if (irela == irelamid)
+                   {
+                     rel_hash = esdo->rela.hashes + esdo->rela.count;
+                     rela_hash_list = rel_hash;
+                     rela_normal = bed->rela_normal;
+                   }
+
                  irela->r_offset = _bfd_elf_section_offset (output_bfd,
                                                             finfo->info, o,
                                                             irela->r_offset);
@@ -9790,23 +9788,26 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                }
 
              /* Swap out the relocs.  */
-             if (input_rel_hdr->sh_size != 0
-                 && !bed->elf_backend_emit_relocs (output_bfd, o,
-                                                   input_rel_hdr,
-                                                   internal_relocs,
-                                                   rel_hash_list))
-               return FALSE;
-
-             input_rel_hdr2 = elf_section_data (o)->rel_hdr2;
-             if (input_rel_hdr2 && input_rel_hdr2->sh_size != 0)
+             input_rel_hdr = esdi->rel.hdr;
+             if (input_rel_hdr && input_rel_hdr->sh_size != 0)
                {
+                 if (!bed->elf_backend_emit_relocs (output_bfd, o,
+                                                    input_rel_hdr,
+                                                    internal_relocs,
+                                                    rel_hash_list))
+                   return FALSE;
                  internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
                                      * bed->s->int_rels_per_ext_rel);
                  rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr);
+               }
+
+             input_rela_hdr = esdi->rela.hdr;
+             if (input_rela_hdr && input_rela_hdr->sh_size != 0)
+               {
                  if (!bed->elf_backend_emit_relocs (output_bfd, o,
-                                                    input_rel_hdr2,
+                                                    input_rela_hdr,
                                                     internal_relocs,
-                                                    rel_hash_list))
+                                                    rela_hash_list))
                    return FALSE;
                }
            }
@@ -9872,12 +9873,14 @@ elf_reloc_link_order (bfd *output_bfd,
   long indx;
   bfd_vma offset;
   bfd_vma addend;
+  struct bfd_elf_section_reloc_data *reldata;
   struct elf_link_hash_entry **rel_hash_ptr;
   Elf_Internal_Shdr *rel_hdr;
   const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
   Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL];
   bfd_byte *erel;
   unsigned int i;
+  struct bfd_elf_section_data *esdo = elf_section_data (output_section);
 
   howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
   if (howto == NULL)
@@ -9888,10 +9891,18 @@ elf_reloc_link_order (bfd *output_bfd,
 
   addend = link_order->u.reloc.p->addend;
 
+  if (esdo->rel.hdr)
+    reldata = &esdo->rel;
+  else if (esdo->rela.hdr)
+    reldata = &esdo->rela;
+  else
+    {
+      reldata = NULL;
+      BFD_ASSERT (0);
+    }
+
   /* Figure out the symbol index.  */
-  rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
-                 + elf_section_data (output_section)->rel_count
-                 + elf_section_data (output_section)->rel_count2);
+  rel_hash_ptr = reldata->hashes + reldata->count;
   if (link_order->type == bfd_section_reloc_link_order)
     {
       indx = link_order->u.reloc.p->u.section->target_index;
@@ -10003,23 +10014,21 @@ elf_reloc_link_order (bfd *output_bfd,
   else
     irel[0].r_info = ELF64_R_INFO (indx, howto->type);
 
-  rel_hdr = &elf_section_data (output_section)->rel_hdr;
+  rel_hdr = reldata->hdr;
   erel = rel_hdr->contents;
   if (rel_hdr->sh_type == SHT_REL)
     {
-      erel += (elf_section_data (output_section)->rel_count
-              * bed->s->sizeof_rel);
+      erel += reldata->count * bed->s->sizeof_rel;
       (*bed->s->swap_reloc_out) (output_bfd, irel, erel);
     }
   else
     {
       irel[0].r_addend = addend;
-      erel += (elf_section_data (output_section)->rel_count
-              * bed->s->sizeof_rela);
+      erel += reldata->count * bed->s->sizeof_rela;
       (*bed->s->swap_reloca_out) (output_bfd, irel, erel);
     }
 
-  ++elf_section_data (output_section)->rel_count;
+  ++reldata->count;
 
   return TRUE;
 }
@@ -10305,7 +10314,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
        {
          unsigned int reloc_count = 0;
          struct bfd_elf_section_data *esdi = NULL;
-         unsigned int *rel_count1;
 
          if (p->type == bfd_section_reloc_link_order
              || p->type == bfd_symbol_reloc_link_order)
@@ -10358,11 +10366,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
                  if ((sec->flags & SEC_RELOC) != 0)
                    {
-                     size_t ext_size;
+                     size_t ext_size = 0;
 
-                     ext_size = esdi->rel_hdr.sh_size;
-                     if (esdi->rel_hdr2 != NULL)
-                       ext_size += esdi->rel_hdr2->sh_size;
+                     if (esdi->rel.hdr != NULL)
+                       ext_size = esdi->rel.hdr->sh_size;
+                     if (esdi->rela.hdr != NULL)
+                       ext_size += esdi->rela.hdr->sh_size;
 
                      if (ext_size > max_external_reloc_size)
                        max_external_reloc_size = ext_size;
@@ -10377,54 +10386,21 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
          o->reloc_count += reloc_count;
 
-         /* MIPS may have a mix of REL and RELA relocs on sections.
-            To support this curious ABI we keep reloc counts in
-            elf_section_data too.  We must be careful to add the
-            relocations from the input section to the right output
-            count.  FIXME: Get rid of one count.  We have
-            o->reloc_count == esdo->rel_count + esdo->rel_count2.  */
-         rel_count1 = &esdo->rel_count;
-         if (esdi != NULL)
+         if (p->type == bfd_indirect_link_order
+             && (info->relocatable || info->emitrelocations))
            {
-             bfd_boolean same_size;
-             bfd_size_type entsize1;
-
-             entsize1 = esdi->rel_hdr.sh_entsize;
-             /* PR 9827: If the header size has not been set yet then
-                assume that it will match the output section's reloc type.  */
-             if (entsize1 == 0)
-               entsize1 = o->use_rela_p ? bed->s->sizeof_rela : bed->s->sizeof_rel;
+             if (esdi->rel.hdr)
+               esdo->rel.count += NUM_SHDR_ENTRIES (esdi->rel.hdr);
+             if (esdi->rela.hdr)
+               esdo->rela.count += NUM_SHDR_ENTRIES (esdi->rela.hdr);
+           }
+         else
+           {
+             if (o->use_rela_p)
+               esdo->rela.count += reloc_count;
              else
-               BFD_ASSERT (entsize1 == bed->s->sizeof_rel
-                           || entsize1 == bed->s->sizeof_rela);
-             same_size = !o->use_rela_p == (entsize1 == bed->s->sizeof_rel);
-
-             if (!same_size)
-               rel_count1 = &esdo->rel_count2;
-
-             if (esdi->rel_hdr2 != NULL)
-               {
-                 bfd_size_type entsize2 = esdi->rel_hdr2->sh_entsize;
-                 unsigned int alt_count;
-                 unsigned int *rel_count2;
-
-                 BFD_ASSERT (entsize2 != entsize1
-                             && (entsize2 == bed->s->sizeof_rel
-                                 || entsize2 == bed->s->sizeof_rela));
-
-                 rel_count2 = &esdo->rel_count2;
-                 if (!same_size)
-                   rel_count2 = &esdo->rel_count;
-
-                 /* The following is probably too simplistic if the
-                    backend counts output relocs unusually.  */
-                 BFD_ASSERT (bed->elf_backend_count_relocs == NULL);
-                 alt_count = NUM_SHDR_ENTRIES (esdi->rel_hdr2);
-                 *rel_count2 += alt_count;
-                 reloc_count -= alt_count;
-               }
+               esdo->rel.count += reloc_count;
            }
-         *rel_count1 += reloc_count;
        }
 
       if (o->reloc_count > 0)
@@ -10461,22 +10437,22 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   /* Set sizes, and assign file positions for reloc sections.  */
   for (o = abfd->sections; o != NULL; o = o->next)
     {
+      struct bfd_elf_section_data *esdo = elf_section_data (o);
       if ((o->flags & SEC_RELOC) != 0)
        {
-         if (!(_bfd_elf_link_size_reloc_section
-               (abfd, &elf_section_data (o)->rel_hdr, o)))
+         if (esdo->rel.hdr
+             && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rel)))
            goto error_return;
 
-         if (elf_section_data (o)->rel_hdr2
-             && !(_bfd_elf_link_size_reloc_section
-                  (abfd, elf_section_data (o)->rel_hdr2, o)))
+         if (esdo->rela.hdr
+             && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rela)))
            goto error_return;
        }
 
       /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them
         to count upwards while actually outputting the relocations.  */
-      elf_section_data (o)->rel_count = 0;
-      elf_section_data (o)->rel_count2 = 0;
+      esdo->rel.count = 0;
+      esdo->rela.count = 0;
     }
 
   _bfd_elf_assign_file_positions_for_relocs (abfd);
@@ -10908,17 +10884,14 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   /* Adjust the relocs to have the correct symbol indices.  */
   for (o = abfd->sections; o != NULL; o = o->next)
     {
+      struct bfd_elf_section_data *esdo = elf_section_data (o);
       if ((o->flags & SEC_RELOC) == 0)
        continue;
 
-      elf_link_adjust_relocs (abfd, &elf_section_data (o)->rel_hdr,
-                             elf_section_data (o)->rel_count,
-                             elf_section_data (o)->rel_hashes);
-      if (elf_section_data (o)->rel_hdr2 != NULL)
-       elf_link_adjust_relocs (abfd, elf_section_data (o)->rel_hdr2,
-                               elf_section_data (o)->rel_count2,
-                               (elf_section_data (o)->rel_hashes
-                                + elf_section_data (o)->rel_count));
+      if (esdo->rel.hdr != NULL)
+       elf_link_adjust_relocs (abfd, &esdo->rel);
+      if (esdo->rela.hdr != NULL)
+       elf_link_adjust_relocs (abfd, &esdo->rela);
 
       /* Set the reloc_count field to 0 to prevent write_relocs from
         trying to swap the relocs out itself.  */
@@ -11213,9 +11186,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
     free (finfo.symshndxbuf);
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      if ((o->flags & SEC_RELOC) != 0
-         && elf_section_data (o)->rel_hashes != NULL)
-       free (elf_section_data (o)->rel_hashes);
+      struct bfd_elf_section_data *esdo = elf_section_data (o);
+      if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL)
+       free (esdo->rel.hashes);
+      if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL)
+       free (esdo->rela.hashes);
     }
 
   elf_tdata (abfd)->linker = TRUE;
@@ -11257,9 +11232,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
     free (finfo.symshndxbuf);
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      if ((o->flags & SEC_RELOC) != 0
-         && elf_section_data (o)->rel_hashes != NULL)
-       free (elf_section_data (o)->rel_hashes);
+      struct bfd_elf_section_data *esdo = elf_section_data (o);
+      if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL)
+       free (esdo->rel.hashes);
+      if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL)
+       free (esdo->rela.hashes);
     }
 
   return FALSE;
@@ -12603,7 +12580,7 @@ get_dynamic_reloc_section_name (bfd *       abfd,
 {
   const char * name;
   unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
-  unsigned int shnam = elf_section_data (sec)->rel_hdr.sh_name;
+  unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name;
 
   name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
   if (name == NULL)
index d78090983863065a6409b8c7ceb855e0111290a0..6b52bc6d71334733eb627c432835b536fbc75f1e 100644 (file)
@@ -2598,7 +2598,7 @@ get_reloc_section (bfd *abfd,
 
   srel_name = (bfd_elf_string_from_elf_section
               (abfd, elf_elfheader(abfd)->e_shstrndx,
-               elf_section_data(sec)->rel_hdr.sh_name));
+               _bfd_elf_single_rel_hdr (sec)->sh_name));
   if (srel_name == NULL)
     return NULL;
 
index a32a61371b947eb396cf6ce8d80507d9193fdf1b..8feb5c483794d022a43631e75c1aa740483ae502 100644 (file)
@@ -783,23 +783,6 @@ static bfd *reldyn_sorting_bfd;
 #define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela)                     \
   (get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela))
 
-/* Determine whether the internal relocation of index REL_IDX is REL
-   (zero) or RELA (non-zero).  The assumption is that, if there are
-   two relocation sections for this section, one of them is REL and
-   the other is RELA.  If the index of the relocation we're testing is
-   in range for the first relocation section, check that the external
-   relocation size is that for RELA.  It is also assumed that, if
-   rel_idx is not in range for the first section, and this first
-   section contains REL relocs, then the relocation is in the second
-   section, that is RELA.  */
-#define MIPS_RELOC_RELA_P(abfd, sec, rel_idx)                          \
-  ((NUM_SHDR_ENTRIES (&elf_section_data (sec)->rel_hdr)                        \
-    * get_elf_backend_data (abfd)->s->int_rels_per_ext_rel             \
-    > (bfd_vma)(rel_idx))                                              \
-   == (elf_section_data (sec)->rel_hdr.sh_entsize                      \
-       == (ABI_64_P (abfd) ? sizeof (Elf64_External_Rela)              \
-          : sizeof (Elf32_External_Rela))))
-
 /* The name of the dynamic relocation section.  */
 #define MIPS_ELF_REL_DYN_NAME(INFO) \
   (mips_elf_hash_table (INFO)->is_vxworks ? ".rela.dyn" : ".rel.dyn")
@@ -7110,14 +7093,14 @@ mips_elf_rel_relocation_p (bfd *abfd, asection *sec,
   Elf_Internal_Shdr *rel_hdr;
   const struct elf_backend_data *bed;
 
-  /* To determine which flavor or relocation this is, we depend on the
-     fact that the INPUT_SECTION's REL_HDR is read before its REL_HDR2.  */
-  rel_hdr = &elf_section_data (sec)->rel_hdr;
+  /* To determine which flavor of relocation this is, we depend on the
+     fact that the INPUT_SECTION's REL_HDR is read before RELA_HDR.  */
+  rel_hdr = elf_section_data (sec)->rel.hdr;
+  if (rel_hdr == NULL)
+    return FALSE;
   bed = get_elf_backend_data (abfd);
-  if ((size_t) (rel - relocs)
-      >= (NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel))
-    rel_hdr = elf_section_data (sec)->rel_hdr2;
-  return rel_hdr->sh_entsize == MIPS_ELF_REL_SIZE (abfd);
+  return ((size_t) (rel - relocs)
+         < NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel);
 }
 
 /* Read the addend for REL relocation REL, which belongs to bfd ABFD.
@@ -8983,13 +8966,13 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
       asection *sec;
       Elf_Internal_Shdr *symtab_hdr;
       struct elf_link_hash_entry *h;
+      bfd_boolean rel_reloc;
 
+      rel_reloc = (NEWABI_P (input_bfd)
+                  && mips_elf_rel_relocation_p (input_bfd, input_section,
+                                                relocs, rel));
       /* Find the relocation howto for this relocation.  */
-      howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type,
-                                      NEWABI_P (input_bfd)
-                                      && (MIPS_RELOC_RELA_P
-                                          (input_bfd, input_section,
-                                           rel - relocs)));
+      howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type, !rel_reloc);
 
       r_symndx = ELF_R_SYM (input_bfd, rel->r_info);
       symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
index 58b18904a614efbdd6bc1a91f1f287920cbdde68..979505a79cd38b0a324540ac3a6b78176a0211b8 100644 (file)
@@ -1343,7 +1343,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
   sreloc = NULL;
 
   if (ABI_64_P (abfd))
-    num_relocs = NUM_SHDR_ENTRIES (& elf_section_data (sec)->rel_hdr);
+    num_relocs = NUM_SHDR_ENTRIES (_bfd_elf_single_rel_hdr (sec));
   else
     num_relocs = sec->reloc_count;
 
@@ -2884,7 +2884,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 
   rel = relocs;
   if (ABI_64_P (output_bfd))
-    num_relocs = NUM_SHDR_ENTRIES (& elf_section_data (input_section)->rel_hdr);
+    num_relocs = NUM_SHDR_ENTRIES (_bfd_elf_single_rel_hdr (input_section));
   else
     num_relocs = input_section->reloc_count;
   relend = relocs + num_relocs;
index 4f64be44f7339d2ad704299882c1c15d0eb29958..38b2f58fb4dbbf7de1e8a466a0b73ec0f87c980f 100644 (file)
@@ -1,3 +1,8 @@
+2010-10-04  Bernd Schmidt  <bernds@codesourcery.com>
+
+       * emultempl/xtensaelf.em (replace_insn_sec_with_prop_sec): Use
+       _bfd_elf_single_rel_hdr.
+
 2010-10-01  Alan Modra  <amodra@gmail.com>
 
        PR ld/12066
index 38c4f0432b9a82f1118456d4211003d76c5ad7f7..b7da721d9a6d01dcfc70bf9a4ba2a7996dc789b4 100644 (file)
@@ -98,6 +98,7 @@ replace_insn_sec_with_prop_sec (bfd *abfd,
   bfd_byte *insn_contents = NULL;
   unsigned entry_count;
   unsigned entry;
+  Elf_Internal_Shdr *rel_hdr;
   Elf_Internal_Rela *internal_relocs = NULL;
   unsigned reloc_count;
 
@@ -147,10 +148,9 @@ replace_insn_sec_with_prop_sec (bfd *abfd,
 
   /* The entry size and size must be set to allow the linker to compute
      the number of relocations since it does not use reloc_count.  */
-  elf_section_data (prop_sec)->rel_hdr.sh_entsize =
-    sizeof (Elf32_External_Rela);
-  elf_section_data (prop_sec)->rel_hdr.sh_size =
-    elf_section_data (insn_sec)->rel_hdr.sh_size;
+  rel_hdr = _bfd_elf_single_rel_hdr (prop_sec);
+  rel_hdr->sh_entsize = sizeof (Elf32_External_Rela);
+  rel_hdr->sh_size = _bfd_elf_single_rel_hdr (insn_sec)->sh_size;
 
   if (prop_contents == NULL && prop_sec->size != 0)
     {