Set SEC_ELF_REVERSE_COPY earlier
authorAlan Modra <amodra@gmail.com>
Wed, 12 Jan 2022 02:07:27 +0000 (12:37 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 12 Jan 2022 02:25:17 +0000 (12:55 +1030)
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.

bfd/elflink.c
ld/ldlang.c

index 059461b57257adc3aeada860633592b62796551b..f5e3fd53c5d3147920bf9bc19d718e5e6f92f319 100644 (file)
@@ -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;
index 9dbc8752f87df6d0dbb0faa38d1bf7568abe451d..0af6c60bce51033095dc0cf13380f0bea055ca0a 100644 (file)
@@ -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;