From: Alan Modra Date: Wed, 12 Jan 2022 02:07:27 +0000 (+1030) Subject: Set SEC_ELF_REVERSE_COPY earlier X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b02db37812bef6e12772bfbddd004e50534eaed1;p=binutils-gdb.git 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 --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;