From: Szabolcs Nagy Date: Mon, 3 Jun 2024 16:20:32 +0000 (+0100) Subject: aarch64: Fix DT_RELR support with discarded sections X-Git-Tag: binutils-2_43~506 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=961befd69308895bf1dc39737d1598246dc296a8;p=thirdparty%2Fbinutils-gdb.git aarch64: Fix DT_RELR support with discarded sections In case of discarded sections, via /DISCARD/ or .gnu.linkonce, relr relocation accounting was wrong. This broke building linux. The issue was that the *_relocate_section logic was copied to record_relr_non_got_relocs to find the relative relocs that can be packed, however *_relocate_section is not called on sections that are discarded, while record_relr_non_got_relocs is called for all input sections. The fix is to filter out the discarded sections with the same logic that is used to count non-GOT relocs in *_late_size_sections for local symbols earlier. Use the discarded_section helper in both cases to clarify the intent and handle all corner-cases consistently. GOT relocations are affected too if all sections are discarded that reference the GOT entry of a particular symbol, however this can cause unused GOT entries independently of DT_RELR, and the only difference with DT_RELR is that a relative reloc may be emitted instead of a R_AARCH64_NONE for the unused GOT entry which is acceptable. A proper fix would require redoing the GOT refcounting after we know the discarded sections, see bug 31850. --- diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 81f1a646125..2221de0a480 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -9327,6 +9327,8 @@ record_relr_non_got_relocs (bfd *input_bfd, struct bfd_link_info *info, return true; if (sec->alignment_power == 0) return true; + if (discarded_section (sec)) + return true; sreloc = elf_section_data (sec)->sreloc; if (sreloc == NULL) return true; @@ -9602,8 +9604,7 @@ elfNN_aarch64_late_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED, for (p = (struct elf_dyn_relocs *) (elf_section_data (s)->local_dynrel); p != NULL; p = p->next) { - if (!bfd_is_abs_section (p->sec) - && bfd_is_abs_section (p->sec->output_section)) + if (discarded_section (p->sec)) { /* Input section has been discarded, either because it is a copy of a linkonce section or due to