This is the mail archive of the binutils-cvs@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]

[binutils-gdb] ELF/BFD: Hold the number of internal static relocs in `->reloc_count'


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=056bafd472efccfb2d7f44f6469dfa08cdf7414b

commit 056bafd472efccfb2d7f44f6469dfa08cdf7414b
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Tue Jun 6 01:24:06 2017 +0100

    ELF/BFD: Hold the number of internal static relocs in `->reloc_count'
    
    Correct a commit e5713223cbc1 ("MIPS/BFD: For n64 hold the number of
    internal relocs in `->reloc_count'") regression and change internal
    relocation handling in the generic ELF BFD linker code such that, except
    in the presence of R_SPARC_OLO10 relocations, a section's `reloc_count'
    holds the number of internal rather than external relocations, making
    the handling more consistent between GAS, which sets `->reloc_count'
    with a call to `bfd_set_reloc', and LD, which sets `->reloc_count' as it
    reads input sections.
    
    The handling of dynamic relocations remains unchanged and they continue
    holding the number of external relocations in `->reloc_count'; they are
    also not converted to the internal form except in `elf_link_sort_relocs'
    (which does not handle the general, i.e. non-n64-MIPS case of composed
    relocations correctly as per the ELF gABI, though it does not seem to
    matter for the targets we currently support).
    
    The n64 MIPS backend is the only one with `int_rels_per_ext_rel' set to
    non-one, and consequently the change is trivial for all the remaining
    backends and targets.
    
    	bfd/
    	* elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Subtract `count'
    	from `reloc_count' rather than decrementing it.
    	* elf.c (bfd_section_from_shdr): Multiply the adjustment to
    	`reloc_count' by `int_rels_per_ext_rel'.
    	* elf32-score.c (score_elf_final_link_relocate): Do not multiply
    	`reloc_count' by `int_rels_per_ext_rel' for last relocation
    	entry determination.
    	(s3_bfd_score_elf_check_relocs): Likewise.
    	* elf32-score7.c (score_elf_final_link_relocate): Likewise.
    	(s7_bfd_score_elf_relocate_section): Likewise.
    	(s7_bfd_score_elf_check_relocs): Likewise.
    	* elf64-mips.c (mips_elf64_get_reloc_upper_bound): Remove
    	prototype and function.
    	(mips_elf64_slurp_one_reloc_table): Do not update `reloc_count'.
    	(mips_elf64_slurp_reloc_table): Assert that `reloc_count' is
    	triple rather than once the sum of REL and RELA relocation entry
    	counts.
    	(bfd_elf64_get_reloc_upper_bound): Remove macro.
    	* elflink.c (_bfd_elf_link_read_relocs): Do not multiply
    	`reloc_count' by `int_rels_per_ext_rel' for internal relocation
    	storage allocation size determination.
    	(elf_link_input_bfd): Multiply `.ctors' and `.dtors' section's
    	size by `int_rels_per_ext_rel'.  Do not multiply `reloc_count'
    	by `int_rels_per_ext_rel' for last relocation entry
    	determination.
    	(bfd_elf_final_link): Do not multiply `reloc_count' by
    	`int_rels_per_ext_rel' for internal relocation storage
    	allocation size determination.
    	(init_reloc_cookie_rels): Do not multiply `reloc_count' by
    	`int_rels_per_ext_rel' for last relocation entry determination.
    	(elf_gc_smash_unused_vtentry_relocs): Likewise.
    	* elfxx-mips.c (_bfd_mips_elf_check_relocs): Likewise.
    	(_bfd_mips_elf_relocate_section): Likewise.

Diff:
---
 bfd/ChangeLog      | 36 ++++++++++++++++++++++++++++++++++++
 bfd/elf-bfd.h      |  2 +-
 bfd/elf.c          |  3 ++-
 bfd/elf32-score.c  |  4 ++--
 bfd/elf32-score7.c |  8 ++++----
 bfd/elf64-mips.c   | 19 ++-----------------
 bfd/elflink.c      | 18 ++++++++----------
 bfd/elfxx-mips.c   |  4 ++--
 8 files changed, 57 insertions(+), 37 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f4a6afa..a138535 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,39 @@
+2017-06-06  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Subtract `count'
+	from `reloc_count' rather than decrementing it.
+	* elf.c (bfd_section_from_shdr): Multiply the adjustment to
+	`reloc_count' by `int_rels_per_ext_rel'.
+	* elf32-score.c (score_elf_final_link_relocate): Do not multiply
+	`reloc_count' by `int_rels_per_ext_rel' for last relocation
+	entry determination.
+	(s3_bfd_score_elf_check_relocs): Likewise.
+	* elf32-score7.c (score_elf_final_link_relocate): Likewise.
+	(s7_bfd_score_elf_relocate_section): Likewise.
+	(s7_bfd_score_elf_check_relocs): Likewise.
+	* elf64-mips.c (mips_elf64_get_reloc_upper_bound): Remove
+	prototype and function.
+	(mips_elf64_slurp_one_reloc_table): Do not update `reloc_count'.
+	(mips_elf64_slurp_reloc_table): Assert that `reloc_count' is
+	triple rather than once the sum of REL and RELA relocation entry
+	counts.
+	(bfd_elf64_get_reloc_upper_bound): Remove macro.
+	* elflink.c (_bfd_elf_link_read_relocs): Do not multiply
+	`reloc_count' by `int_rels_per_ext_rel' for internal relocation
+	storage allocation size determination.
+	(elf_link_input_bfd): Multiply `.ctors' and `.dtors' section's
+	size by `int_rels_per_ext_rel'.  Do not multiply `reloc_count'
+	by `int_rels_per_ext_rel' for last relocation entry
+	determination.
+	(bfd_elf_final_link): Do not multiply `reloc_count' by
+	`int_rels_per_ext_rel' for internal relocation storage
+	allocation size determination.
+	(init_reloc_cookie_rels): Do not multiply `reloc_count' by
+	`int_rels_per_ext_rel' for last relocation entry determination.
+	(elf_gc_smash_unused_vtentry_relocs): Likewise.
+	* elfxx-mips.c (_bfd_mips_elf_check_relocs): Likewise.
+	(_bfd_mips_elf_relocate_section): Likewise.
+
 2017-06-05  Alan Modra  <amodra@gmail.com>
 
 	PR 21529
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 4110ace..820bc98 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2767,7 +2767,7 @@ extern asection _bfd_elf_large_com_section;
 	    memmove (rel, rel + count,					\
 		     (relend - rel - count) * sizeof (*rel));		\
 									\
-	    input_section->reloc_count--;				\
+	    input_section->reloc_count -= count;			\
 	    relend -= count;						\
 	    rel--;							\
 	    continue;							\
diff --git a/bfd/elf.c b/bfd/elf.c
index 34d39c5..b0da500 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2374,7 +2374,8 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
 	*hdr2 = *hdr;
 	*p_hdr = hdr2;
 	elf_elfsections (abfd)[shindex] = hdr2;
-	target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr);
+	target_sect->reloc_count += (NUM_SHDR_ENTRIES (hdr)
+				     * bed->s->int_rels_per_ext_rel);
 	target_sect->flags |= SEC_RELOC;
 	target_sect->relocation = NULL;
 	target_sect->rel_filepos = hdr->sh_offset;
diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c
index 4468276..a8914e6 100644
--- a/bfd/elf32-score.c
+++ b/bfd/elf32-score.c
@@ -2038,7 +2038,7 @@ score_elf_final_link_relocate (reloc_howto_type *howto,
       bfd_vma lo_value = 0;
 
       bed = get_elf_backend_data (output_bfd);
-      relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+      relend = relocs + input_section->reloc_count;
       lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
       if ((local_p) && (lo16_rel != NULL))
         {
@@ -2808,7 +2808,7 @@ s3_bfd_score_elf_check_relocs (bfd *abfd,
 
   sreloc = NULL;
   bed = get_elf_backend_data (abfd);
-  rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
+  rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; ++rel)
     {
       unsigned long r_symndx;
diff --git a/bfd/elf32-score7.c b/bfd/elf32-score7.c
index abf9b32..5075fa4 100644
--- a/bfd/elf32-score7.c
+++ b/bfd/elf32-score7.c
@@ -1906,7 +1906,7 @@ score_elf_final_link_relocate (reloc_howto_type *howto,
       bfd_vma lo_value = 0;
 
       bed = get_elf_backend_data (output_bfd);
-      relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+      relend = relocs + input_section->reloc_count;
       lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
       if ((local_p) && (lo16_rel != NULL))
         {
@@ -1944,7 +1944,7 @@ score_elf_final_link_relocate (reloc_howto_type *howto,
             addend |= 0xffffc000;
 
           bed = get_elf_backend_data (output_bfd);
-          relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+          relend = relocs + input_section->reloc_count;
           lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
           if ((local_p) && (lo16_rel != NULL))
             {
@@ -2481,7 +2481,7 @@ s7_bfd_score_elf_relocate_section (bfd *output_bfd,
                     addend |= 0xffffc000;
 
                   bed = get_elf_backend_data (output_bfd);
-                  relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+                  relend = relocs + input_section->reloc_count;
                   lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
                   if (lo16_rel != NULL)
                     {
@@ -2617,7 +2617,7 @@ s7_bfd_score_elf_check_relocs (bfd *abfd,
 
   sreloc = NULL;
   bed = get_elf_backend_data (abfd);
-  rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
+  rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; ++rel)
     {
       unsigned long r_symndx;
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index e95db2c..84f2a3f 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -86,8 +86,6 @@ static void mips_elf64_info_to_howto_rel
   (bfd *, arelent *, Elf_Internal_Rela *);
 static void mips_elf64_info_to_howto_rela
   (bfd *, arelent *, Elf_Internal_Rela *);
-static long mips_elf64_get_reloc_upper_bound
-  (bfd *, asection *);
 static long mips_elf64_get_dynamic_reloc_upper_bound
   (bfd *);
 static bfd_boolean mips_elf64_slurp_one_reloc_table
@@ -3648,12 +3646,6 @@ mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
    to three relocs, we must tell the user to allocate more space.  */
 
 static long
-mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
-{
-  return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
-}
-
-static long
 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
 {
   return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
@@ -3819,8 +3811,6 @@ mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
 	}
     }
 
-  asect->reloc_count += relent - relents;
-
   if (allocated != NULL)
     free (allocated);
 
@@ -3835,8 +3825,7 @@ mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
 /* Read the relocations.  On Irix 6, there can be two reloc sections
    associated with a single data section.  This is copied from
    elfcode.h as well, with changes as small as accounting for 3
-   internal relocs per external reloc and resetting reloc_count to
-   zero before processing the relocs of a section.  */
+   internal relocs per external reloc.  */
 
 static bfd_boolean
 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
@@ -3864,7 +3853,7 @@ mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
       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->reloc_count == 3 * (reloc_count + reloc_count2));
       BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
 		  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
 
@@ -3890,9 +3879,6 @@ mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
   if (relents == NULL)
     return FALSE;
 
-  /* The slurp_one_reloc_table routine increments reloc_count.  */
-  asect->reloc_count = 0;
-
   if (rel_hdr != NULL
       && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
 					     rel_hdr, reloc_count,
@@ -4437,7 +4423,6 @@ const struct elf_size_info mips_elf64_size_info =
 #define bfd_elf64_bfd_print_private_bfd_data \
 				_bfd_mips_elf_print_private_bfd_data
 
-#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
 #define bfd_elf64_mkobject		_bfd_mips_elf_mkobject
 
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 71da4c9..07d3ea5 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -2450,8 +2450,7 @@ _bfd_elf_link_read_relocs (bfd *abfd,
     {
       bfd_size_type size;
 
-      size = o->reloc_count;
-      size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela);
+      size = (bfd_size_type) o->reloc_count * sizeof (Elf_Internal_Rela);
       if (keep_memory)
 	internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_alloc (abfd, size);
       else
@@ -10402,7 +10401,8 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 				 ".fini_array") == 0))
 	      && (o->name[6] == 0 || o->name[6] == '.'))
 	    {
-	      if (o->size != o->reloc_count * address_size)
+	      if (o->size * bed->s->int_rels_per_ext_rel
+		  != o->reloc_count * address_size)
 		{
 		  _bfd_error_handler
 		    /* xgettext:c-format */
@@ -10426,7 +10426,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 	     relocs against removed link-once sections.  */
 
 	  rel = internal_relocs;
-	  relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
+	  relend = rel + o->reloc_count;
 	  for ( ; rel < relend; rel++)
 	    {
 	      unsigned long r_symndx = rel->r_info >> r_sym_shift;
@@ -10615,7 +10615,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 	      /* Adjust the reloc addresses and symbol indices.  */
 
 	      irela = internal_relocs;
-	      irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel;
+	      irelaend = irela + o->reloc_count;
 	      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.  */
@@ -11789,8 +11789,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
   if (max_internal_reloc_count != 0)
     {
-      amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel;
-      amt *= sizeof (Elf_Internal_Rela);
+      amt = max_internal_reloc_count * sizeof (Elf_Internal_Rela);
       flinfo.internal_relocs = (Elf_Internal_Rela *) bfd_malloc (amt);
       if (flinfo.internal_relocs == NULL)
 	goto error_return;
@@ -12589,8 +12588,7 @@ init_reloc_cookie_rels (struct elf_reloc_cookie *cookie,
       if (cookie->rels == NULL)
 	return FALSE;
       cookie->rel = cookie->rels;
-      cookie->relend = (cookie->rels
-			+ sec->reloc_count * bed->s->int_rels_per_ext_rel);
+      cookie->relend = cookie->rels + sec->reloc_count;
     }
   cookie->rel = cookie->rels;
   return TRUE;
@@ -13203,7 +13201,7 @@ elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp)
   bed = get_elf_backend_data (sec->owner);
   log_file_align = bed->s->log_file_align;
 
-  relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
+  relend = relstart + sec->reloc_count;
 
   for (rel = relstart; rel < relend; ++rel)
     if (rel->r_offset >= hstart && rel->r_offset < hend)
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index cbf39c0..1ef27f6 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -8102,7 +8102,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
   extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
 
   bed = get_elf_backend_data (abfd);
-  rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
+  rel_end = relocs + sec->reloc_count;
 
   /* Check for the mips16 stub sections.  */
 
@@ -10034,7 +10034,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
   const struct elf_backend_data *bed;
 
   bed = get_elf_backend_data (output_bfd);
-  relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+  relend = relocs + input_section->reloc_count;
   for (rel = relocs; rel < relend; ++rel)
     {
       const char *name;


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