[binutils-gdb] Set SEC_ELF_REVERSE_COPY earlier

Alan Modra amodra@sourceware.org
Wed Jan 12 04:29:16 GMT 2022


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

commit b02db37812bef6e12772bfbddd004e50534eaed1
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Jan 12 12:37:27 2022 +1030

    Set SEC_ELF_REVERSE_COPY earlier
    
    For the sake of DT_RELR.
    
    bfd/
            * elflink.c (elf_link_input_bfd): Don't set SEC_ELF_REVERSE_COPY
            here.  Move sanity checks to reverse copying code.
    ld/
            * ldlang.c (lang_add_section): Set SEC_ELF_REVERSE_COPY for
            .ctors/.dtors in .init_array/.fini_array.

Diff:
---
 bfd/elflink.c | 42 ++++++++++++++++--------------------------
 ld/ldlang.c   | 10 ++++++++++
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 059461b5725..f5e3fd53c5d 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11247,31 +11247,6 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 	      && o->reloc_count > 0)
 	    return false;
 
-	  /* 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;
-	    }
-
 	  action_discarded = -1;
 	  if (!elf_section_ignore_discarded_relocs (o))
 	    action_discarded = (*bed->action_discarded) (o);
@@ -11756,9 +11731,24 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 
 		offset *= bfd_octets_per_byte (output_bfd, o);
 
-		if ((o->flags & SEC_ELF_REVERSE_COPY))
+		if ((o->flags & SEC_ELF_REVERSE_COPY)
+		    && o->size > address_size)
 		  {
 		    /* Reverse-copy input section to output.  */
+
+		    if (o->reloc_count != 0
+			&& (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;
+		      }
+
 		    do
 		      {
 			todo -= address_size;
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 9dbc8752f87..0af6c60bce5 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2701,6 +2701,16 @@ lang_add_section (lang_statement_list_type *ptr,
       output->block_value = 128;
     }
 
+  /* When a .ctors section is placed in .init_array it must be copied
+     in reverse order.  Similarly for .dtors.  Set that up.  */
+  if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
+      && ((startswith (section->name, ".ctors")
+	   && strcmp (output->bfd_section->name, ".init_array") == 0)
+	  || (startswith (section->name, ".dtors")
+	      && strcmp (output->bfd_section->name, ".fini_array") == 0))
+      && (section->name[6] == 0 || section->name[6] == '.'))
+    section->flags |= SEC_ELF_REVERSE_COPY;
+
   if (section->alignment_power > output->bfd_section->alignment_power)
     output->bfd_section->alignment_power = section->alignment_power;


More information about the Binutils-cvs mailing list