[03/10] elf: Extract _bfd_elf_process_reverse_copy

Message ID 20220107190631.309790-4-hjl.tools@gmail.com
State Superseded
Headers
Series ld: Implement DT_RELR for x86 |

Checks

Context Check Description
dj/TryBot-apply_patch fail Patch failed to apply to master at the time it was sent

Commit Message

H.J. Lu Jan. 7, 2022, 7:06 p.m. UTC
  Extract _bfd_elf_process_reverse_copy from elf_link_input_bfd so that
it can be called in check_relocs to set SEC_ELF_REVERSE_COPY before
elf_link_input_bfd is called.

	* elf-bfd.h (_bfd_elf_process_reverse_copy): New prototype.
	* elflink.c (_bfd_elf_process_reverse_copy): New.  Extracted
	from elf_link_input_bfd.
	(elf_link_input_bfd): Call _bfd_elf_process_reverse_copy.
---
 bfd/elf-bfd.h |  2 ++
 bfd/elflink.c | 60 ++++++++++++++++++++++++++++++++-------------------
 2 files changed, 40 insertions(+), 22 deletions(-)
  

Patch

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 81f8fd47db7..2441b3c0cd7 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2331,6 +2331,8 @@  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
   (bfd *, asection *);
+extern bool _bfd_elf_process_reverse_copy (asection *, unsigned int,
+					   unsigned int);
 
 extern bool _bfd_elf_link_hide_sym_by_version
   (struct bfd_link_info *, struct elf_link_hash_entry *);
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 059461b5725..29ef9ddf8b9 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -10851,6 +10851,41 @@  _bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info)
   return kept;
 }
 
+/* Set SEC_ELF_REVERSE_COPY on section S when we need to reverse-copy
+   input .ctors/.dtors sections if they are placed in .init_array or
+   .finit_array for output.  ADDRESS_SIZE is address in bytes.
+   INT_RELS_PER_EXT_REL is the number of internal relocations to
+   allocate per external relocation entry.  */
+
+bool
+_bfd_elf_process_reverse_copy (asection *s, unsigned int address_size,
+			       unsigned int int_rels_per_ext_rel)
+{
+  if (s->size <= address_size
+      || (s->flags & SEC_ELF_REVERSE_COPY) != 0)
+    return true;
+
+  if (((startswith (s->name, ".ctors")
+	&& strcmp (s->output_section->name, ".init_array") == 0)
+       || (startswith (s->name, ".dtors")
+	   && strcmp (s->output_section->name, ".fini_array") == 0))
+      && (s->name[6] == 0 || s->name[6] == '.'))
+    {
+      if (s->size * int_rels_per_ext_rel
+	  != s->reloc_count * address_size)
+	{
+	  _bfd_error_handler
+	    /* xgettext:c-format */
+	    (_("error: %pB: size of section %pA is not multiple of "
+	       "address size"), s->owner, s);
+	  bfd_set_error (bfd_error_bad_value);
+	  return false;
+	}
+      s->flags |= SEC_ELF_REVERSE_COPY;
+    }
+  return true;
+}
+
 /* Link an input file into the linker output file.  This function
    handles all the sections and relocations of the input file at once.
    This is so that we only have to read the local symbols once, and
@@ -11249,28 +11284,9 @@  elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 
 	  /* We need to reverse-copy input .ctors/.dtors sections if
 	     they are placed in .init_array/.finit_array for output.  */
-	  if (o->size > address_size
-	      && ((startswith (o->name, ".ctors")
-		   && strcmp (o->output_section->name,
-			      ".init_array") == 0)
-		  || (startswith (o->name, ".dtors")
-		      && strcmp (o->output_section->name,
-				 ".fini_array") == 0))
-	      && (o->name[6] == 0 || o->name[6] == '.'))
-	    {
-	      if (o->size * bed->s->int_rels_per_ext_rel
-		  != o->reloc_count * address_size)
-		{
-		  _bfd_error_handler
-		    /* xgettext:c-format */
-		    (_("error: %pB: size of section %pA is not "
-		       "multiple of address size"),
-		     input_bfd, o);
-		  bfd_set_error (bfd_error_bad_value);
-		  return false;
-		}
-	      o->flags |= SEC_ELF_REVERSE_COPY;
-	    }
+	  if (!_bfd_elf_process_reverse_copy (o, address_size,
+					      bed->s->int_rels_per_ext_rel))
+	    return false;
 
 	  action_discarded = -1;
 	  if (!elf_section_ignore_discarded_relocs (o))